diff --git a/apps/www/next.config.ts b/apps/www/next.config.ts
index 4c4c433235..6c9430f735 100644
--- a/apps/www/next.config.ts
+++ b/apps/www/next.config.ts
@@ -74,6 +74,14 @@ const nextConfig = async (phase: string) => {
destination: '/:path*?locale=cn', // Rewrite it to the corresponding path without /cn
source: '/cn/:path*', // Match any path under /cn
},
+ {
+ destination: '/?locale=pt-br',
+ source: '/pt-br',
+ },
+ {
+ destination: '/:path*?locale=pt-br', // Rewrite it to the corresponding path without /pt-br
+ source: '/pt-br/:path*', // Match any path under /pt-br
+ },
];
},
diff --git a/apps/www/src/app/(app)/_components/announcement-button.tsx b/apps/www/src/app/(app)/_components/announcement-button.tsx
index 6c78a86e24..690f4a6011 100644
--- a/apps/www/src/app/(app)/_components/announcement-button.tsx
+++ b/apps/www/src/app/(app)/_components/announcement-button.tsx
@@ -13,6 +13,9 @@ const i18n = {
en: {
description: 'MCP, AI, Upload, and more',
},
+ 'pt-br': {
+ description: 'MCP, IA, Upload, e mais',
+ },
};
export function AnnouncementButton() {
diff --git a/apps/www/src/app/(app)/_components/potion-lazy-block.tsx b/apps/www/src/app/(app)/_components/potion-lazy-block.tsx
index 920498cb3a..b57cb5c780 100644
--- a/apps/www/src/app/(app)/_components/potion-lazy-block.tsx
+++ b/apps/www/src/app/(app)/_components/potion-lazy-block.tsx
@@ -24,6 +24,13 @@ const i18n = {
github: 'GitHub',
potionDescription: 'A Notion-like AI template.',
},
+ 'pt-br': {
+ buildYourRichTextEditor: 'Construa seu editor de texto',
+ description: 'Framework · Plugins · Componentes · Temas',
+ getStarted: 'Começar',
+ github: 'GitHub',
+ potionDescription: 'Um template de IA similar ao Notion.',
+ },
};
export function PotionLazyBlock() {
diff --git a/apps/www/src/app/(app)/docs/[[...slug]]/page.tsx b/apps/www/src/app/(app)/docs/[[...slug]]/page.tsx
index 63e03f9559..abcfb0d7d6 100644
--- a/apps/www/src/app/(app)/docs/[[...slug]]/page.tsx
+++ b/apps/www/src/app/(app)/docs/[[...slug]]/page.tsx
@@ -43,23 +43,23 @@ async function getDocFromParams({ params, searchParams }: DocPageProps) {
let slug = slugParam?.join('/') || '';
- // For Chinese docs, look for .cn.mdx files
- if (locale === 'cn') {
- // First try to find the Chinese version with .cn.mdx
- const cnDoc = allDocs.find(
+ // For non-default locales (e.g. cn, pt-br), look for .locale.mdx files
+ if (locale) {
+ // First try to find the localized version with .locale.mdx
+ const localizedDoc = allDocs.find(
(doc) =>
- doc.slugAsParams === `docs/${slug || 'index'}.cn` &&
- doc._raw.sourceFileName?.endsWith('.cn.mdx')
+ doc.slugAsParams === `docs/${slug || 'index'}.${locale}` &&
+ doc._raw.sourceFileName?.endsWith(`.${locale}.mdx`)
);
- if (cnDoc) {
+ if (localizedDoc) {
const path = slugParam?.join('/') || '';
- cnDoc.slug = `/docs${path ? `/${path}` : ''}?locale=cn`;
- return cnDoc;
+ localizedDoc.slug = `/docs${path ? `/${path}` : ''}?locale=${locale}`;
+ return localizedDoc;
}
}
- // Default behavior for non-Chinese or fallback
+ // Default behavior for non-localized or fallback
slug = `docs${slug ? `/${slug}` : ''}`;
const doc = allDocs.find((doc) => doc.slugAsParams === slug);
@@ -70,9 +70,9 @@ async function getDocFromParams({ params, searchParams }: DocPageProps) {
const path = slugParam?.join('/') || '';
doc.slug = `/docs${path ? `/${path}` : ''}`;
- // Only add locale param for Chinese
- if (locale === 'cn') {
- doc.slug += '?locale=cn';
+ // Only add locale param if present
+ if (locale) {
+ doc.slug += `?locale=${locale}`;
}
return doc;
diff --git a/apps/www/src/app/(app)/editors/editor-description.tsx b/apps/www/src/app/(app)/editors/editor-description.tsx
index 5fb98e6ad0..b95f502fdd 100644
--- a/apps/www/src/app/(app)/editors/editor-description.tsx
+++ b/apps/www/src/app/(app)/editors/editor-description.tsx
@@ -19,6 +19,11 @@ const i18n = {
description: 'Beautifully designed. Copy and paste into your apps.',
title: 'Building Editors for the Web',
},
+ 'pt-br': {
+ browseEditors: 'Navegar por Editores',
+ description: 'Desenhado elegantemente. Copie e cole em suas aplicações.',
+ title: 'Construindo Editores para a Web',
+ },
};
export function EditorDescription() {
diff --git a/apps/www/src/app/(app)/page.tsx b/apps/www/src/app/(app)/page.tsx
index f9dd0c64d6..3cfe251213 100644
--- a/apps/www/src/app/(app)/page.tsx
+++ b/apps/www/src/app/(app)/page.tsx
@@ -34,6 +34,13 @@ const i18n = {
github: 'GitHub',
potionDescription: 'A Notion-like AI template.',
},
+ 'pt-br': {
+ buildYourRichTextEditor: 'Construa seu editor de texto',
+ description: 'Framework · Plugins · Componentes · Temas',
+ getStarted: 'Começar',
+ github: 'GitHub',
+ potionDescription: 'Um template de IA similar ao Notion.',
+ },
};
const title = 'Build your rich-text editor';
diff --git a/apps/www/src/components/languages-dropdown-menu.tsx b/apps/www/src/components/languages-dropdown-menu.tsx
index 4a733334c4..9bd9ccdef0 100644
--- a/apps/www/src/components/languages-dropdown-menu.tsx
+++ b/apps/www/src/components/languages-dropdown-menu.tsx
@@ -16,23 +16,26 @@ export function LanguagesDropdownMenu() {
const handleClick = (locale?: string) => {
const url = new URL(window.location.href);
+ const supportedLocales = ['cn', 'pt-br'];
- if (locale) {
- if (pathname?.includes(locale)) {
- return;
- }
+ if (!pathname) return;
+
+ const segments = pathname.split('/').filter((p) => !!p);
+ const currentLocale = supportedLocales.includes(segments[0])
+ ? segments[0]
+ : undefined;
+
+ // If the target locale is the same as the current, do nothing
+ if (locale === currentLocale) return;
+
+ // Remove the current locale from the segments if it exists
+ const newSegments = currentLocale ? segments.slice(1) : segments;
- url.pathname = `/${locale}${pathname}`;
+ if (locale) {
+ url.pathname = `/${locale}/${newSegments.join('/')}`;
url.searchParams.set('locale', locale);
} else {
- if (!pathname?.includes('cn')) return;
- if (pathname) {
- const segments = pathname.split('/').filter((p) => !!p);
- const newSegments = segments.filter((segment) => segment !== 'cn');
- url.pathname =
- newSegments.length > 0 ? `/${newSegments.join('/')}` : '/';
- }
-
+ url.pathname = `/${newSegments.join('/')}`;
url.searchParams.delete('locale');
}
@@ -66,6 +69,16 @@ export function LanguagesDropdownMenu() {
中文
+
+
+
);
diff --git a/apps/www/src/components/main-nav.tsx b/apps/www/src/components/main-nav.tsx
index 353df915d2..3091f66d73 100644
--- a/apps/www/src/components/main-nav.tsx
+++ b/apps/www/src/components/main-nav.tsx
@@ -27,6 +27,12 @@ const i18n = {
editors: 'Editors',
templates: 'Templates',
},
+ 'pt-br': {
+ components: 'Componentes',
+ docs: 'Documentação',
+ editors: 'Editores',
+ templates: 'Templates',
+ },
};
export function MainNav({
diff --git a/apps/www/src/components/open-in-plus.tsx b/apps/www/src/components/open-in-plus.tsx
index 8b6ac58b1f..126fb47ea9 100644
--- a/apps/www/src/components/open-in-plus.tsx
+++ b/apps/www/src/components/open-in-plus.tsx
@@ -17,6 +17,12 @@ const i18n = {
getAccess: 'Get all-access',
productionReady: 'Production-ready AI template and reusable components.',
},
+ 'pt-br': {
+ buildYourEditor: 'Construa seu editor',
+ getAccess: 'Obtenha acesso completo',
+ productionReady:
+ 'Template de IA pronto para produção e componentes reutilizáveis.',
+ },
};
export function OpenInPlus({ className }: { className?: string }) {
diff --git a/apps/www/src/components/playground-preview.tsx b/apps/www/src/components/playground-preview.tsx
index 8a8f0625db..2c0bab55f2 100644
--- a/apps/www/src/components/playground-preview.tsx
+++ b/apps/www/src/components/playground-preview.tsx
@@ -25,6 +25,9 @@ const i18n = {
en: {
description: 'An AI editor',
},
+ 'pt-br': {
+ description: 'Um editor de IA',
+ },
};
// TODO: sync
diff --git a/apps/www/src/hooks/useLocale.ts b/apps/www/src/hooks/useLocale.ts
index 8de81716d1..94eb42afdf 100644
--- a/apps/www/src/hooks/useLocale.ts
+++ b/apps/www/src/hooks/useLocale.ts
@@ -8,4 +8,6 @@ export const useLocale = () => {
};
export const getLocalizedPath = (locale: string, href: string) =>
- locale === 'cn' ? `/cn${href}?locale=cn` : href;
+ locale === 'cn' || locale === 'pt-br'
+ ? `/${locale}${href}?locale=${locale}`
+ : href;
diff --git a/apps/www/src/i18n/getI18nValues.ts b/apps/www/src/i18n/getI18nValues.ts
index 710d66a9ac..609c79f06d 100644
--- a/apps/www/src/i18n/getI18nValues.ts
+++ b/apps/www/src/i18n/getI18nValues.ts
@@ -1,3 +1,4 @@
+// #region en
import { aiValue as aiValueEn } from '@/registry/examples/values/ai-value';
import { alignValue as alignValueEn } from '@/registry/examples/values/align-value';
import { autoformatValue as autoformatValueEn } from '@/registry/examples/values/autoformat-value';
@@ -6,6 +7,46 @@ import { basicMarksValue as basicMarksValueEn } from '@/registry/examples/values
import { basicNodesValue as basicNodesValueEn } from '@/registry/examples/values/basic-nodes-value';
import { blockMenuValue as blockMenuValueEn } from '@/registry/examples/values/block-menu-value';
import { blockSelectionValue as blockSelectionValueEn } from '@/registry/examples/values/block-selection-value';
+import { columnValue as columnValueEn } from '@/registry/examples/values/column-value';
+import { copilotValue as copilotValueEn } from '@/registry/examples/values/copilot-value';
+import { cursorOverlayValue as cursorOverlayValueEn } from '@/registry/examples/values/cursor-overlay-value';
+import { dateValue as dateValueEn } from '@/registry/examples/values/date-value';
+import { deserializeCsvValue as deserializeCsvValueEn } from '@/registry/examples/values/deserialize-csv-value';
+import { deserializeDocxValue as deserializeDocxValueEn } from '@/registry/examples/values/deserialize-docx-value';
+import { deserializeHtmlValue as deserializeHtmlValueEn } from '@/registry/examples/values/deserialize-html-value';
+import { deserializeMdValue as deserializeMdValueEn } from '@/registry/examples/values/deserialize-md-value';
+import { discussionValue as commentValueEn } from '@/registry/examples/values/discussion-value';
+import { dndValue as dndValueEn } from '@/registry/examples/values/dnd-value';
+import { editableVoidsValue as editableVoidsValueEn } from '@/registry/examples/values/editable-voids-value';
+import { emojiValue as emojiValueEn } from '@/registry/examples/values/emoji-value';
+import { equationValue as equationValueEn } from '@/registry/examples/values/equation-value';
+import { excalidrawValue as excalidrawValueEn } from '@/registry/examples/values/excalidraw-value';
+import {
+ exitBreakValue as exitBreakValueEn,
+ trailingBlockValue as trailingBlockValueEn,
+} from '@/registry/examples/values/exit-break-value';
+import { findReplaceValue as findReplaceValueEn } from '@/registry/examples/values/find-replace-value';
+import { floatingToolbarValue as floatingToolbarValueEn } from '@/registry/examples/values/floating-toolbar-value';
+import { fontValue as fontValueEn } from '@/registry/examples/values/font-value';
+import { iframeValue as iframeValueEn } from '@/registry/examples/values/iframe-value';
+import { indentValue as indentValueEn } from '@/registry/examples/values/indent-value';
+import { lineHeightValue as lineHeightValueEn } from '@/registry/examples/values/line-height-value';
+import { linkValue as linkValueEn } from '@/registry/examples/values/link-value';
+import { listValue as listValueEn } from '@/registry/examples/values/list-value';
+import { mediaValue as mediaValueEn } from '@/registry/examples/values/media-value';
+import { mentionValue as mentionValueEn } from '@/registry/examples/values/mention-value';
+import { blockPlaceholderValue as placeholderValueEn } from '@/registry/examples/values/placeholder-value';
+import { playgroundValue as playgroundValueEn } from '@/registry/examples/values/playground-value';
+import { pluginRulesValue as pluginRulesValueEn } from '@/registry/examples/values/plugin-rules-value';
+import { previewMdValue as previewMdValueEn } from '@/registry/examples/values/preview-md-value';
+import { slashCommandValue as slashCommandValueEn } from '@/registry/examples/values/slash-command-value';
+import { tabbableValue as tabbableValueEn } from '@/registry/examples/values/tabbable-value';
+import { tableValue as tableValueEn } from '@/registry/examples/values/table-value';
+import { tocValue as tocValueEn } from '@/registry/examples/values/toc-value';
+import { toggleValue as toggleValueEn } from '@/registry/examples/values/toggle-value';
+// #endregion
+
+// #region cn
import { aiValue as aiValueCn } from '@/registry/examples/values/cn/ai-value';
import { alignValue as alignValueCn } from '@/registry/examples/values/cn/align-value';
import { autoformatValue as autoformatValueCn } from '@/registry/examples/values/cn/autoformat-value';
@@ -51,43 +92,54 @@ import { tabbableValue as tabbableValueCn } from '@/registry/examples/values/cn/
import { tableValue as tableValueCn } from '@/registry/examples/values/cn/table-value';
import { tocValue as tocValueCn } from '@/registry/examples/values/cn/toc-value';
import { toggleValue as toggleValueCn } from '@/registry/examples/values/cn/toggle-value';
-import { columnValue as columnValueEn } from '@/registry/examples/values/column-value';
-import { copilotValue as copilotValueEn } from '@/registry/examples/values/copilot-value';
-import { cursorOverlayValue as cursorOverlayValueEn } from '@/registry/examples/values/cursor-overlay-value';
-import { dateValue as dateValueEn } from '@/registry/examples/values/date-value';
-import { deserializeCsvValue as deserializeCsvValueEn } from '@/registry/examples/values/deserialize-csv-value';
-import { deserializeDocxValue as deserializeDocxValueEn } from '@/registry/examples/values/deserialize-docx-value';
-import { deserializeHtmlValue as deserializeHtmlValueEn } from '@/registry/examples/values/deserialize-html-value';
-import { deserializeMdValue as deserializeMdValueEn } from '@/registry/examples/values/deserialize-md-value';
-import { discussionValue as commentValueEn } from '@/registry/examples/values/discussion-value';
-import { dndValue as dndValueEn } from '@/registry/examples/values/dnd-value';
-import { editableVoidsValue as editableVoidsValueEn } from '@/registry/examples/values/editable-voids-value';
-import { emojiValue as emojiValueEn } from '@/registry/examples/values/emoji-value';
-import { equationValue as equationValueEn } from '@/registry/examples/values/equation-value';
-import { excalidrawValue as excalidrawValueEn } from '@/registry/examples/values/excalidraw-value';
+// #endregion
+
+// #region pt-br
+import { aiValue as aiValuePt } from '@/registry/examples/values/pt-br/ai-value';
+import { alignValue as alignValuePt } from '@/registry/examples/values/pt-br/align-value';
+import { autoformatValue as autoformatValuePt } from '@/registry/examples/values/pt-br/autoformat-value';
+import { basicBlocksValue as basicBlocksValuePt } from '@/registry/examples/values/pt-br/basic-blocks-value';
+import { basicMarksValue as basicMarksValuePt } from '@/registry/examples/values/pt-br/basic-marks-value';
+import { basicNodesValue as basicNodesValuePt } from '@/registry/examples/values/pt-br/basic-nodes-value';
+import { blockMenuValue as blockMenuValuePt } from '@/registry/examples/values/pt-br/block-menu-value';
+import { blockSelectionValue as blockSelectionValuePt } from '@/registry/examples/values/pt-br/block-selection-value';
+import { columnValue as columnValuePt } from '@/registry/examples/values/pt-br/column-value';
+import { copilotValue as copilotValuePt } from '@/registry/examples/values/pt-br/copilot-value';
+import { cursorOverlayValue as cursorOverlayValuePt } from '@/registry/examples/values/pt-br/cursor-overlay-value';
+import { dateValue as dateValuePt } from '@/registry/examples/values/pt-br/date-value';
+import { deserializeCsvValue as deserializeCsvValuePt } from '@/registry/examples/values/pt-br/deserialize-csv-value';
+import { deserializeDocxValue as deserializeDocxValuePt } from '@/registry/examples/values/pt-br/deserialize-docx-value';
+import { deserializeHtmlValue as deserializeHtmlValuePt } from '@/registry/examples/values/pt-br/deserialize-html-value';
+import { deserializeMdValue as deserializeMdValuePt } from '@/registry/examples/values/pt-br/deserialize-md-value';
+import { discussionValue as discussionValuePt } from '@/registry/examples/values/pt-br/discussion-value';
+import { dndValue as dndValuePt } from '@/registry/examples/values/pt-br/dnd-value';
+import { editableVoidsValue as editableVoidsValuePt } from '@/registry/examples/values/pt-br/editable-voids-value';
+import { emojiValue as emojiValuePt } from '@/registry/examples/values/pt-br/emoji-value';
+import { equationValue as equationValuePt } from '@/registry/examples/values/pt-br/equation-value';
+import { excalidrawValue as excalidrawValuePt } from '@/registry/examples/values/pt-br/excalidraw-value';
import {
- exitBreakValue as exitBreakValueEn,
- trailingBlockValue as trailingBlockValueEn,
-} from '@/registry/examples/values/exit-break-value';
-import { findReplaceValue as findReplaceValueEn } from '@/registry/examples/values/find-replace-value';
-import { floatingToolbarValue as floatingToolbarValueEn } from '@/registry/examples/values/floating-toolbar-value';
-import { fontValue as fontValueEn } from '@/registry/examples/values/font-value';
-import { iframeValue as iframeValueEn } from '@/registry/examples/values/iframe-value';
-import { indentValue as indentValueEn } from '@/registry/examples/values/indent-value';
-import { lineHeightValue as lineHeightValueEn } from '@/registry/examples/values/line-height-value';
-import { linkValue as linkValueEn } from '@/registry/examples/values/link-value';
-import { listValue as listValueEn } from '@/registry/examples/values/list-value';
-import { mediaValue as mediaValueEn } from '@/registry/examples/values/media-value';
-import { mentionValue as mentionValueEn } from '@/registry/examples/values/mention-value';
-import { blockPlaceholderValue as placeholderValueEn } from '@/registry/examples/values/placeholder-value';
-import { playgroundValue as playgroundValueEn } from '@/registry/examples/values/playground-value';
-import { pluginRulesValue as pluginRulesValueEn } from '@/registry/examples/values/plugin-rules-value';
-import { previewMdValue as previewMdValueEn } from '@/registry/examples/values/preview-md-value';
-import { slashCommandValue as slashCommandValueEn } from '@/registry/examples/values/slash-command-value';
-import { tabbableValue as tabbableValueEn } from '@/registry/examples/values/tabbable-value';
-import { tableValue as tableValueEn } from '@/registry/examples/values/table-value';
-import { tocValue as tocValueEn } from '@/registry/examples/values/toc-value';
-import { toggleValue as toggleValueEn } from '@/registry/examples/values/toggle-value';
+ exitBreakValue as exitBreakValuePt,
+ trailingBlockValue as trailingBlockValuePt,
+} from '@/registry/examples/values/pt-br/exit-break-value';
+import { findReplaceValue as findReplaceValuePt } from '@/registry/examples/values/pt-br/find-replace-value';
+import { floatingToolbarValue as floatingToolbarValuePt } from '@/registry/examples/values/pt-br/floating-toolbar-value';
+import { fontValue as fontValuePt } from '@/registry/examples/values/pt-br/font-value';
+import { iframeValue as iframeValuePt } from '@/registry/examples/values/pt-br/iframe-value';
+import { indentValue as indentValuePt } from '@/registry/examples/values/pt-br/indent-value';
+import { lineHeightValue as lineHeightValuePt } from '@/registry/examples/values/pt-br/line-height-value';
+import { linkValue as linkValuePt } from '@/registry/examples/values/pt-br/link-value';
+import { listValue as listValuePt } from '@/registry/examples/values/pt-br/list-value';
+import { mediaValue as mediaValuePt } from '@/registry/examples/values/pt-br/media-value';
+import { mentionValue as mentionValuePt } from '@/registry/examples/values/pt-br/mention-value';
+import { blockPlaceholderValue as placeholderValuePt } from '@/registry/examples/values/pt-br/placeholder-value';
+import { playgroundValue as playgroundValuePt } from '@/registry/examples/values/pt-br/playground-value';
+import { previewMdValue as previewMdValuePt } from '@/registry/examples/values/pt-br/preview-md-value';
+import { slashCommandValue as slashCommandValuePt } from '@/registry/examples/values/pt-br/slash-command-value';
+import { tabbableValue as tabbableValuePt } from '@/registry/examples/values/pt-br/tabbable-value';
+import { tableValue as tableValuePt } from '@/registry/examples/values/pt-br/table-value';
+import { tocValue as tocValuePt } from '@/registry/examples/values/pt-br/toc-value';
+import { toggleValue as toggleValuePt } from '@/registry/examples/values/pt-br/toggle-value';
+// #endregion
const i18n = {
cn: {
@@ -180,6 +232,50 @@ const i18n = {
toggle: toggleValueEn,
trailingBlock: trailingBlockValueEn,
},
+ 'pt-br': {
+ ai: aiValuePt,
+ autoformat: autoformatValuePt,
+ basicBlocks: basicBlocksValuePt,
+ basicMarks: basicMarksValuePt,
+ basicNodes: basicNodesValuePt,
+ blockMenu: blockMenuValuePt,
+ blockSelection: blockSelectionValuePt,
+ column: columnValuePt,
+ copilot: copilotValuePt,
+ cursorOverlay: cursorOverlayValuePt,
+ date: dateValuePt,
+ deserializeCsv: deserializeCsvValuePt,
+ deserializeDocx: deserializeDocxValuePt,
+ deserializeHtml: deserializeHtmlValuePt,
+ deserializeMd: deserializeMdValuePt,
+ discussion: discussionValuePt,
+ dnd: dndValuePt,
+ editableVoids: editableVoidsValuePt,
+ emoji: emojiValuePt,
+ equation: equationValuePt,
+ excalidraw: excalidrawValuePt,
+ exitBreak: exitBreakValuePt,
+ findReplace: findReplaceValuePt,
+ floatingToolbar: floatingToolbarValuePt,
+ font: fontValuePt,
+ iframe: iframeValuePt,
+ indent: indentValuePt,
+ lineHeight: lineHeightValuePt,
+ link: linkValuePt,
+ list: listValuePt,
+ media: mediaValuePt,
+ mention: mentionValuePt,
+ placeholder: placeholderValuePt,
+ playground: playgroundValuePt,
+ previewMd: previewMdValuePt,
+ slashCommand: slashCommandValuePt,
+ tabbable: tabbableValuePt,
+ table: tableValuePt,
+ 'text-align': alignValuePt,
+ toc: tocValuePt,
+ toggle: toggleValuePt,
+ trailingBlock: trailingBlockValuePt,
+ },
};
export const getI18nValues = (locale: string) =>
diff --git a/apps/www/src/lib/withLocale.ts b/apps/www/src/lib/withLocale.ts
index 39a71b1536..082d1a1b4d 100644
--- a/apps/www/src/lib/withLocale.ts
+++ b/apps/www/src/lib/withLocale.ts
@@ -1,6 +1,6 @@
export const hrefWithLocale = (href: string, locale: string) => {
- if (locale === 'cn') {
- return `/cn${href}?locale=${locale}`;
+ if (locale === 'cn' || locale === 'pt-br') {
+ return `/${locale}${href}?locale=${locale}`;
}
return href;
diff --git a/apps/www/src/registry/examples/values/pt-br/ai-value.tsx b/apps/www/src/registry/examples/values/pt-br/ai-value.tsx
new file mode 100644
index 0000000000..7b342e319d
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/ai-value.tsx
@@ -0,0 +1,100 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const aiValue: any = (
+
+ Menu de IA
+ Gere e refine conteúdo com IA.
+ Acesse o menu de IA de várias maneiras:
+
+ Pressione "⌘ + J".
+
+
+
+ Selecione o texto e clique em "Perguntar à IA" na barra de ferramentas
+ flutuante
+
+
+
+
+ Clique com o botão direito em um bloco e selecione "Perguntar à IA"
+
+
+
+ Pressione espaço em um bloco vazio. Experimente:
+
+
+
+
+ Uma vez aberto, você pode:
+
+ Pesquisar comandos no campo de entrada:
+
+
+ Use as setas para navegar, Enter para selecionar
+
+
+ Comandos de geração:
+
+
+ Continuar escrevendo
+
+
+ Adicionar um resumo
+
+
+ Explicar
+
+
+ Sugestões de geração:
+
+
+ Aceitar
+
+
+ Descartar
+
+
+ Tentar novamente
+
+
+ Comandos de edição:
+
+
+ Melhorar a escrita
+
+
+ Adicionar emojis
+
+
+ Tornar mais longo ou mais curto
+
+
+ Corrigir ortografia e gramática
+
+
+ Simplificar a linguagem
+
+ Sugestões de edição:
+
+ Substituir a seleção
+
+
+ Inserir abaixo
+
+
+ Descartar
+
+
+ Tentar novamente
+
+
+
+ Nota: o histórico do chat é preservado até que o menu seja fechado.
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/align-value.tsx b/apps/www/src/registry/examples/values/pt-br/align-value.tsx
new file mode 100644
index 0000000000..a15a87efbd
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/align-value.tsx
@@ -0,0 +1,20 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const alignValue: any = (
+
+ Alinhamento
+
+ Alinhe o texto dentro dos blocos para criar layouts visualmente atraentes
+ e equilibrados.
+
+ Centralizado
+
+ Crie layouts limpos e equilibrados justificando o texto do bloco,
+ proporcionando uma aparência profissional e polida.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/autoformat-value.tsx b/apps/www/src/registry/examples/values/pt-br/autoformat-value.tsx
new file mode 100644
index 0000000000..1859d84e18
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/autoformat-value.tsx
@@ -0,0 +1,93 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const autoformatValue: any = (
+
+ Formatação Automática
+
+ Potencialize sua experiência de escrita habilitando recursos de formatação
+ automática. Adicione atalhos estilo Markdown que aplicam formatação
+ automaticamente enquanto você digita.
+
+ Enquanto digita, experimente estas regras de marcação:
+
+ Digite ** ou __ em ambos os lados
+ do seu texto para adicionar **negrito*.
+
+
+ Digite * ou _ em ambos os lados do
+ seu texto para adicionar *itálico.
+
+
+
+ Digite ` em ambos os lados do seu texto para adicionar
+ `código inline.
+
+
+
+ Digite ~~ em ambos os lados do seu texto para
+ adicionar ~~tachado~.
+
+
+ Note que nada acontece quando há um caractere antes, tente em:*negrito
+
+
+ Nós até suportamos aspas inteligentes, tente digitar{' '}
+ "olá" 'mundo'.
+
+
+
+ No início de qualquer novo bloco ou bloco existente, tente estes (regras
+ de bloco):
+
+
+
+ Digite *, - ou{' '}
+ +
+ seguido de espaço para criar uma lista com marcadores.
+
+
+ Digite 1. ou 1) seguido de{' '}
+ espaço
+ para criar uma lista numerada.
+
+
+ Digite [] ou [x]
+ seguido de espaço para criar uma lista de tarefas.
+
+
+ Digite > seguido de espaço para
+ criar uma citação em bloco.
+
+
+ Digite ``` para criar um bloco de código.
+
+
+ Digite --- para criar uma linha horizontal.
+
+
+
+ Digite # seguido de espaço para
+ criar um título H1.
+
+
+ Digite ### seguido de espaço para
+ criar um subtítulo H3.
+
+
+ Digite #### seguido de espaço para
+ criar um subtítulo H4.
+
+
+ Digite ##### seguido de espaço{' '}
+ para criar um subtítulo H5.
+
+
+ Digite ###### seguido de espaço{' '}
+ para criar um subtítulo H6.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/basic-blocks-value.tsx b/apps/www/src/registry/examples/values/pt-br/basic-blocks-value.tsx
new file mode 100644
index 0000000000..d9c013b658
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/basic-blocks-value.tsx
@@ -0,0 +1,42 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+import { KEYS } from 'platejs';
+
+jsx;
+
+export const basicBlocksValue: any = (
+
+ Título 1
+
+ Este é um título de nível superior, geralmente usado para títulos
+ principais e cabeçalhos de seções maiores.
+
+ Título 2
+
+ Títulos secundários ajudam a organizar o conteúdo em seções e subseções
+ claras.
+
+ Título 3
+
+ Títulos de terceiro nível fornecem mais estrutura e hierarquia ao
+ conteúdo.
+
+
+ "Citações em bloco são perfeitas para destacar informações importantes,
+ citações de fontes externas ou enfatizar pontos-chave no seu conteúdo."
+
+
+ Use títulos para criar uma estrutura de documento clara que ajude os
+ leitores a navegar pelo seu conteúdo de forma eficaz. Combine-os com
+ citações em bloco para enfatizar informações importantes.
+
+
+
+
+
+ Linhas horizontais ajudam a separar visualmente diferentes seções do seu
+ conteúdo, criando pausas claras entre tópicos ou ideias.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/basic-marks-value.tsx b/apps/www/src/registry/examples/values/pt-br/basic-marks-value.tsx
new file mode 100644
index 0000000000..c94676b865
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/basic-marks-value.tsx
@@ -0,0 +1,36 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const basicMarksValue: any = (
+
+ Formatação de Texto
+
+ Adicione estilo e ênfase ao seu texto usando várias opções de formatação.
+
+
+ Faça o texto negrito, itálico,{' '}
+ sublinhado, ou aplique uma{' '}
+
+ combinação
+ {' '}
+ desses estilos para ênfase.
+
+
+ Adicione tachado para indicar conteúdo
+ excluído, use código inline para termos técnicos, ou{' '}
+ destaque informações importantes.
+
+
+ Formate expressões matemáticas com texto{' '}
+ subscrito e{' '}
+ sobrescrito.
+
+
+ Mostre atalhos de teclado como ⌘ + B para negrito ou{' '}
+ ⌘ + I para formatação em itálico.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/basic-nodes-value.tsx b/apps/www/src/registry/examples/values/pt-br/basic-nodes-value.tsx
new file mode 100644
index 0000000000..3463996c2e
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/basic-nodes-value.tsx
@@ -0,0 +1,4 @@
+import { basicBlocksValue } from '@/registry/examples/values/pt-br/basic-blocks-value';
+import { basicMarksValue } from '@/registry/examples/values/pt-br/basic-marks-value';
+
+export const basicNodesValue = [...basicBlocksValue, ...basicMarksValue];
diff --git a/apps/www/src/registry/examples/values/pt-br/block-menu-value.tsx b/apps/www/src/registry/examples/values/pt-br/block-menu-value.tsx
new file mode 100644
index 0000000000..ca4a01fb40
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/block-menu-value.tsx
@@ -0,0 +1,33 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const blockMenuValue: any = (
+
+ Menu de Bloco
+
+ Abrir o menu de bloco:
+
+
+ Clique com o botão direito em qualquer bloco não selecionado para abrir
+ o menu de contexto. Se você clicar com o botão direito dentro de um
+ bloco selecionado, verá o menu de contexto nativo do navegador.
+
+
+ Opções disponíveis no menu de bloco:
+
+ Pedir à IA para editar o bloco.
+
+
+ Excluir o bloco.
+
+
+ Duplicar o bloco.
+
+
+ Transformar o tipo de bloco em outro tipo de bloco.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/block-selection-value.tsx b/apps/www/src/registry/examples/values/pt-br/block-selection-value.tsx
new file mode 100644
index 0000000000..cf3e124853
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/block-selection-value.tsx
@@ -0,0 +1,29 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const blockSelectionValue: any = (
+
+ Seleção de Bloco
+
+
+ A seleção de bloco permite selecionar vários blocos de uma vez. Você
+ pode iniciar uma seleção clicando e arrastando a partir do preenchimento
+ do editor.
+
+
+ Principais recursos da seleção de bloco:
+
+ Selecionar múltiplos blocos.
+
+
+ Mantenha Shift pressionado para manter a seleção anterior. Dessa forma,
+ você pode selecionar blocos não contíguos.
+
+
+ Executar ações em massa nos blocos selecionados
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/callout-value.tsx b/apps/www/src/registry/examples/values/pt-br/callout-value.tsx
new file mode 100644
index 0000000000..ee8eb8c830
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/callout-value.tsx
@@ -0,0 +1,32 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const calloutValue: any = (
+
+ Destaques (Callouts)
+
+ Use destaques para chamar a atenção para informações importantes e
+ organizar o conteúdo com ênfase visual.
+
+
+ Dica: Destaques ajudam a chamar a atenção para
+ informações chave sem interromper o fluxo do conteúdo.
+
+
+ Aviso: Considerações importantes ou problemas
+ potenciais dos quais os usuários devem estar cientes.
+
+
+ Sucesso: Celebre conquistas ou destaque resultados
+ positivos.
+
+
+ Clique em qualquer ícone de destaque para personalizá-lo com o seletor de
+ emojis. Destaques suportam formatação rica e podem conter qualquer
+ conteúdo.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/code-block-value.tsx b/apps/www/src/registry/examples/values/pt-br/code-block-value.tsx
new file mode 100644
index 0000000000..0797aed5b8
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/code-block-value.tsx
@@ -0,0 +1,78 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const codeBlockValue: any = (
+
+ Blocos de Código
+
+ Exiba seu código com destaque de sintaxe. Suporta múltiplas linguagens de
+ programação com formatação e indentação adequadas.
+
+
+ // Exemplo JavaScript com async/await
+ {'async function fetchUserData(userId) {'}
+ {' try {'}
+
+ {' const response = await fetch(`/api/users/${userId}`);'}
+
+ {' const userData = await response.json();'}
+ {' return userData;'}
+ {' } catch (error) {'}
+ {` console.error('Falha ao buscar dados do usuário:', error);`}
+ {' throw error;'}
+ {' }'}
+ {'}'}
+
+ Exemplo Python com definição de classe:
+
+ # Classe Python com dicas de tipo
+ from typing import List, Optional
+
+ class GerenciadorTarefas:
+ {' def __init__(self) -> None:'}
+ {' self.tasks: List[str] = []'}
+
+
+ {' def adicionar_tarefa(self, task: str) -> None:'}
+
+ {` """Adicionar uma nova tarefa à lista."""`}
+ {' self.tasks.append(task)'}
+
+
+ {' def obter_tarefa(self, index: int) -> Optional[str]:'}
+
+ {` """Obter uma tarefa pelo índice, retornar None se não encontrada."""`}
+
+ {
+ ' return self.tasks[index] if 0 <= index < len(self.tasks) else None'
+ }
+
+
+ Exemplo de estilo CSS:
+
+ /* CSS Moderno com propriedades personalizadas */
+ {':root {'}
+ {' --primary-color: #3b82f6;'}
+ {' --secondary-color: #64748b;'}
+ {' --border-radius: 0.5rem;'}
+ {'}'}
+
+ {'.card {'}
+ {' background: white;'}
+ {' border-radius: var(--border-radius);'}
+
+ {' box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);'}
+
+ {' padding: 1.5rem;'}
+ {' transition: transform 0.2s ease-in-out;'}
+ {'}'}
+
+ {'.card:hover {'}
+ {' transform: translateY(-2px);'}
+ {'}'}
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/column-value.tsx b/apps/www/src/registry/examples/values/pt-br/column-value.tsx
new file mode 100644
index 0000000000..6df3451ba4
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/column-value.tsx
@@ -0,0 +1,22 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const columnValue: any = (
+
+ Coluna
+ Crie colunas e a borda ficará oculta durante a visualização
+
+
+ esquerda 1
+ esquerda 2
+
+
+ direita 1
+ direita 2
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/copilot-value.tsx b/apps/www/src/registry/examples/values/pt-br/copilot-value.tsx
new file mode 100644
index 0000000000..5e6ce0d14a
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/copilot-value.tsx
@@ -0,0 +1,38 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const copilotValue: any = (
+
+ Copilot
+
+ Posicione seu cursor no
+ final de um parágrafo
+ onde você deseja adicionar ou modificar texto.
+
+
+ Pressione Control + Espaço para acionar o Copilot
+
+
+ O Copilot irá
+ automaticamente
+ sugerir conclusões enquanto você digita.
+
+
+ Escolha entre as conclusões sugeridas:
+
+
+ Tab:Aceita toda a conclusão sugerida
+
+
+ Command + Seta Direita
+ : Completa um caractere de cada vez
+
+
+ Esc
+ : Cancela o Copilot
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/cursor-overlay-value.tsx b/apps/www/src/registry/examples/values/pt-br/cursor-overlay-value.tsx
new file mode 100644
index 0000000000..75c20f6eef
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/cursor-overlay-value.tsx
@@ -0,0 +1,20 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const cursorOverlayValue: any = (
+
+ Sobreposição de Cursor
+
+ Tente arrastar sobre o texto: você verá um cursor colorido no alvo de
+ soltura: a cor e outros estilos são personalizáveis!
+
+
+ Você também pode tentar clicar no botão "Perguntar à IA" - a seleção
+ permanecerá visível enquanto foca em outra entrada, e será atualizada
+ durante o streaming.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/date-value.tsx b/apps/www/src/registry/examples/values/pt-br/date-value.tsx
new file mode 100644
index 0000000000..142aea66aa
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/date-value.tsx
@@ -0,0 +1,29 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+const today = new Date().toISOString().split('T')[0];
+
+export const dateValue: any = (
+
+ Data
+
+ Insira e exiba datas em seu texto usando elementos de data inline. Essas
+ datas podem ser facilmente selecionadas e modificadas usando uma interface
+ de calendário.
+
+
+ Tente selecionar{' '}
+
+
+ {' '}
+ ou{' '}
+
+
+
+ .
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/demo-values.tsx b/apps/www/src/registry/examples/values/pt-br/demo-values.tsx
new file mode 100644
index 0000000000..fd7cf03016
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/demo-values.tsx
@@ -0,0 +1,109 @@
+import { calloutValue } from '@/registry/examples/values/pt-br/callout-value';
+import { playgroundValue } from '@/registry/examples/values/playground-value';
+
+import { aiValue } from './ai-value';
+import { alignValue } from './align-value';
+import { autoformatValue } from './autoformat-value';
+import { basicBlocksValue } from './basic-blocks-value';
+import { basicMarksValue } from './basic-marks-value';
+import { basicNodesValue } from './basic-nodes-value';
+import { blockMenuValue } from './block-menu-value';
+import { blockSelectionValue } from './block-selection-value';
+import { codeBlockValue } from './code-block-value';
+import { columnValue } from './column-value';
+import { copilotValue } from './copilot-value';
+import { cursorOverlayValue } from './cursor-overlay-value';
+import { dateValue } from './date-value';
+import { deserializeCsvValue } from './deserialize-csv-value';
+import { deserializeDocxValue } from './deserialize-docx-value';
+import { deserializeHtmlValue } from './deserialize-html-value';
+import { deserializeMdValue } from './deserialize-md-value';
+import { discussionValue } from './discussion-value';
+import { dndValue } from './dnd-value';
+import { editableVoidsValue } from './editable-voids-value';
+import { emojiValue } from './emoji-value';
+import { equationValue } from './equation-value';
+import { excalidrawValue } from './excalidraw-value';
+import { exitBreakValue } from './exit-break-value';
+import { findReplaceValue } from './find-replace-value';
+import { floatingToolbarValue } from './floating-toolbar-value';
+import { fontValue } from './font-value';
+import { iframeValue } from './iframe-value';
+import { indentValue } from './indent-value';
+import { lineHeightValue } from './line-height-value';
+import { linkValue } from './link-value';
+import { listValue as listClassicValue } from './list-classic-value';
+import { listValue } from './list-value';
+import { mediaValue } from './media-value';
+import { mentionValue } from './mention-value';
+import { blockPlaceholderValue } from './placeholder-value';
+import { pluginRulesValue } from './plugin-rules-value';
+import { previewMdValue } from './preview-md-value';
+import { slashCommandValue } from './slash-command-value';
+import { tabbableValue } from './tabbable-value';
+import { tableValue } from './table-value';
+import { tocValue } from './toc-value';
+import { toggleValue } from './toggle-value';
+
+const values = {
+ ai: aiValue,
+ autoformat: autoformatValue,
+ 'basic-blocks': basicBlocksValue,
+ 'basic-marks': basicMarksValue,
+ 'basic-nodes': basicNodesValue,
+ 'block-menu': blockMenuValue,
+ // 'multi-editors': multiEditorsValue,
+ 'block-placeholder': blockPlaceholderValue,
+ 'block-selection': blockSelectionValue,
+ callout: calloutValue,
+ 'code-block': codeBlockValue,
+ column: columnValue,
+ copilot: copilotValue,
+ csv: deserializeCsvValue,
+ 'cursor-overlay': cursorOverlayValue,
+ date: dateValue,
+ discussion: discussionValue,
+ dnd: dndValue,
+ docx: deserializeDocxValue,
+ 'editable-voids': editableVoidsValue,
+ emoji: emojiValue,
+ // upload: uploadValue,
+ equation: equationValue,
+ // equation: equationValue,
+ excalidraw: excalidrawValue,
+ 'exit-break': exitBreakValue,
+ 'find-replace': findReplaceValue,
+ 'floating-toolbar': floatingToolbarValue,
+ font: fontValue,
+ html: deserializeHtmlValue,
+ // 'huge-document': hugeDocumentValue,
+ iframe: iframeValue,
+ indent: indentValue,
+ 'line-height': lineHeightValue,
+ link: linkValue,
+ list: listValue,
+ 'list-classic': listClassicValue,
+ markdown: deserializeMdValue,
+ media: mediaValue,
+ // 'media-toolbar': mediaToolbarValue,
+ mention: mentionValue,
+ playground: playgroundValue,
+ 'plugin-rules': pluginRulesValue,
+ 'preview-markdown': previewMdValue,
+ 'slash-command': slashCommandValue,
+ tabbable: tabbableValue,
+ table: tableValue,
+ 'text-align': alignValue,
+ toc: tocValue,
+ toggle: toggleValue,
+};
+
+export const DEMO_VALUES = Object.entries(values).reduce(
+ (acc, [key, value]) => {
+ const demoKey = key.replace('Value', '');
+ acc[demoKey] = value;
+
+ return acc;
+ },
+ {} as Record
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/deserialize-csv-value.tsx b/apps/www/src/registry/examples/values/pt-br/deserialize-csv-value.tsx
new file mode 100644
index 0000000000..f856e0b2b3
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/deserialize-csv-value.tsx
@@ -0,0 +1,12 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const deserializeCsvValue: any = (
+
+ CSV
+ Copie e cole conteúdo CSV em uma tabela.
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/deserialize-docx-value.tsx b/apps/www/src/registry/examples/values/pt-br/deserialize-docx-value.tsx
new file mode 100644
index 0000000000..00d20cac01
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/deserialize-docx-value.tsx
@@ -0,0 +1,15 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const deserializeDocxValue: any = (
+
+ Docx
+
+ Importe facilmente conteúdo de documentos Microsoft Word simplesmente
+ copiando e colando o conteúdo Docx no editor.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/deserialize-html-value.tsx b/apps/www/src/registry/examples/values/pt-br/deserialize-html-value.tsx
new file mode 100644
index 0000000000..e0730e4148
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/deserialize-html-value.tsx
@@ -0,0 +1,25 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const deserializeHtmlValue: any = (
+
+ HTML
+
+ Por padrão, quando você cola conteúdo no editor Slate, ele utiliza os
+ dados
+ 'text/plain'
+ da área de transferência. Embora isso seja adequado para certos cenários,
+ há momentos em que você quer que os usuários possam colar conteúdo
+ preservando sua formatação. Para conseguir isso, seu editor deve ser capaz
+ de manipular dados 'text/html'.
+
+
+ Para experimentar a preservação perfeita da formatação, simplesmente copie
+ e cole conteúdo renderizado em HTML (não o código-fonte) de outro site
+ neste editor. Você notará que a formatação do conteúdo colado é mantida.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/deserialize-md-value.tsx b/apps/www/src/registry/examples/values/pt-br/deserialize-md-value.tsx
new file mode 100644
index 0000000000..d6de547f11
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/deserialize-md-value.tsx
@@ -0,0 +1,16 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const deserializeMdValue: any = (
+
+ Markdown
+
+ Copie e cole conteúdo Markdown de editores Markdown populares como{' '}
+ markdown-it.github.io/ no
+ editor para fácil conversão e edição.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/discussion-value.tsx b/apps/www/src/registry/examples/values/pt-br/discussion-value.tsx
new file mode 100644
index 0000000000..48a7cdf45f
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/discussion-value.tsx
@@ -0,0 +1,88 @@
+import type { Value } from 'platejs';
+
+export const discussionValue: Value = [
+ {
+ children: [{ text: 'Discussões' }],
+ type: 'h2',
+ },
+ {
+ children: [
+ { text: 'Revise e refine o conteúdo perfeitamente. Use ' },
+ {
+ children: [
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: 'sugestões',
+ },
+ ],
+ type: 'a',
+ url: '/docs/suggestion',
+ },
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: ' ',
+ },
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: 'como este texto adicionado',
+ },
+ { text: ' ou para ' },
+ {
+ suggestion: true,
+ suggestion_playground2: {
+ id: 'playground2',
+ createdAt: Date.now(),
+ type: 'remove',
+ userId: 'bob',
+ },
+ text: 'marcar texto para remoção',
+ },
+ { text: '. Discuta alterações usando ' },
+ {
+ children: [
+ { comment: true, comment_discussion1: true, text: 'comentários' },
+ ],
+ type: 'a',
+ url: '/docs/comment',
+ },
+ {
+ comment: true,
+ comment_discussion1: true,
+ text: ' em muitos segmentos de texto',
+ },
+ { text: '. Você pode até ter ' },
+ {
+ comment: true,
+ comment_discussion2: true,
+ suggestion: true,
+ suggestion_playground3: {
+ id: 'playground3',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'charlie',
+ },
+ text: 'anotações',
+ },
+ { text: ' sobrepostas!' },
+ ],
+ type: 'p',
+ },
+];
diff --git a/apps/www/src/registry/examples/values/pt-br/dnd-value.tsx b/apps/www/src/registry/examples/values/pt-br/dnd-value.tsx
new file mode 100644
index 0000000000..62b33460ae
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/dnd-value.tsx
@@ -0,0 +1,40 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const dndValue: any = (
+
+ Arrastar e Soltar
+
+ Reorganize facilmente o conteúdo do seu documento usando arrastar e
+ soltar.
+
+ Como usar:
+
+
+ Passe o mouse sobre o lado esquerdo de um bloco para ver a alça de
+ arrasto (seis pontos).
+
+
+
+
+ Clique e segure a alça, depois arraste o bloco para um novo local.
+
+
+
+ Solte para colocar o bloco em sua nova posição.
+
+ Experimente! Arraste estes itens para reordená-los:
+
+ Primeiro item
+
+
+ Segundo item
+
+
+ Terceiro item
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/editable-voids-value.tsx b/apps/www/src/registry/examples/values/pt-br/editable-voids-value.tsx
new file mode 100644
index 0000000000..c93a38566d
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/editable-voids-value.tsx
@@ -0,0 +1,21 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const editableVoidsValue: any = (
+
+
+ Além de nós que contêm texto editável, você pode inserir nós vazios (void
+ nodes), que também podem conter elementos editáveis, entradas ou até mesmo
+ outro editor Slate inteiro.
+
+
+
+
+
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/emoji-value.tsx b/apps/www/src/registry/examples/values/pt-br/emoji-value.tsx
new file mode 100644
index 0000000000..14b7f7d6c9
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/emoji-value.tsx
@@ -0,0 +1,16 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const emojiValue: any = (
+
+ Emoji
+ Expresse-se com um toque de diversão 🎉 e emoção 😃.
+
+ Escolha na barra de ferramentas ou digite dois pontos para abrir a lista
+ suspensa.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/equation-value.tsx b/apps/www/src/registry/examples/values/pt-br/equation-value.tsx
new file mode 100644
index 0000000000..7573afb468
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/equation-value.tsx
@@ -0,0 +1,95 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const equationValue: any = (
+
+
+ Equação
+
+
+
+ Equações permitem que você expresse conceitos matemáticos complexos em
+ formatos inline e bloco.
+
+
+
+ Principais características:
+
+
+ Suporte à sintaxe LaTeX
+
+
+ Formatos de equação inline e bloco
+
+
+ Exemplo de equação inline:
+
+
+
+ (Famosa equação de Einstein)
+
+
+ Exemplos de equação em bloco:
+
+
+
+
+
+ A fórmula quadrática para resolver
+
+
+
+ .
+
+
+
+
+
+ O teorema fundamental do cálculo.
+
+
+ Tente estas ações:
+
+
+
+ Clique em qualquer equação para editá-la. Pressione Esc para fechar o
+ menu sem editar.
+
+
+
+ Você pode navegar pela equação usando as teclas de seta
+
+
+
+ Use o comando de barra (/equation) para inserir uma nova equação
+
+
+
+
+ Use o comando de barra (/inline equation) para equações inline
+
+
+
+
+ Uso avançado: Combine equações com outros elementos como tabelas ou
+ blocos de código para documentação científica abrangente. Por exemplo:
+
+
+
+ A equação de Schrödinger,
+
+
+
+ , é fundamental na mecânica quântica.
+
+
+
+ Experimente diferentes tipos de equações e formatações para criar
+ conteúdo matemático rico em seus documentos.
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/excalidraw-value.tsx b/apps/www/src/registry/examples/values/pt-br/excalidraw-value.tsx
new file mode 100644
index 0000000000..31e4511304
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/excalidraw-value.tsx
@@ -0,0 +1,71 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+import type { TExcalidrawElement } from '@platejs/excalidraw';
+import type { NodeProps } from 'platejs';
+
+export const excalidrawInitialData: NodeProps = {
+ data: {
+ elements: [
+ {
+ id: 'oDVXy8D6rom3H1-LLH2-f',
+ angle: 0,
+ backgroundColor: 'transparent',
+ fillStyle: 'hachure',
+ groupIds: [],
+ height: 141.976_562_5,
+ isDeleted: false,
+ opacity: 100,
+ roughness: 1,
+ seed: 1_968_410_350,
+ strokeColor: '#000000',
+ strokeStyle: 'solid',
+ strokeWidth: 1,
+ type: 'rectangle',
+ version: 141,
+ versionNonce: 361_174_001,
+ width: 186.472_656_25,
+ x: 100.503_906_25,
+ y: 93.675_781_25,
+ },
+ {
+ id: '-xMIs_0jIFqvpx-R9UnaG',
+ angle: 0,
+ backgroundColor: 'transparent',
+ fillStyle: 'hachure',
+ groupIds: [],
+ height: 129.511_718_75,
+ isDeleted: false,
+ opacity: 100,
+ roughness: 1,
+ seed: 957_947_807,
+ strokeColor: '#000000',
+ strokeStyle: 'solid',
+ strokeWidth: 1,
+ type: 'ellipse',
+ version: 47,
+ versionNonce: 1_128_618_623,
+ width: 198.218_75,
+ x: 300.570_312_5,
+ y: 190.691_406_25,
+ },
+ ],
+ state: { currentItemFontFamily: 1, viewBackgroundColor: '#AFEEEE' },
+ },
+};
+
+export const excalidrawValue: any = (
+
+ Excalidraw
+
+ Liberte sua criatividade com o plugin Excalidraw, que permite que você
+ incorpore e desenhe diagramas diretamente no seu editor.
+
+
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/exit-break-value.tsx b/apps/www/src/registry/examples/values/pt-br/exit-break-value.tsx
new file mode 100644
index 0000000000..cf8b3d1c9f
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/exit-break-value.tsx
@@ -0,0 +1,48 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+import { createTable } from './table-value';
+
+jsx;
+
+export const trailingBlockValue: any = (
+
+ Bloco Final
+ Sempre tenha um parágrafo final no fim do seu editor.
+
+);
+
+export const exitBreakValue: any = (
+
+ Quebra de Saída
+
+ Saia de estruturas de blocos aninhados usando atalhos de teclado. O plugin
+ determina automaticamente o ponto de saída apropriado:
+
+
+
+ ⌘⏎ – Sair e inserir um novo bloco após a estrutura atual
+
+
+ ⌘⇧⏎ – Sair e inserir um novo bloco antes da estrutura atual
+
+
+ Automático – Encontra o ancestral mais próximo que permite irmãos de
+ parágrafo
+
+
+
+ Quebras de saída funcionam de forma inteligente em estruturas aninhadas
+ como tabelas:
+
+
+ {createTable()}
+
+
+ Tente ⌘⏎ para sair deste bloco de código.
+
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/find-replace-value.tsx b/apps/www/src/registry/examples/values/pt-br/find-replace-value.tsx
new file mode 100644
index 0000000000..f503b30423
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/find-replace-value.tsx
@@ -0,0 +1,16 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const findReplaceValue: any = (
+
+
+ Este é um texto editável que você pode pesquisar. Enquanto você pesquisa,
+ ele procura por sequências de texto correspondentes e adiciona{' '}
+ decorações a elas em tempo real.
+
+ Experimente você mesmo digitando na caixa de pesquisa acima!
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/floating-toolbar-value.tsx b/apps/www/src/registry/examples/values/pt-br/floating-toolbar-value.tsx
new file mode 100644
index 0000000000..1f7da2c6c5
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/floating-toolbar-value.tsx
@@ -0,0 +1,55 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const floatingToolbarValue: any = (
+
+ Barra de Ferramentas Flutuante
+
+ A barra de ferramentas flutuante fornece acesso rápido a opções de
+ formatação e ações para o texto selecionado.
+
+ Como usar a barra de ferramentas flutuante:
+
+
+ Selecione qualquer texto para invocar a barra de ferramentas flutuante.
+
+
+ Com a barra de ferramentas flutuante, você pode:
+
+ Pedir ajuda à IA
+
+
+ Adicionar um comentário ao texto selecionado
+
+
+ Transformar um tipo de bloco em outro
+
+
+
+ Aplicar formatação de texto: negrito, itálico, sublinhado, tachado,
+ código
+
+
+
+
+ Tente selecionar algum texto abaixo para ver a barra de ferramentas
+ flutuante em ação:
+
+
+
+ Texto em negrito
+ ,
+ texto em itálico
+ ,
+ texto sublinhado
+ , e
+
+ formatação combinada
+
+ .
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/font-value.tsx b/apps/www/src/registry/examples/values/pt-br/font-value.tsx
new file mode 100644
index 0000000000..a8da372eee
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/font-value.tsx
@@ -0,0 +1,43 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const fontValue: any = (
+
+ Cores
+
+ Adicione{' '}
+
+ m
+
+
+ ú
+
+
+ l
+
+
+ t
+
+
+ i
+
+
+ p
+
+
+ l
+
+
+ a
+ {' '}
+ fonte e cores de{' '}
+
+ fundo
+ {' '}
+ para criar texto vibrante e atraente.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/huge-document-value.tsx b/apps/www/src/registry/examples/values/pt-br/huge-document-value.tsx
new file mode 100644
index 0000000000..980e6e14d5
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/huge-document-value.tsx
@@ -0,0 +1,42 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import type { Descendant, Value } from 'platejs';
+
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+const HEADINGS = 300;
+const PARAGRAPHS = 10;
+
+export const createHugeDocumentValue = () => {
+ const hugeDocument: Descendant[] = [];
+
+ for (let h = 0; h < HEADINGS; h++) {
+ hugeDocument.push(
+ (
+ Do voluptate enim commodo quis ad aliqua dolore enim eu nisi.
+ ) as any
+ );
+
+ for (let p = 0; p < PARAGRAPHS; p++) {
+ hugeDocument.push(
+ (
+
+ Ex est consequat anim ad deserunt sint. Ea excepteur consequat amet
+ amet excepteur culpa nulla. Voluptate exercitation pariatur enim.
+ Excepteur ea nulla nostrud est ex sunt anim. Sunt laborum et et ea
+ aliquip excepteur sint nulla amet. Sunt sit cillum amet. Anim esse
+ ut irure ipsum irure proident consectetur eu velit esse. Laborum
+ minim laborum laborum sunt eiusmod aliqua fugiat adipisicing. Cillum
+ aliqua exercitation ex aliquip aliquip amet aliquip est eiusmod
+ tempor pariatur veniam adipisicing ad. Officia sunt ipsum
+ adipisicing eu quis laborum do cupidatat officia dolor.
+
+ ) as any
+ );
+ }
+ }
+
+ return hugeDocument as Value;
+};
diff --git a/apps/www/src/registry/examples/values/pt-br/iframe-value.tsx b/apps/www/src/registry/examples/values/pt-br/iframe-value.tsx
new file mode 100644
index 0000000000..ab09e5bdfa
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/iframe-value.tsx
@@ -0,0 +1,21 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const iframeValue: any = (
+
+
+ Neste exemplo, o documento é renderizado em um iframe{' '}
+ controlado. Isso é particularmente útil quando você
+ precisa separar os estilos do conteúdo do editor daqueles que endereçam
+ sua interface de usuário.
+
+
+ Este também é o único método confiável para visualizar quaisquer{' '}
+ consultas de mídia (media queries)
+ em seu CSS.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/indent-value.tsx b/apps/www/src/registry/examples/values/pt-br/indent-value.tsx
new file mode 100644
index 0000000000..81b3e414da
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/indent-value.tsx
@@ -0,0 +1,18 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const indentValue: any = (
+
+ Indentação
+
+ Controle facilmente a indentação de blocos específicos para destacar
+ informações importantes e melhorar a estrutura visual.
+
+
+ Por exemplo, este parágrafo parece pertencer ao anterior.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/line-height-value.tsx b/apps/www/src/registry/examples/values/pt-br/line-height-value.tsx
new file mode 100644
index 0000000000..29e0719869
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/line-height-value.tsx
@@ -0,0 +1,19 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const lineHeightValue: any = (
+
+ Altura da Linha
+
+ Controle a altura da linha do seu texto para melhorar a legibilidade e
+ ajustar o espaçamento entre as linhas.
+
+
+ Escolha a altura de linha ideal para garantir uma leitura confortável e um
+ documento esteticamente agradável.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/link-value.tsx b/apps/www/src/registry/examples/values/pt-br/link-value.tsx
new file mode 100644
index 0000000000..d5d3025cbc
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/link-value.tsx
@@ -0,0 +1,23 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const linkValue: any = (
+
+ Link
+
+ Adicione{' '}
+
+ hiperlinks
+ {' '}
+ ao seu texto para referenciar fontes externas ou fornecer informações
+ adicionais usando o plugin Link.
+
+
+ Crie hiperlinks facilmente usando a barra de ferramentas ou colando uma
+ URL enquanto seleciona o texto desejado.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/list-classic-value.tsx b/apps/www/src/registry/examples/values/pt-br/list-classic-value.tsx
new file mode 100644
index 0000000000..43b72e90b6
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/list-classic-value.tsx
@@ -0,0 +1,69 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+import { KEYS } from 'platejs';
+
+jsx;
+
+export const listValue: any = (
+
+ ✍️ Lista
+
+
+
+
+
+ Gatos
+
+
+ Cães
+
+
+ Pássaros
+
+
+ Papagaios
+
+
+ Corujas
+
+
+ Corujas-das-torres
+
+
+ Corujas-das-neves
+
+
+
+
+
+
+
+
+ Vermelho
+
+
+ Azul
+
+
+ Azul claro
+
+
+ Azul escuro
+
+
+ Azul marinho
+
+
+ Azul turquesa
+
+
+
+
+
+
+ Verde
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/list-value.tsx b/apps/www/src/registry/examples/values/pt-br/list-value.tsx
new file mode 100644
index 0000000000..63e2ce5751
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/list-value.tsx
@@ -0,0 +1,62 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const listValue: any = (
+
+ Lista
+
+
+ Crie listas indentadas com múltiplos níveis de indentação e personalize o
+ tipo de estilo de lista para cada nível.
+
+
+ Tarefa 1
+
+
+
+ Disco 1
+
+
+ Disco 2
+
+
+ Tarefa 2
+
+
+ Romano 1
+
+
+ Decimal 11
+
+
+ Decimal 111
+
+
+ Decimal 112
+
+
+ Decimal 12
+
+
+ Decimal 13
+
+
+ Romano 2
+
+
+ Decimal 11
+
+
+ Decimal 12
+
+
+ Romano 3
+
+
+ Romano 4
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/media-value.tsx b/apps/www/src/registry/examples/values/pt-br/media-value.tsx
new file mode 100644
index 0000000000..102e2dcbe7
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/media-value.tsx
@@ -0,0 +1,85 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const imageValue: any = (
+
+ Imagem
+ Adicione imagens fazendo upload ou fornecendo a URL da imagem:
+
+
+
+ Personalize legendas de imagens e redimensione imagens.
+
+);
+
+export const mediaPlaceholderValue: any = (
+
+ Upload
+
+ Nosso editor suporta vários tipos de mídia para upload, incluindo imagens,
+ vídeos, áudio e arquivos.
+
+
+
+
+
+ Status de upload em tempo real e rastreamento de progresso
+
+
+
+
+
+ Limites de tamanho de arquivo configuráveis e configurações de upload em
+ lote
+
+
+
+
+
+ Mensagens de erro claras para quaisquer problemas de upload
+
+
+ Experimente agora - arraste uma imagem da sua área de trabalho ou clique
+ no botão de upload na barra de ferramentas
+
+
+);
+
+export const mediaValue: any = (
+
+ {imageValue}
+ {mediaPlaceholderValue}
+
+ Incorporar (Embed)
+ Incorpore vários tipos de conteúdo, como vídeos e tweets:
+
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/mention-value.tsx b/apps/www/src/registry/examples/values/pt-br/mention-value.tsx
new file mode 100644
index 0000000000..bd88e6f189
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/mention-value.tsx
@@ -0,0 +1,26 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const mentionValue: any = (
+
+ Menção
+
+ Mencione e referencie outros usuários ou entidades em seu texto usando
+ @-menções.
+
+
+ Tente mencionar{' '}
+
+
+ {' '}
+ ou{' '}
+
+
+
+ .
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/multi-editors-value.tsx b/apps/www/src/registry/examples/values/pt-br/multi-editors-value.tsx
new file mode 100644
index 0000000000..639736e472
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/multi-editors-value.tsx
@@ -0,0 +1,43 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import type { Descendant } from 'platejs';
+
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const createMultiEditorsValue = () => {
+ const multiEditors: Descendant[][] = [];
+
+ for (let h = 0; h < 300; h++) {
+ const multiEditor: Descendant[] = [];
+ multiEditor.push(
+ (Amet duis nisi ea enim laborum laboris.) as any
+ );
+
+ for (let p = 0; p < 2; p++) {
+ multiEditor.push(
+ (
+
+ Laborum dolor et tempor consectetur amet ullamco consectetur ullamco
+ irure incididunt reprehenderit ullamco nulla tempor. Laboris veniam
+ commodo id in ex ullamco incididunt nulla eu Lorem adipisicing
+ deserunt duis ad. Mollit magna enim exercitation amet proident
+ reprehenderit magna nulla officia ad in non. Magna magna adipisicing
+ fugiat cillum do esse eu adipisicing. Culpa dolor non Lorem. Dolore
+ non voluptate velit in eu culpa velit. Exercitation fugiat cupidatat
+ adipisicing duis veniam proident irure ea excepteur aliqua esse ad
+ cupidatat adipisicing id. Ut exercitation proident ea eiusmod enim
+ non minim proident Lorem aliqua officia voluptate ullamco culpa
+ Lorem. Exercitation eiusmod dolor nostrud qui excepteur. Dolor
+ commodo duis reprehenderit excepteur laboris do minim qui.
+
+ ) as any
+ );
+ }
+
+ multiEditors.push(multiEditor);
+ }
+
+ return multiEditors;
+};
diff --git a/apps/www/src/registry/examples/values/pt-br/placeholder-value.tsx b/apps/www/src/registry/examples/values/pt-br/placeholder-value.tsx
new file mode 100644
index 0000000000..e59b80dbd0
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/placeholder-value.tsx
@@ -0,0 +1,18 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const blockPlaceholderValue: any = (
+
+ Placeholder
+
+ Mostre um placeholder ao selecionar um bloco vazio. Experimente no próximo
+ bloco:
+
+
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/playground-value.tsx b/apps/www/src/registry/examples/values/pt-br/playground-value.tsx
new file mode 100644
index 0000000000..5780693fe9
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/playground-value.tsx
@@ -0,0 +1,545 @@
+import type { Value } from 'platejs';
+
+export const playgroundValue: Value = [
+ // Intro
+ {
+ children: [{ text: 'Bem-vindo ao Plate Playground!' }],
+ type: 'h1',
+ },
+ {
+ children: [
+ { text: 'Experimente um editor de rich-text moderno construído com ' },
+ { children: [{ text: 'Slate' }], type: 'a', url: 'https://slatejs.org' },
+ { text: ' e ' },
+ { children: [{ text: 'React' }], type: 'a', url: 'https://reactjs.org' },
+ {
+ text: '. Este playground mostra apenas uma parte das capacidades do Plate. ',
+ },
+ {
+ children: [{ text: 'Explore a documentação' }],
+ type: 'a',
+ url: '/docs',
+ },
+ { text: ' para descobrir mais.' },
+ ],
+ type: 'p',
+ },
+ // Suggestions & Comments Section
+ {
+ children: [{ text: 'Edição Colaborativa' }],
+ type: 'h2',
+ },
+ {
+ children: [
+ { text: 'Revise e refine o conteúdo perfeitamente. Use ' },
+ {
+ children: [
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: 'sugestões',
+ },
+ ],
+ type: 'a',
+ url: '/docs/suggestion',
+ },
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: ' ',
+ },
+ {
+ suggestion: true,
+ suggestion_playground1: {
+ id: 'playground1',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'alice',
+ },
+ text: 'como este texto adicionado',
+ },
+ { text: ' ou para ' },
+ {
+ suggestion: true,
+ suggestion_playground2: {
+ id: 'playground2',
+ createdAt: Date.now(),
+ type: 'remove',
+ userId: 'bob',
+ },
+ text: 'marcar texto para remoção',
+ },
+ { text: '. Discuta alterações usando ' },
+ {
+ children: [
+ { comment: true, comment_discussion1: true, text: 'comentários' },
+ ],
+ type: 'a',
+ url: '/docs/comment',
+ },
+ {
+ comment: true,
+ comment_discussion1: true,
+ text: ' em muitos segmentos de texto',
+ },
+ { text: '. Você pode até ter ' },
+ {
+ comment: true,
+ comment_discussion2: true,
+ suggestion: true,
+ suggestion_playground3: {
+ id: 'playground3',
+ createdAt: Date.now(),
+ type: 'insert',
+ userId: 'charlie',
+ },
+ text: 'anotações',
+ },
+ { text: ' sobrepostas!' },
+ ],
+ type: 'p',
+ },
+ // AI Section
+ {
+ children: [{ text: 'Edição com IA' }],
+ type: 'h2',
+ },
+ {
+ children: [
+ { text: 'Aumente sua produtividade com o ' },
+ {
+ children: [{ text: 'AI SDK' }],
+ type: 'a',
+ url: '/docs/ai',
+ },
+ { text: ' integrado. Pressione ' },
+ { kbd: true, text: '⌘+J' },
+ { text: ' ou ' },
+ { kbd: true, text: 'Espaço' },
+ { text: ' em uma linha vazia para:' },
+ ],
+ type: 'p',
+ },
+ {
+ children: [
+ { text: 'Gerar conteúdo (continuar escrevendo, resumir, explicar)' },
+ ],
+ indent: 1,
+ listStyleType: 'disc',
+ type: 'p',
+ },
+ {
+ children: [
+ {
+ text: 'Editar texto existente (melhorar, corrigir gramática, mudar tom)',
+ },
+ ],
+ indent: 1,
+ listStyleType: 'disc',
+ type: 'p',
+ },
+ // Core Features Section (Combined)
+ {
+ children: [{ text: 'Edição de Conteúdo Rico' }],
+ type: 'h2',
+ },
+ {
+ children: [
+ { text: 'Estruture seu conteúdo com ' },
+ {
+ children: [{ text: 'títulos' }],
+ type: 'a',
+ url: '/docs/heading',
+ },
+ { text: ', ' },
+ {
+ children: [{ text: 'listas' }],
+ type: 'a',
+ url: '/docs/list',
+ },
+ { text: ', e ' },
+ {
+ children: [{ text: 'citações' }],
+ type: 'a',
+ url: '/docs/blockquote',
+ },
+ { text: '. Aplique ' },
+ {
+ children: [{ text: 'marcas' }],
+ type: 'a',
+ url: '/docs/basic-marks',
+ },
+ { text: ' como ' },
+ { bold: true, text: 'negrito' },
+ { text: ', ' },
+ { italic: true, text: 'itálico' },
+ { text: ', ' },
+ { text: 'sublinhado', underline: true },
+ { text: ', ' },
+ { strikethrough: true, text: 'tachado' },
+ { text: ', e ' },
+ { code: true, text: 'código' },
+ { text: '. Use ' },
+ {
+ children: [{ text: 'formatação automática' }],
+ type: 'a',
+ url: '/docs/autoformat',
+ },
+ { text: ' para atalhos tipo ' },
+ {
+ children: [{ text: 'Markdown' }],
+ type: 'a',
+ url: '/docs/markdown',
+ },
+ { text: ' (ex: ' },
+ { kbd: true, text: '* ' },
+ { text: ' para listas, ' },
+ { kbd: true, text: '# ' },
+ { text: ' para H1).' },
+ ],
+ type: 'p',
+ },
+ {
+ children: [
+ {
+ text: 'Citações em bloco são ótimas para destacar informações importantes.',
+ },
+ ],
+ type: 'blockquote',
+ },
+ {
+ children: [
+ { children: [{ text: 'function hello() {' }], type: 'code_line' },
+ {
+ children: [
+ { text: " console.info('Blocos de código são suportados!');" },
+ ],
+ type: 'code_line',
+ },
+ { children: [{ text: '}' }], type: 'code_line' },
+ ],
+ lang: 'javascript',
+ type: 'code_block',
+ },
+ {
+ children: [
+ { text: 'Crie ' },
+ {
+ children: [{ text: 'links' }],
+ type: 'a',
+ url: '/docs/link',
+ },
+ { text: ', ' },
+ {
+ children: [{ text: '@menção' }],
+ type: 'a',
+ url: '/docs/mention',
+ },
+ { text: ' usuários como ' },
+ { children: [{ text: '' }], type: 'mention', value: 'Alice' },
+ { text: ', ou insira ' },
+ {
+ children: [{ text: 'emojis' }],
+ type: 'a',
+ url: '/docs/emoji',
+ },
+ { text: ' ✨. Use o ' },
+ {
+ children: [{ text: 'comando de barra' }],
+ type: 'a',
+ url: '/docs/slash-command',
+ },
+ { text: ' (/) para acesso rápido aos elementos.' },
+ ],
+ type: 'p',
+ },
+ // Table Section
+ {
+ children: [{ text: 'Como o Plate se Compara' }],
+ type: 'h3',
+ },
+ {
+ children: [
+ {
+ text: 'O Plate oferece muitos recursos prontos para uso como plugins gratuitos e de código aberto.',
+ },
+ ],
+ type: 'p',
+ },
+ {
+ children: [
+ {
+ children: [
+ {
+ children: [
+ { children: [{ bold: true, text: 'Recurso' }], type: 'p' },
+ ],
+ type: 'th',
+ },
+ {
+ children: [
+ {
+ children: [{ bold: true, text: 'Plate (Grátis & OSS)' }],
+ type: 'p',
+ },
+ ],
+ type: 'th',
+ },
+ {
+ children: [
+ { children: [{ bold: true, text: 'Tiptap' }], type: 'p' },
+ ],
+ type: 'th',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'IA' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [{ children: [{ text: 'Extensão Paga' }], type: 'p' }],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'Comentários' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [{ children: [{ text: 'Extensão Paga' }], type: 'p' }],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'Sugestões' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [
+ { children: [{ text: 'Pago (Comments Pro)' }], type: 'p' },
+ ],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'Seletor de Emoji' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [{ children: [{ text: 'Extensão Paga' }], type: 'p' }],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'Índice (TOC)' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [{ children: [{ text: 'Extensão Paga' }], type: 'p' }],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [{ children: [{ text: 'Alça de Arrastar' }], type: 'p' }],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [{ children: [{ text: 'Extensão Paga' }], type: 'p' }],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ {
+ children: [
+ {
+ children: [
+ { children: [{ text: 'Colaboração (Yjs)' }], type: 'p' },
+ ],
+ type: 'td',
+ },
+ {
+ children: [
+ {
+ attributes: { align: 'center' },
+ children: [{ text: '✅' }],
+ type: 'p',
+ },
+ ],
+ type: 'td',
+ },
+ {
+ children: [
+ { children: [{ text: 'Hocuspocus (OSS/Pago)' }], type: 'p' },
+ ],
+ type: 'td',
+ },
+ ],
+ type: 'tr',
+ },
+ ],
+
+ colSizes: [160, 170, 200],
+ type: 'table',
+ },
+ // Media Section
+ {
+ children: [{ text: 'Imagens e Mídia' }],
+ type: 'h3',
+ },
+ {
+ children: [
+ {
+ text: 'Incorpore mídia rica como imagens diretamente em seu conteúdo. Suporta ',
+ },
+ {
+ children: [{ text: 'Uploads de mídia' }],
+ type: 'a',
+ url: '/docs/media',
+ },
+ {
+ text: ' e ',
+ },
+ {
+ children: [{ text: 'arrastar e soltar' }],
+ type: 'a',
+ url: '/docs/dnd',
+ },
+ {
+ text: ' para uma experiência suave.',
+ },
+ ],
+ type: 'p',
+ },
+ {
+ attributes: { align: 'center' },
+ caption: [
+ {
+ children: [{ text: 'Imagens com legendas fornecem contexto.' }],
+ type: 'p',
+ },
+ ],
+ children: [{ text: '' }],
+ type: 'img',
+ url: 'https://images.unsplash.com/photo-1712688930249-98e1963af7bd?q=80&w=600&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D',
+ width: '75%',
+ },
+ {
+ children: [{ text: '' }],
+ isUpload: true,
+ name: 'exemplo.pdf',
+ type: 'file',
+ url: 'https://s26.q4cdn.com/900411403/files/doc_downloads/test.pdf',
+ },
+ {
+ children: [{ text: '' }],
+ type: 'audio',
+ url: 'https://samplelib.com/lib/preview/mp3/sample-3s.mp3',
+ },
+ {
+ children: [{ text: 'Índice' }],
+ type: 'h3',
+ },
+ {
+ children: [{ text: '' }],
+ type: 'toc',
+ },
+ {
+ children: [{ text: '' }],
+ type: 'p',
+ },
+];
diff --git a/apps/www/src/registry/examples/values/pt-br/plugin-rules-value.tsx b/apps/www/src/registry/examples/values/pt-br/plugin-rules-value.tsx
new file mode 100644
index 0000000000..6e67552aa8
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/plugin-rules-value.tsx
@@ -0,0 +1,100 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const pluginRulesValue: any = (
+
+ Regras de Plugin
+
+ Regras de plugin controlam como os blocos respondem a Enter, Backspace,
+ seleção e normalização.
+
+
+ Regras de Quebra (Break)
+
+
+ Divisão e Redefinição de Título (splitReset):{' '}
+ Pressione Enter no meio do título para dividir e redefinir o novo bloco
+ para parágrafo.
+
+
+ Pressione Enter após "Pressione" para ver o comportamento de splitReset
+
+
+
+ Citação em bloco com quebras de linha: Enter adiciona
+ quebras de linha, Enter em linhas vazias redefine para parágrafo.
+
+
+ Esta citação em bloco usa regras de quebra de linha. Pressione Enter aqui
+ para quebras de linha.
+
+
+ Regras de Exclusão (Delete)
+
+
+ Redefinição de bloco de código: Backspace em bloco de
+ código vazio redefine para parágrafo.
+
+
+ console.info('Olá mundo');
+
+
+
+
+
+
+ Itens de lista: Backspace no início remove a
+ formatação de lista.
+
+
+ Pressione Backspace no início para remover a formatação de lista
+
+
+ Regras de Seleção
+
+
+ Afinidade rígida (código): Use as setas ao redor de{' '}
+ marcas de código - requer dois pressionamentos de
+ tecla para cruzar fronteiras.
+
+
+
+ Afinidade direcional: Use as setas ao redor de texto{' '}
+ sobrescrito - a afinidade do cursor depende da
+ direção do movimento.
+
+
+
+ Link direcional: Navegue com as setas ao redor{' '}
+ deste link para testar o comportamento
+ direcional.
+
+
+ Regras de Normalização
+
+
+ Remoção de link vazio: Exclua todo o texto{' '}
+ deste link - o elemento de link será
+ removido automaticamente.
+
+
+ Regras de Mesclagem (Merge)
+
+
+ Elementos vazios (Void):
+
+
+
+ Pressione Backspace no início - o elemento vazio é selecionado em vez de
+ excluído.
+
+
+
+
+
+ Backspace no início remove o parágrafo vazio acima
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/preview-md-value.tsx b/apps/www/src/registry/examples/values/pt-br/preview-md-value.tsx
new file mode 100644
index 0000000000..aa6301cc7e
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/preview-md-value.tsx
@@ -0,0 +1,22 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const previewMdValue: any = (
+
+ 👀 Pré-visualização Markdown
+
+ O Slate é flexível o suficiente para adicionar **decorações** que podem
+ formatar texto com base em seu conteúdo. Por exemplo, este editor tem
+ decorações de pré-visualização **Markdown** nele, para tornar _muito_
+ simples fazer um editor com pré-visualização de `Markdown` integrada.
+
+ - Lista.
+ Citação em bloco.
+ ---
+ ## Experimente!
+ Experimente você mesmo!
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/slash-command-value.tsx b/apps/www/src/registry/examples/values/pt-br/slash-command-value.tsx
new file mode 100644
index 0000000000..edc91767c6
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/slash-command-value.tsx
@@ -0,0 +1,46 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const slashCommandValue: any = (
+
+
+ Comando de Barra
+
+
+
+ O menu de barra fornece acesso rápido a várias opções de formatação e
+ tipos de conteúdo.
+
+
+
+
+ Digite '/' em qualquer lugar do seu documento para abrir o menu de
+ barra.
+
+
+
+
+ Comece a digitar para filtrar opções ou use as setas para navegar.
+
+
+
+ Pressione Enter ou clique para selecionar uma opção.
+
+
+ Pressione Esc para fechar o menu sem selecionar.
+
+ Opções disponíveis incluem:
+
+ Títulos: Título 1, Título 2, Título 3
+
+
+ Listas: Lista com marcadores, Lista numerada
+
+
+ Elementos Inline: Data
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/soft-break-value.tsx b/apps/www/src/registry/examples/values/pt-br/soft-break-value.tsx
new file mode 100644
index 0000000000..6454d84444
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/soft-break-value.tsx
@@ -0,0 +1,27 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const softBreakValue: any = (
+
+ Quebra Suave
+
+ Personalize como quebras suaves (quebras de linha dentro de um parágrafo)
+ são tratadas usando regras configuráveis
+
+
+ hotkey – Use teclas de atalho como ⇧⏎ para inserir uma quebra suave em
+ qualquer lugar dentro de um parágrafo.
+
+
+ query – Defina regras personalizadas para limitar quebras suaves a tipos
+ de blocos específicos.
+
+ Tente aqui ⏎
+
+ E aqui ⏎ também.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/tabbable-value.tsx b/apps/www/src/registry/examples/values/pt-br/tabbable-value.tsx
new file mode 100644
index 0000000000..025a6e75d9
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/tabbable-value.tsx
@@ -0,0 +1,55 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const tabbableValue: any = (
+
+ Tabbable (Navegação por Tab)
+
+ Garanta uma experiência de navegação por tab suave dentro do seu editor
+ com o plugin Tabbable.
+
+
+ Lide corretamente com ordens de tabulação para nós vazios (void nodes),
+ permitindo navegação e interação contínuas. Sem este plugin, elementos DOM
+ dentro de nós vazios vêm após o editor na ordem de tabulação.
+
+
+
+
+
+
+
+ Coloque seu cursor aqui e tente pressionar tab ou shift+tab.
+
+ Item de lista 1
+
+
+ Item de lista 2
+
+
+ Item de lista 3
+
+
+ if (true) {'{'}
+
+ {'// <-'} Coloque o cursor no início da linha e pressione tab
+
+ {'}'}
+
+
+ Neste exemplo, o plugin está desativado quando o cursor está dentro de uma
+ lista ou um bloco de código. Você pode personalizar isso usando a opção{' '}
+ query.
+
+
+
+
+
+ Quando você pressiona tab no final do editor, o foco deve ir para o botão
+ abaixo.
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/table-value.tsx b/apps/www/src/registry/examples/values/pt-br/table-value.tsx
new file mode 100644
index 0000000000..bf81607be7
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/table-value.tsx
@@ -0,0 +1,119 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const createTable = (spanning?: boolean): any => (
+
+
+ {spanning ? (
+
+
+
+ Plugin
+
+
+
+ ) : (
+
+
+
+ Plugin
+
+
+
+
+ Elemento
+
+
+
+
+ Inline
+
+
+
+
+ Void
+
+
+
+ )}
+
+
+
+
+ Título
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Não
+
+
+
+
+
+ Imagem
+
+
+
+ Sim
+
+
+ Não
+
+
+ Sim
+
+
+
+
+
+ Menção
+
+
+
+ Sim
+
+
+ Sim
+
+
+ Sim
+
+
+
+
+);
+
+export const tableValue: any = (
+
+ Tabela
+
+ Crie tabelas personalizáveis com colunas e linhas redimensionáveis,
+ permitindo que você projete layouts estruturados.
+
+ {createTable()}
+
+);
+
+export const tableMergeValue: any = (
+
+ Mesclagem de Tabela
+
+ Você pode desativar a mesclagem usando a opção{' '}
+ disableMerge: true. Experimente:
+
+ {createTable(true)}
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/toc-value.tsx b/apps/www/src/registry/examples/values/pt-br/toc-value.tsx
new file mode 100644
index 0000000000..c23400db4c
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/toc-value.tsx
@@ -0,0 +1,66 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const tocValue: any = (
+
+
+ Índice (Table of Contents)
+
+
+
+ O recurso de Índice (TOC) permite que você crie uma visão geral
+ atualizada automaticamente da estrutura do seu documento.
+
+
+ Como usar o Índice:
+
+ Digite "/toc" e pressione Enter para criar o TOC.
+
+
+
+ O TOC é atualizado automaticamente quando você modifica títulos no
+ documento.
+
+
+
+
+
+ Conteúdo de Exemplo
+
+
+ Este é um exemplo de conteúdo que seria refletido no Índice.
+
+
+ Subseção
+
+
+ Adicionar ou modificar títulos em seu documento atualizará
+ automaticamente o TOC.
+
+
+ Benefícios de Usar TOC
+
+
+ Um Índice melhora a navegação do documento e fornece uma rápida visão
+ geral da estrutura do seu conteúdo.
+
+
+
+);
+
+export const tocPlaygroundValue: any = (
+
+
+
+
+
+
+ Clique em qualquer título no índice para rolar suavemente para essa
+ seção.
+
+
+
+);
diff --git a/apps/www/src/registry/examples/values/pt-br/toggle-value.tsx b/apps/www/src/registry/examples/values/pt-br/toggle-value.tsx
new file mode 100644
index 0000000000..6e8f155f99
--- /dev/null
+++ b/apps/www/src/registry/examples/values/pt-br/toggle-value.tsx
@@ -0,0 +1,19 @@
+/** @jsxRuntime classic */
+/** @jsx jsx */
+import { jsx } from '@platejs/test-utils';
+
+jsx;
+
+export const toggleValue: any = (
+
+ Alternância (Toggle)
+ Crie alternâncias com múltiplos níveis de indentação
+ Alternância nível 1
+ Dentro da alternância nível 1
+
+ Alternância nível 2
+
+ Dentro da alternância nível 2
+ Após alternâncias
+
+);
diff --git a/languine.json b/languine.json
index b5f03842ae..858fa35001 100644
--- a/languine.json
+++ b/languine.json
@@ -1,12 +1,16 @@
{
"language": {
"source": "en",
- "targets": ["cn"]
+ "targets": ["cn", "pt-br"]
},
"content": [
{
"source": "docs/*.mdx",
"target": "docs/*.cn.mdx"
+ },
+ {
+ "source": "docs/*.mdx",
+ "target": "docs/*.pt-br.mdx"
}
]
}
diff --git a/tooling/scripts/translate.mjs b/tooling/scripts/translate.mjs
index 24f2cb483b..7d337db450 100644
--- a/tooling/scripts/translate.mjs
+++ b/tooling/scripts/translate.mjs
@@ -14,6 +14,22 @@ import path from 'node:path';
// Load environment variables
import OpenAI from 'openai';
+// Read languine configuration
+const readConfig = () => {
+ try {
+ const configPath = path.resolve(process.cwd(), 'languine.json');
+ const configContent = fs.readFileSync(configPath, 'utf8');
+ return JSON.parse(configContent);
+ } catch (error) {
+ console.error('Error reading languine.json:', error);
+ process.exit(1);
+ }
+};
+
+const config = readConfig();
+const { content: contentConfig, language } = config;
+const targets = language?.targets || [];
+
const TARGET_DIR = 'docs';
const DAYS = Number(process.argv[2]) || 60; // 默认 60 天
const CUTOFF = Date.now() - DAYS * 24 * 60 * 60 * 1000;
@@ -33,7 +49,7 @@ console.error(`Scanning ${files.length} files… (cutoff = ${DAYS} days)`);
// 2) 查询最后提交时间并过滤
const results = files
- .filter((f) => !f.endsWith('.cn.mdx')) // 过滤掉以.cn.mdx结尾的文件
+ .filter((f) => !targets.some((target) => f.endsWith(`.${target}.mdx`))) // 过滤掉翻译文件
.flatMap((f) => {
const out = spawnSync('git', ['log', '-1', '--format=%ci', '--', f], {
encoding: 'utf8',
@@ -55,32 +71,34 @@ const openai = new OpenAI({
baseURL: 'https://api.deepseek.com',
});
-// Read languine configuration
-const readConfig = () => {
- try {
- const configPath = path.resolve(process.cwd(), 'languine.json');
- const configContent = fs.readFileSync(configPath, 'utf8');
- return JSON.parse(configContent);
- } catch (error) {
- console.error('Error reading languine.json:', error);
- process.exit(1);
- }
-};
-
// Translate content using OpenAI
async function translateContent(content, targetLanguage) {
try {
- const response = await openai.chat.completions.create({
- messages: [
- {
- content: `You are a professional translator. Translate the following MDX content from English to ${targetLanguage}.
+ let systemPrompt = `You are a professional translator. Translate the following MDX content from English to ${targetLanguage}.
Preserve all Markdown formatting, code blocks, and component tags. Do not translate code inside code blocks or component names.
- The content is in .mdx format, which combines Markdown with JSX components.
+ The content is in .mdx format, which combines Markdown with JSX components.`;
+
+ if (targetLanguage === 'cn') {
+ systemPrompt += `
- Do not translate the provider as 提供者, just keep it as provider.
- Do not translate the entry as 条目, just keep it as entry.
- Do not translate the leaf as 叶子, just keep it as leaf.
- Do not translate the element as 元素, just keep it as element.
- `,
+ `;
+ }
+
+ if (targetLanguage === 'pt-br') {
+ systemPrompt += `
+ - Do not translate the provider as Provedor, just keep it as provider.
+ - Do not translate the entry as Entrada, just keep it as entry.
+ - Do not translate the leaf as Folha, just keep it as leaf.
+ `;
+ }
+
+ const response = await openai.chat.completions.create({
+ messages: [
+ {
+ content: systemPrompt,
role: 'system',
},
{
@@ -100,9 +118,6 @@ async function translateContent(content, targetLanguage) {
// Process files for translation
async function processTranslation() {
- const config = readConfig();
- const { content: contentConfig, language } = config;
-
if (!language?.source || !language.targets || !contentConfig) {
console.error('Invalid configuration in languine.json');
process.exit(1);
@@ -113,8 +128,8 @@ async function processTranslation() {
const sourceContent = fs.readFileSync(sourceFile, 'utf8');
for (const targetLanguage of language.targets) {
- // Add .cn.mdx suffix to the source file path
- const targetFile = sourceFile.replace('.mdx', '.cn.mdx');
+ // Add target suffix to the source file path
+ const targetFile = sourceFile.replace('.mdx', `.${targetLanguage}.mdx`);
console.info(
`Translating ${sourceFile} to ${targetLanguage} (${targetFile})`