diff --git a/.changeset/mean-taxis-tie.md b/.changeset/mean-taxis-tie.md
new file mode 100644
index 0000000000..8cd353a316
--- /dev/null
+++ b/.changeset/mean-taxis-tie.md
@@ -0,0 +1,6 @@
+---
+'@udecode/plate-ui': minor
+---
+
+- add support for custom tailwind prefix
+- minify build
diff --git a/apps/www/content/docs/components/avatar.mdx b/apps/www/content/docs/components/avatar.mdx
index 6b799bec6e..c48758ba71 100644
--- a/apps/www/content/docs/components/avatar.mdx
+++ b/apps/www/content/docs/components/avatar.mdx
@@ -2,8 +2,8 @@
title: Avatar
description: An image element with a fallback for representing the user.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/avatar
+links:
+ doc: https://ui.shadcn.com/docs/components/avatar
api: https://www.radix-ui.com/docs/primitives/components/avatar#api-reference
---
diff --git a/apps/www/content/docs/components/button.mdx b/apps/www/content/docs/components/button.mdx
index 744b3688f2..a14dd71119 100644
--- a/apps/www/content/docs/components/button.mdx
+++ b/apps/www/content/docs/components/button.mdx
@@ -2,8 +2,8 @@
title: Button
description: Displays a button or a component that looks like a button.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/button
+links:
+ doc: https://ui.shadcn.com/docs/components/button
---
## Installation
diff --git a/apps/www/content/docs/components/changelog.mdx b/apps/www/content/docs/components/changelog.mdx
index f9db7f80a3..c9f58fd9f9 100644
--- a/apps/www/content/docs/components/changelog.mdx
+++ b/apps/www/content/docs/components/changelog.mdx
@@ -10,6 +10,19 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver
## December 2023 #6
+### December 25 #6.2
+
+- [dialog](https://github.com/udecode/plate/pull/2824/files#diff-5f7205cdd85718b7f26cef1e746ad67d69c83703135a7e3ad1a9a09ca69c38c8)
+- Plate 28, includes a few optimizations: [changes](https://github.com/udecode/plate/pull/2816/files#diff-726cd463a614f1a49228e05a2eb7ea9bc95f2e574423eb4264c6cb95eb0ac792)
+ - `combobox`
+ - `insert-dropdown-menu`
+ - `media-popover`
+ - `mode-dropdown-menu`
+ - `more-dropdown-menu`
+ - `table-dropdown-menu`
+ - `table-element`
+ - `turn-into-dropdown-menu`
+
### December 10 #6.1
- `image-element`: wrap the component with `withHOC(ResizableProvide, ...)`
diff --git a/apps/www/content/docs/components/checkbox.mdx b/apps/www/content/docs/components/checkbox.mdx
index 3e721d4d31..7103236aaa 100644
--- a/apps/www/content/docs/components/checkbox.mdx
+++ b/apps/www/content/docs/components/checkbox.mdx
@@ -2,8 +2,8 @@
title: Checkbox
description: A control that allows the user to toggle between checked and not checked.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/checkbox
+links:
+ doc: https://ui.shadcn.com/docs/components/checkbox
---
## Installation
diff --git a/apps/www/content/docs/components/command.mdx b/apps/www/content/docs/components/command.mdx
index f31d52c624..e625fff298 100644
--- a/apps/www/content/docs/components/command.mdx
+++ b/apps/www/content/docs/components/command.mdx
@@ -2,8 +2,8 @@
title: Command
description: Fast, composable, unstyled command menu for React.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/command
+links:
+ doc: https://ui.shadcn.com/docs/components/command
---
## Installation
diff --git a/apps/www/content/docs/components/components-json.mdx b/apps/www/content/docs/components/components-json.mdx
index a3b0807cbf..d501e41723 100644
--- a/apps/www/content/docs/components/components-json.mdx
+++ b/apps/www/content/docs/components/components-json.mdx
@@ -101,6 +101,18 @@ For more information, see the theming docs.
**This cannot be changed after initialization.** To switch between CSS variables and utility classes, you'll have to delete and re-install your components.
+### tailwind.prefix
+
+The prefix to use for your Tailwind CSS utility classes. Components will be added with this prefix.
+
+```json title="components.json"
+{
+ "tailwind": {
+ "prefix": "tw-"
+ }
+}
+```
+
## rsc
Whether or not to enable support for React Server Components.
diff --git a/apps/www/content/docs/components/dialog.mdx b/apps/www/content/docs/components/dialog.mdx
index 24d641c512..1e2cbef5fd 100644
--- a/apps/www/content/docs/components/dialog.mdx
+++ b/apps/www/content/docs/components/dialog.mdx
@@ -2,8 +2,8 @@
title: Dialog
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/dialog
+links:
+ doc: https://ui.shadcn.com/docs/components/dialog
---
## Installation
diff --git a/apps/www/content/docs/components/dropdown-menu.mdx b/apps/www/content/docs/components/dropdown-menu.mdx
index 867ec75964..a4e10108de 100644
--- a/apps/www/content/docs/components/dropdown-menu.mdx
+++ b/apps/www/content/docs/components/dropdown-menu.mdx
@@ -2,8 +2,8 @@
title: Dropdown Menu
description: Display a menu of options for selection within a dropdown interface.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/dropdown-menu
+links:
+ doc: https://ui.shadcn.com/docs/components/dropdown-menu
api: https://www.radix-ui.com/docs/primitives/components/dropdown-menu#api-reference
---
diff --git a/apps/www/content/docs/components/input.mdx b/apps/www/content/docs/components/input.mdx
index f63119e3f6..181193a715 100644
--- a/apps/www/content/docs/components/input.mdx
+++ b/apps/www/content/docs/components/input.mdx
@@ -2,8 +2,8 @@
title: Input
description: Displays a form input field or a component that looks like an input field.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/input
+links:
+ doc: https://ui.shadcn.com/docs/components/input
---
## Installation
diff --git a/apps/www/content/docs/components/installation.mdx b/apps/www/content/docs/components/installation.mdx
index 9144f49068..b3ff6b2573 100644
--- a/apps/www/content/docs/components/installation.mdx
+++ b/apps/www/content/docs/components/installation.mdx
@@ -32,19 +32,6 @@ description: How to install dependencies and structure your app.
Vite
-
-
- Remix
-
-
- Remix
-
+
+
+ ...
+
+
+ )
+}
+```
+
+**2. Configure `theme.extend.fontFamily` in `tailwind.config.js`**
+
+```js showLineNumbers title=tailwind.config.js {9-11}
+const { fontFamily } = require("tailwindcss/defaultTheme")
+
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ darkMode: ["class"],
+ content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
+ theme: {
+ extend: {
+ fontFamily: {
+ sans: ["var(--font-sans)", ...fontFamily.sans],
+ },
+ },
+ },
+}
+```
+
### Add icons
Add the icons you'll use in `components/icons.tsx`:
diff --git a/apps/www/content/docs/components/installation/remix.mdx b/apps/www/content/docs/components/installation/remix.mdx
deleted file mode 100644
index affda511ee..0000000000
--- a/apps/www/content/docs/components/installation/remix.mdx
+++ /dev/null
@@ -1,124 +0,0 @@
----
-title: Remix
-description: Install and configure Remix.
----
-
-
-
-### Create project
-
-Start by creating a new Remix project using `create-remix`:
-
-```bash
-npx create-remix@latest my-app
-```
-
-### Run the CLI
-
-Run the `plate-ui` init command to setup your project:
-
-```bash
-npx @udecode/plate-ui@latest init
-```
-
-### Configure components.json
-
-You will be asked a few questions to configure `components.json`:
-
-```txt showLineNumbers
-Which style would you like to use? › Default
-Which color would you like to use as base color? › Slate
-Where is your global CSS file? › app/tailwind.css
-Do you want to use CSS variables for colors? › no / yes
-Where is your tailwind.config.js located? › tailwind.config.js
-Configure the import alias for components: › ~/components
-Configure the import alias for utils: › ~/lib/utils
-Are you using React Server Components? › no
-```
-
-### Add icons
-
-Create `app/components/icons.tsx` and add the icons your components are using:
-
-
-
-We use icons from [Lucide](https://lucide.dev). You can use any icon library you want.
-
-### App structure
-
-
-
-**Note**: This app structure is only a suggestion. You can place the files wherever you want.
-
-
-
-- Place the UI components in the `app/components/ui` folder.
-- Your own components can be placed in the `app/components` folder.
-- The `app/lib` folder contains all the utility functions. We have a `utils.ts` where we define the `cn` helper.
-- The `app/tailwind.css` file contains the global CSS.
-
-### Install Tailwind CSS
-
-```bash
-npm add -D tailwindcss@latest autoprefixer@latest
-```
-
-Then we create a `postcss.config.js` file:
-
-```js
-module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- },
-};
-```
-
-And finally we add the following to our `remix.config.js` file:
-
-```js {4-5}
-/** @type {import('@remix-run/dev').AppConfig} */
-module.exports = {
- // ...
- tailwind: true,
- postcss: true,
- // ...
-};
-```
-
-### Add `tailwind.css` to your app
-
-In your `app/root.tsx` file, import the `tailwind.css` file:
-
-```js {1, 4}
-import styles from './tailwind.css';
-
-export const links: LinksFunction = () => [
- { rel: 'stylesheet', href: styles },
- ...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : []),
-];
-```
-
-### That's it
-
-You can now start adding components to your project.
-
-```bash
-npx @udecode/plate-ui@latest add button
-```
-
-The command above will add the `Button` component to your project. You can then import it like this:
-
-```tsx {1,6} showLineNumbers
-import { Button } from '@/components/ui/button';
-
-export default function Home() {
- return (
-
- Click me
-
- );
-}
-```
-
-
diff --git a/apps/www/content/docs/components/installation/vite.mdx b/apps/www/content/docs/components/installation/vite.mdx
index 916b2e0a0f..69545461f8 100644
--- a/apps/www/content/docs/components/installation/vite.mdx
+++ b/apps/www/content/docs/components/installation/vite.mdx
@@ -25,18 +25,26 @@ npx tailwindcss init -p
### Edit tsconfig.json
-Add the code below to the compilerOptions of your tsconfig.json so your app can resolve paths without error
-
-```bash
-"baseUrl": ".",
-"paths": {
- "@/*": ["./src/*"]
+Add the following code to the `tsconfig.json` file to resolve paths:
+
+```bash {4-9} showLineNumbers
+{
+ "compilerOptions": {
+ // ...
+ "baseUrl": ".",
+ "paths": {
+ "@/*": [
+ "./src/*"
+ ]
+ }
+ // ...
+ }
}
```
### Update vite.config.ts
-Add the code below to the vite.config.ts so your app can resolve paths without error
+Add the following code to the vite.config.ts so your app can resolve paths without error
```bash
# (so you can import "path" without error)
diff --git a/apps/www/content/docs/components/popover.mdx b/apps/www/content/docs/components/popover.mdx
index 50eedf71a2..2a0cf90f1c 100644
--- a/apps/www/content/docs/components/popover.mdx
+++ b/apps/www/content/docs/components/popover.mdx
@@ -2,8 +2,8 @@
title: Popover
description: Displays rich content in a portal, triggered by a button.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/popover
+links:
+ doc: https://ui.shadcn.com/docs/components/popover
api: https://www.radix-ui.com/docs/primitives/components/popover#api-reference
---
diff --git a/apps/www/content/docs/components/separator.mdx b/apps/www/content/docs/components/separator.mdx
index fda00d2cc1..8be21eeb95 100644
--- a/apps/www/content/docs/components/separator.mdx
+++ b/apps/www/content/docs/components/separator.mdx
@@ -2,8 +2,8 @@
title: Separator
description: Visually or semantically separates content.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/separator
+links:
+ doc: https://ui.shadcn.com/docs/components/separator
api: https://www.radix-ui.com/docs/primitives/components/separator#api-reference
---
diff --git a/apps/www/content/docs/components/toggle.mdx b/apps/www/content/docs/components/toggle.mdx
index 75475661b7..705373600c 100644
--- a/apps/www/content/docs/components/toggle.mdx
+++ b/apps/www/content/docs/components/toggle.mdx
@@ -2,8 +2,8 @@
title: Toggle
description: Enable or disable a specific feature or functionality with a toggle switch.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/toggle
+links:
+ doc: https://ui.shadcn.com/docs/components/toggle
api: https://www.radix-ui.com/docs/primitives/components/toggle#api-reference
---
diff --git a/apps/www/content/docs/components/toolbar.mdx b/apps/www/content/docs/components/toolbar.mdx
index b58da6c2b3..dbfdf317d0 100644
--- a/apps/www/content/docs/components/toolbar.mdx
+++ b/apps/www/content/docs/components/toolbar.mdx
@@ -2,8 +2,8 @@
title: Toolbar
description: A container for grouping a set of controls, such as buttons, toggle groups or dropdown menus.
component: true
-radix:
- link: https://www.radix-ui.com/docs/primitives/components/toolbar
+links:
+ doc: https://www.radix-ui.com/docs/primitives/components/toolbar
api: https://www.radix-ui.com/docs/primitives/components/toolbar#api-reference
---
diff --git a/apps/www/content/docs/components/tooltip.mdx b/apps/www/content/docs/components/tooltip.mdx
index 81c31ceab9..6e96b7bde8 100644
--- a/apps/www/content/docs/components/tooltip.mdx
+++ b/apps/www/content/docs/components/tooltip.mdx
@@ -2,8 +2,8 @@
title: Tooltip
description: A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.
component: true
-radix:
- shadcn: https://ui.shadcn.com/docs/components/tooltip
+links:
+ doc: https://ui.shadcn.com/docs/components/tooltip
api: https://www.radix-ui.com/docs/primitives/components/tooltip#api-reference
---
diff --git a/apps/www/contentlayer.config.js b/apps/www/contentlayer.config.js
index 7f55ab36a2..146fbf2dcc 100644
--- a/apps/www/contentlayer.config.js
+++ b/apps/www/contentlayer.config.js
@@ -27,13 +27,10 @@ const computedFields = {
},
};
-const RadixProperties = defineNestedType(() => ({
- name: 'RadixProperties',
+const LinksProperties = defineNestedType(() => ({
+ name: 'LinksProperties',
fields: {
- shadcn: {
- type: 'string',
- },
- link: {
+ doc: {
type: 'string',
},
api: {
@@ -71,9 +68,9 @@ export const Doc = defineDocumentType(() => ({
type: 'boolean',
default: true,
},
- radix: {
+ links: {
type: 'nested',
- of: RadixProperties,
+ of: LinksProperties,
},
docs: {
type: 'list',
diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs
index 90b971e385..5a757c2191 100644
--- a/apps/www/next.config.mjs
+++ b/apps/www/next.config.mjs
@@ -31,7 +31,6 @@ const nextConfig = async (phase, { defaultConfig }) => {
// Enable experimental features.
experimental: {
esmExternals: false,
- serverActions: true,
// Specify external packages that should be excluded from server-side rendering.
// https://beta.nextjs.org/docs/api-reference/next-config#servercomponentsexternalpackages
serverComponentsExternalPackages: ['@prisma/client'],
diff --git a/apps/www/package.json b/apps/www/package.json
index 55584671ad..198e30f70a 100644
--- a/apps/www/package.json
+++ b/apps/www/package.json
@@ -17,7 +17,7 @@
"typecheck": "yarn prebuild && tsc --noEmit"
},
"dependencies": {
- "@faker-js/faker": "^7.6.0",
+ "@faker-js/faker": "^8.2.0",
"@radix-ui/colors": "1.0.0",
"@radix-ui/react-accessible-icon": "^1.0.3",
"@radix-ui/react-accordion": "^1.1.2",
@@ -38,7 +38,7 @@
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-radio-group": "^1.1.3",
"@radix-ui/react-scroll-area": "^1.0.4",
- "@radix-ui/react-select": "^1.2.2",
+ "@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
@@ -110,14 +110,17 @@
"cmdk": "^0.2.0",
"contentlayer": "0.3.4",
"date-fns": "^2.30.0",
+ "embla-carousel-autoplay": "8.0.0-rc15",
+ "embla-carousel-react": "8.0.0-rc15",
"framer-motion": "^10.16.4",
- "jotai": "^2.2.2",
+ "geist": "^1.1.0",
+ "jotai": "^2.6.0",
"lodash.template": "^4.5.0",
- "lucide-react": "^0.277.0",
- "next": "13.4.19",
+ "lucide-react": "^0.288.0",
+ "next": "14.0.4",
"next-contentlayer": "0.3.4",
"next-themes": "^0.2.1",
- "next-usequerystate": "1.8.0-beta.13",
+ "next-usequerystate": "^1.13.2",
"prism-react-renderer": "^1.3.5",
"react": "^18.2.0",
"react-dnd": "16.0.1",
@@ -125,6 +128,7 @@
"react-dom": "^18.2.0",
"react-lite-youtube-embed": "^2.3.52",
"react-modal-sheet": "2.0.0",
+ "react-resizable-panels": "^0.0.55",
"react-syntax-highlighter": "^15.5.0",
"react-tweet": "^3.1.0",
"react-wrap-balancer": "^1.0.0",
@@ -134,7 +138,8 @@
"slate-hyperscript": "0.77.0",
"slate-react": "0.99.0",
"slate-test-utils": "1.3.2",
- "tailwind-merge": "^1.13.2",
+ "sonner": "^1.2.3",
+ "tailwind-merge": "^2.2.0",
"unist-builder": "3.0.0",
"unist-util-visit": "^4.1.2"
},
@@ -159,8 +164,8 @@
"remark-gfm": "^3.0.1",
"rimraf": "^5.0.1",
"shiki": "^0.12.1",
- "tailwindcss": "^3.3.2",
- "tailwindcss-animate": "^1.0.6",
+ "tailwindcss": "^3.4.0",
+ "tailwindcss-animate": "^1.0.7",
"ts-node": "^10.9.2",
"typescript": "5.1.6",
"vaul": "^0.6.0"
diff --git a/apps/www/public/registry/styles/default/combobox.json b/apps/www/public/registry/styles/default/combobox.json
index 66fe0f9c87..360793ad1e 100644
--- a/apps/www/public/registry/styles/default/combobox.json
+++ b/apps/www/public/registry/styles/default/combobox.json
@@ -9,7 +9,7 @@
"files": [
{
"name": "combobox.tsx",
- "content": "'use client';\n\nimport React, { useEffect } from 'react';\nimport * as Popover from '@radix-ui/react-popover';\nimport {\n comboboxActions,\n ComboboxContentItemProps,\n ComboboxContentProps,\n ComboboxProps,\n Data,\n NoData,\n TComboboxItem,\n useActiveComboboxStore,\n useComboboxContent,\n useComboboxContentState,\n useComboboxControls,\n useComboboxItem,\n useComboboxSelectors,\n} from '@udecode/plate-combobox';\nimport { useEditorState, useEventEditorSelectors } from '@udecode/plate-common';\nimport { createVirtualRef } from '@udecode/plate-floating';\n\nimport { cn } from '@/lib/utils';\n\nexport function ComboboxItem({\n combobox,\n index,\n item,\n onRenderItem,\n}: ComboboxContentItemProps) {\n const { props } = useComboboxItem({ item, index, combobox, onRenderItem });\n\n return (\n
\n );\n}\n\nexport function ComboboxContent(\n props: ComboboxContentProps\n) {\n const {\n component: Component,\n items,\n portalElement,\n combobox,\n onRenderItem,\n } = props;\n\n const editor = useEditorState();\n\n const filteredItems =\n useComboboxSelectors.filteredItems() as TComboboxItem[];\n const activeComboboxStore = useActiveComboboxStore()!;\n\n const state = useComboboxContentState({ items, combobox });\n const { menuProps, targetRange } = useComboboxContent(state);\n\n return (\n \n \n\n \n event.preventDefault()}\n >\n {Component ? Component({ store: activeComboboxStore }) : null}\n\n {filteredItems.map((item, index) => (\n \n ))}\n \n \n \n );\n}\n\n/**\n * Register the combobox id, trigger, onSelectItem\n * Renders the combobox if active.\n */\nexport function Combobox({\n id,\n trigger,\n searchPattern,\n onSelectItem,\n controlled,\n maxSuggestions,\n filter,\n sort,\n disabled: _disabled,\n ...props\n}: ComboboxProps) {\n const storeItems = useComboboxSelectors.items();\n const disabled =\n _disabled ?? (storeItems.length === 0 && !props.items?.length);\n\n const focusedEditorId = useEventEditorSelectors.focus?.();\n const combobox = useComboboxControls();\n const activeId = useComboboxSelectors.activeId();\n const editor = useEditorState();\n\n useEffect(() => {\n comboboxActions.setComboboxById({\n id,\n trigger,\n searchPattern,\n controlled,\n onSelectItem,\n maxSuggestions,\n filter,\n sort,\n });\n }, [\n id,\n trigger,\n searchPattern,\n controlled,\n onSelectItem,\n maxSuggestions,\n filter,\n sort,\n ]);\n\n if (\n !combobox ||\n !editor.selection ||\n focusedEditorId !== editor.id ||\n activeId !== id ||\n disabled\n ) {\n return null;\n }\n\n return ;\n}\n"
+ "content": "'use client';\n\nimport React, { useEffect } from 'react';\nimport * as Popover from '@radix-ui/react-popover';\nimport {\n comboboxActions,\n ComboboxContentItemProps,\n ComboboxContentProps,\n ComboboxProps,\n Data,\n NoData,\n TComboboxItem,\n useActiveComboboxStore,\n useComboboxContent,\n useComboboxContentState,\n useComboboxControls,\n useComboboxItem,\n useComboboxSelectors,\n} from '@udecode/plate-combobox';\nimport {\n useEditorRef,\n useEditorSelector,\n useEventEditorSelectors,\n usePlateSelectors,\n} from '@udecode/plate-common';\nimport { createVirtualRef } from '@udecode/plate-floating';\n\nimport { cn } from '@/lib/utils';\n\nexport function ComboboxItem({\n combobox,\n index,\n item,\n onRenderItem,\n}: ComboboxContentItemProps) {\n const { props } = useComboboxItem({ item, index, combobox, onRenderItem });\n\n return (\n
\n );\n}\n\nexport function ComboboxContent(\n props: ComboboxContentProps\n) {\n const {\n component: Component,\n items,\n portalElement,\n combobox,\n onRenderItem,\n } = props;\n\n const editor = useEditorRef();\n\n const filteredItems =\n useComboboxSelectors.filteredItems() as TComboboxItem[];\n const activeComboboxStore = useActiveComboboxStore()!;\n\n const state = useComboboxContentState({ items, combobox });\n const { menuProps, targetRange } = useComboboxContent(state);\n\n return (\n \n \n\n \n event.preventDefault()}\n >\n {Component ? Component({ store: activeComboboxStore }) : null}\n\n {filteredItems.map((item, index) => (\n \n ))}\n \n \n \n );\n}\n\n/**\n * Register the combobox id, trigger, onSelectItem\n * Renders the combobox if active.\n */\nexport function Combobox({\n id,\n trigger,\n searchPattern,\n onSelectItem,\n controlled,\n maxSuggestions,\n filter,\n sort,\n disabled: _disabled,\n ...props\n}: ComboboxProps) {\n const storeItems = useComboboxSelectors.items();\n const disabled =\n _disabled ?? (storeItems.length === 0 && !props.items?.length);\n\n const focusedEditorId = useEventEditorSelectors.focus?.();\n const combobox = useComboboxControls();\n const activeId = useComboboxSelectors.activeId();\n const selectionDefined = useEditorSelector(\n (editor) => !!editor.selection,\n []\n );\n const editorId = usePlateSelectors().id();\n\n useEffect(() => {\n comboboxActions.setComboboxById({\n id,\n trigger,\n searchPattern,\n controlled,\n onSelectItem,\n maxSuggestions,\n filter,\n sort,\n });\n }, [\n id,\n trigger,\n searchPattern,\n controlled,\n onSelectItem,\n maxSuggestions,\n filter,\n sort,\n ]);\n\n if (\n !combobox ||\n !selectionDefined ||\n focusedEditorId !== editorId ||\n activeId !== id ||\n disabled\n ) {\n return null;\n }\n\n return ;\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/command.json b/apps/www/public/registry/styles/default/command.json
index 082761055b..af872f9005 100644
--- a/apps/www/public/registry/styles/default/command.json
+++ b/apps/www/public/registry/styles/default/command.json
@@ -9,7 +9,7 @@
"files": [
{
"name": "command.tsx",
- "content": "'use client';\n\nimport * as React from 'react';\nimport { DialogProps } from '@radix-ui/react-dialog';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '@/lib/utils';\nimport { Icons } from '@/components/icons';\n\nimport { Dialog, DialogContent } from './dialog';\n\nconst Command = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nCommand.displayName = CommandPrimitive.displayName;\n\ninterface CommandDialogProps extends DialogProps {}\n\nfunction CommandDialog({ children, ...props }: CommandDialogProps) {\n return (\n \n \n \n {children}\n \n \n \n );\n}\n\nconst CommandInput = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n
\n));\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.HTMLAttributes) {\n return (\n \n );\n}\nCommandShortcut.displayName = 'CommandShortcut';\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n"
+ "content": "'use client';\n\nimport * as React from 'react';\nimport { type DialogProps } from '@radix-ui/react-dialog';\nimport { Command as CommandPrimitive } from 'cmdk';\n\nimport { cn } from '@/lib/utils';\nimport { Icons } from '@/components/icons';\n\nimport { Dialog, DialogContent } from './dialog';\n\nconst Command = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nCommand.displayName = CommandPrimitive.displayName;\n\ninterface CommandDialogProps extends DialogProps {}\n\nfunction CommandDialog({ children, ...props }: CommandDialogProps) {\n return (\n \n \n \n {children}\n \n \n \n );\n}\n\nconst CommandInput = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n \n \n
\n));\n\nCommandInput.displayName = CommandPrimitive.Input.displayName;\n\nconst CommandList = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandList.displayName = CommandPrimitive.List.displayName;\n\nconst CommandEmpty = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => (\n \n));\n\nCommandEmpty.displayName = CommandPrimitive.Empty.displayName;\n\nconst CommandGroup = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandGroup.displayName = CommandPrimitive.Group.displayName;\n\nconst CommandSeparator = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nCommandSeparator.displayName = CommandPrimitive.Separator.displayName;\n\nconst CommandItem = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\n\nCommandItem.displayName = CommandPrimitive.Item.displayName;\n\nfunction CommandShortcut({\n className,\n ...props\n}: React.HTMLAttributes) {\n return (\n \n );\n}\nCommandShortcut.displayName = 'CommandShortcut';\n\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n};\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/dialog.json b/apps/www/public/registry/styles/default/dialog.json
index c260b1a238..4c46626808 100644
--- a/apps/www/public/registry/styles/default/dialog.json
+++ b/apps/www/public/registry/styles/default/dialog.json
@@ -7,7 +7,7 @@
"files": [
{
"name": "dialog.tsx",
- "content": "'use client';\n\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\n\nimport { cn } from '@/lib/utils';\nimport { Icons } from '@/components/icons';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = ({\n className,\n ...props\n}: DialogPrimitive.DialogPortalProps) => (\n \n);\nDialogPortal.displayName = DialogPrimitive.Portal.displayName;\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n \n \n {children}\n \n \n Close \n \n \n \n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n
\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n
\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n"
+ "content": "'use client';\n\nimport * as React from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\n\nimport { cn } from '@/lib/utils';\nimport { Icons } from '@/components/icons';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\nconst DialogContent = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, children, ...props }, ref) => (\n \n \n \n {children}\n \n \n Close \n \n \n \n));\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n
\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({\n className,\n ...props\n}: React.HTMLAttributes) => (\n
\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = React.forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>(({ className, ...props }, ref) => (\n \n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/insert-dropdown-menu.json b/apps/www/public/registry/styles/default/insert-dropdown-menu.json
index 7c78b9cdac..7fc7582545 100644
--- a/apps/www/public/registry/styles/default/insert-dropdown-menu.json
+++ b/apps/www/public/registry/styles/default/insert-dropdown-menu.json
@@ -12,7 +12,7 @@
"files": [
{
"name": "insert-dropdown-menu.tsx",
- "content": "'use client';\n\nimport React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';\nimport {\n focusEditor,\n insertEmptyElement,\n useEditorState,\n} from '@udecode/plate-common';\nimport { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading';\nimport { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n label: 'Basic blocks',\n items: [\n {\n value: ELEMENT_PARAGRAPH,\n label: 'Paragraph',\n description: 'Paragraph',\n icon: Icons.paragraph,\n },\n {\n value: ELEMENT_H1,\n label: 'Heading 1',\n description: 'Heading 1',\n icon: Icons.h1,\n },\n {\n value: ELEMENT_H2,\n label: 'Heading 2',\n description: 'Heading 2',\n icon: Icons.h2,\n },\n {\n value: ELEMENT_H3,\n label: 'Heading 3',\n description: 'Heading 3',\n icon: Icons.h3,\n },\n {\n value: ELEMENT_BLOCKQUOTE,\n label: 'Quote',\n description: 'Quote (⌘+⇧+.)',\n icon: Icons.blockquote,\n },\n // {\n // value: ELEMENT_TABLE,\n // label: 'Table',\n // description: 'Table',\n // icon: Icons.table,\n // },\n // {\n // value: 'ul',\n // label: 'Bulleted list',\n // description: 'Bulleted list',\n // icon: Icons.ul,\n // },\n // {\n // value: 'ol',\n // label: 'Numbered list',\n // description: 'Numbered list',\n // icon: Icons.ol,\n // },\n // {\n // value: ELEMENT_HR,\n // label: 'Divider',\n // description: 'Divider (---)',\n // icon: Icons.hr,\n // },\n ],\n },\n // {\n // label: 'Media',\n // items: [\n // {\n // value: ELEMENT_CODE_BLOCK,\n // label: 'Code',\n // description: 'Code (```)',\n // icon: Icons.codeblock,\n // },\n // {\n // value: ELEMENT_IMAGE,\n // label: 'Image',\n // description: 'Image',\n // icon: Icons.image,\n // },\n // {\n // value: ELEMENT_MEDIA_EMBED,\n // label: 'Embed',\n // description: 'Embed',\n // icon: Icons.embed,\n // },\n // {\n // value: ELEMENT_EXCALIDRAW,\n // label: 'Excalidraw',\n // description: 'Excalidraw',\n // icon: Icons.excalidraw,\n // },\n // ],\n // },\n // {\n // label: 'Inline',\n // items: [\n // {\n // value: ELEMENT_LINK,\n // label: 'Link',\n // description: 'Link',\n // icon: Icons.link,\n // },\n // ],\n // },\n];\n\nexport function InsertDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorState();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {items.map(({ items: nestedItems, label }, index) => (\n \n {index !== 0 && }\n\n {label} \n {nestedItems.map(\n ({ value: type, label: itemLabel, icon: Icon }) => (\n {\n switch (type) {\n // case ELEMENT_CODE_BLOCK: {\n // insertEmptyCodeBlock(editor);\n //\n // break;\n // }\n // case ELEMENT_IMAGE: {\n // await insertMedia(editor, { type: ELEMENT_IMAGE });\n //\n // break;\n // }\n // case ELEMENT_MEDIA_EMBED: {\n // await insertMedia(editor, {\n // type: ELEMENT_MEDIA_EMBED,\n // });\n //\n // break;\n // }\n // case 'ul':\n // case 'ol': {\n // insertEmptyElement(editor, ELEMENT_PARAGRAPH, {\n // select: true,\n // nextBlock: true,\n // });\n //\n // if (settingsStore.get.checkedId(KEY_LIST_STYLE_TYPE)) {\n // toggleIndentList(editor, {\n // listStyleType: type === 'ul' ? 'disc' : 'decimal',\n // });\n // } else if (settingsStore.get.checkedId('list')) {\n // toggleList(editor, { type });\n // }\n //\n // break;\n // }\n // case ELEMENT_TABLE: {\n // insertTable(editor);\n //\n // break;\n // }\n // case ELEMENT_LINK: {\n // triggerFloatingLink(editor, { focused: true });\n //\n // break;\n // }\n default: {\n insertEmptyElement(editor, type, {\n select: true,\n nextBlock: true,\n });\n }\n }\n\n focusEditor(editor);\n }}\n >\n \n {itemLabel}\n \n )\n )}\n \n ))}\n \n \n );\n}\n"
+ "content": "'use client';\n\nimport React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';\nimport {\n focusEditor,\n insertEmptyElement,\n useEditorRef,\n} from '@udecode/plate-common';\nimport { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading';\nimport { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n label: 'Basic blocks',\n items: [\n {\n value: ELEMENT_PARAGRAPH,\n label: 'Paragraph',\n description: 'Paragraph',\n icon: Icons.paragraph,\n },\n {\n value: ELEMENT_H1,\n label: 'Heading 1',\n description: 'Heading 1',\n icon: Icons.h1,\n },\n {\n value: ELEMENT_H2,\n label: 'Heading 2',\n description: 'Heading 2',\n icon: Icons.h2,\n },\n {\n value: ELEMENT_H3,\n label: 'Heading 3',\n description: 'Heading 3',\n icon: Icons.h3,\n },\n {\n value: ELEMENT_BLOCKQUOTE,\n label: 'Quote',\n description: 'Quote (⌘+⇧+.)',\n icon: Icons.blockquote,\n },\n // {\n // value: ELEMENT_TABLE,\n // label: 'Table',\n // description: 'Table',\n // icon: Icons.table,\n // },\n // {\n // value: 'ul',\n // label: 'Bulleted list',\n // description: 'Bulleted list',\n // icon: Icons.ul,\n // },\n // {\n // value: 'ol',\n // label: 'Numbered list',\n // description: 'Numbered list',\n // icon: Icons.ol,\n // },\n // {\n // value: ELEMENT_HR,\n // label: 'Divider',\n // description: 'Divider (---)',\n // icon: Icons.hr,\n // },\n ],\n },\n // {\n // label: 'Media',\n // items: [\n // {\n // value: ELEMENT_CODE_BLOCK,\n // label: 'Code',\n // description: 'Code (```)',\n // icon: Icons.codeblock,\n // },\n // {\n // value: ELEMENT_IMAGE,\n // label: 'Image',\n // description: 'Image',\n // icon: Icons.image,\n // },\n // {\n // value: ELEMENT_MEDIA_EMBED,\n // label: 'Embed',\n // description: 'Embed',\n // icon: Icons.embed,\n // },\n // {\n // value: ELEMENT_EXCALIDRAW,\n // label: 'Excalidraw',\n // description: 'Excalidraw',\n // icon: Icons.excalidraw,\n // },\n // ],\n // },\n // {\n // label: 'Inline',\n // items: [\n // {\n // value: ELEMENT_LINK,\n // label: 'Link',\n // description: 'Link',\n // icon: Icons.link,\n // },\n // ],\n // },\n];\n\nexport function InsertDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {items.map(({ items: nestedItems, label }, index) => (\n \n {index !== 0 && }\n\n {label} \n {nestedItems.map(\n ({ value: type, label: itemLabel, icon: Icon }) => (\n {\n switch (type) {\n // case ELEMENT_CODE_BLOCK: {\n // insertEmptyCodeBlock(editor);\n //\n // break;\n // }\n // case ELEMENT_IMAGE: {\n // await insertMedia(editor, { type: ELEMENT_IMAGE });\n //\n // break;\n // }\n // case ELEMENT_MEDIA_EMBED: {\n // await insertMedia(editor, {\n // type: ELEMENT_MEDIA_EMBED,\n // });\n //\n // break;\n // }\n // case 'ul':\n // case 'ol': {\n // insertEmptyElement(editor, ELEMENT_PARAGRAPH, {\n // select: true,\n // nextBlock: true,\n // });\n //\n // if (settingsStore.get.checkedId(KEY_LIST_STYLE_TYPE)) {\n // toggleIndentList(editor, {\n // listStyleType: type === 'ul' ? 'disc' : 'decimal',\n // });\n // } else if (settingsStore.get.checkedId('list')) {\n // toggleList(editor, { type });\n // }\n //\n // break;\n // }\n // case ELEMENT_TABLE: {\n // insertTable(editor);\n //\n // break;\n // }\n // case ELEMENT_LINK: {\n // triggerFloatingLink(editor, { focused: true });\n //\n // break;\n // }\n default: {\n insertEmptyElement(editor, type, {\n select: true,\n nextBlock: true,\n });\n }\n }\n\n focusEditor(editor);\n }}\n >\n \n {itemLabel}\n \n )\n )}\n \n ))}\n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/media-popover.json b/apps/www/public/registry/styles/default/media-popover.json
index f44b36a19c..c2d66d945e 100644
--- a/apps/www/public/registry/styles/default/media-popover.json
+++ b/apps/www/public/registry/styles/default/media-popover.json
@@ -12,7 +12,7 @@
"files": [
{
"name": "media-popover.tsx",
- "content": "import React, { useEffect } from 'react';\nimport {\n isCollapsed,\n useEditorState,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common';\nimport {\n floatingMediaActions,\n FloatingMedia as FloatingMediaPrimitive,\n useFloatingMediaSelectors,\n} from '@udecode/plate-media';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Icons } from '@/components/icons';\n\nimport { Button, buttonVariants } from './button';\nimport { inputVariants } from './input';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport interface MediaPopoverProps {\n pluginKey?: string;\n children: React.ReactNode;\n}\n\nexport function MediaPopover({ pluginKey, children }: MediaPopoverProps) {\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorState();\n\n const isOpen = !readOnly && selected && isCollapsed(editor.selection);\n const isEditing = useFloatingMediaSelectors().isEditing();\n\n useEffect(() => {\n if (!isOpen && isEditing) {\n floatingMediaActions.isEditing(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n if (readOnly) return <>{children}>;\n\n return (\n \n {children} \n\n e.preventDefault()}\n >\n {isEditing ? (\n \n ) : (\n \n \n Edit link\n \n\n \n\n \n \n \n
\n )}\n \n \n );\n}\n"
+ "content": "import React, { useEffect } from 'react';\nimport {\n isSelectionExpanded,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common';\nimport {\n floatingMediaActions,\n FloatingMedia as FloatingMediaPrimitive,\n useFloatingMediaSelectors,\n} from '@udecode/plate-media';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { Icons } from '@/components/icons';\n\nimport { Button, buttonVariants } from './button';\nimport { inputVariants } from './input';\nimport { Popover, PopoverAnchor, PopoverContent } from './popover';\nimport { Separator } from './separator';\n\nexport interface MediaPopoverProps {\n pluginKey?: string;\n children: React.ReactNode;\n}\n\nexport function MediaPopover({ pluginKey, children }: MediaPopoverProps) {\n const readOnly = useReadOnly();\n const selected = useSelected();\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n const isOpen = !readOnly && selected && selectionCollapsed;\n const isEditing = useFloatingMediaSelectors().isEditing();\n\n useEffect(() => {\n if (!isOpen && isEditing) {\n floatingMediaActions.isEditing(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isOpen]);\n\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n if (readOnly) return <>{children}>;\n\n return (\n \n {children} \n\n e.preventDefault()}\n >\n {isEditing ? (\n \n ) : (\n \n \n Edit link\n \n\n \n\n \n \n \n
\n )}\n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/mode-dropdown-menu.json b/apps/www/public/registry/styles/default/mode-dropdown-menu.json
index 4529b82da9..482eba98d1 100644
--- a/apps/www/public/registry/styles/default/mode-dropdown-menu.json
+++ b/apps/www/public/registry/styles/default/mode-dropdown-menu.json
@@ -8,7 +8,7 @@
"files": [
{
"name": "mode-dropdown-menu.tsx",
- "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport {\n focusEditor,\n useEditorReadOnly,\n useEditorState,\n usePlateStore,\n} from '@udecode/plate-common';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function ModeDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorState();\n const setReadOnly = usePlateStore().set.readOnly();\n const readOnly = useEditorReadOnly();\n const openState = useOpenState();\n\n let value = 'editing';\n if (readOnly) value = 'viewing';\n\n const item: any = {\n editing: (\n <>\n \n Editing \n >\n ),\n viewing: (\n <>\n \n Viewing \n >\n ),\n };\n\n return (\n \n \n \n {item[value]}\n \n \n\n \n {\n if (newValue !== 'viewing') {\n setReadOnly(false);\n }\n\n if (newValue === 'viewing') {\n setReadOnly(true);\n return;\n }\n\n if (newValue === 'editing') {\n focusEditor(editor);\n return;\n }\n }}\n >\n \n {item.editing}\n \n\n \n {item.viewing}\n \n \n \n \n );\n}\n"
+ "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport {\n focusEditor,\n useEditorReadOnly,\n useEditorRef,\n usePlateStore,\n} from '@udecode/plate-common';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function ModeDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const setReadOnly = usePlateStore().set.readOnly();\n const readOnly = useEditorReadOnly();\n const openState = useOpenState();\n\n let value = 'editing';\n if (readOnly) value = 'viewing';\n\n const item: any = {\n editing: (\n <>\n \n Editing \n >\n ),\n viewing: (\n <>\n \n Viewing \n >\n ),\n };\n\n return (\n \n \n \n {item[value]}\n \n \n\n \n {\n if (newValue !== 'viewing') {\n setReadOnly(false);\n }\n\n if (newValue === 'viewing') {\n setReadOnly(true);\n return;\n }\n\n if (newValue === 'editing') {\n focusEditor(editor);\n return;\n }\n }}\n >\n \n {item.editing}\n \n\n \n {item.viewing}\n \n \n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/more-dropdown-menu.json b/apps/www/public/registry/styles/default/more-dropdown-menu.json
index 370b6e375d..71a6c439d1 100644
--- a/apps/www/public/registry/styles/default/more-dropdown-menu.json
+++ b/apps/www/public/registry/styles/default/more-dropdown-menu.json
@@ -10,7 +10,7 @@
"files": [
{
"name": "more-dropdown-menu.tsx",
- "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { MARK_SUBSCRIPT, MARK_SUPERSCRIPT } from '@udecode/plate-basic-marks';\nimport { focusEditor, toggleMark, useEditorState } from '@udecode/plate-common';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function MoreDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorState();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {\n toggleMark(editor, {\n key: MARK_SUBSCRIPT,\n clear: MARK_SUPERSCRIPT,\n });\n focusEditor(editor);\n }}\n >\n \n Superscript\n {/* (⌘+,) */}\n \n {\n toggleMark(editor, {\n key: MARK_SUPERSCRIPT,\n clear: MARK_SUBSCRIPT,\n });\n focusEditor(editor);\n }}\n >\n \n Subscript\n {/* (⌘+.) */}\n \n \n \n );\n}\n"
+ "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { MARK_SUBSCRIPT, MARK_SUPERSCRIPT } from '@udecode/plate-basic-marks';\nimport { focusEditor, toggleMark, useEditorRef } from '@udecode/plate-common';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function MoreDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n {\n toggleMark(editor, {\n key: MARK_SUBSCRIPT,\n clear: MARK_SUPERSCRIPT,\n });\n focusEditor(editor);\n }}\n >\n \n Superscript\n {/* (⌘+,) */}\n \n {\n toggleMark(editor, {\n key: MARK_SUPERSCRIPT,\n clear: MARK_SUBSCRIPT,\n });\n focusEditor(editor);\n }}\n >\n \n Subscript\n {/* (⌘+.) */}\n \n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/table-dropdown-menu.json b/apps/www/public/registry/styles/default/table-dropdown-menu.json
index 6563232559..040ede15a7 100644
--- a/apps/www/public/registry/styles/default/table-dropdown-menu.json
+++ b/apps/www/public/registry/styles/default/table-dropdown-menu.json
@@ -10,7 +10,7 @@
"files": [
{
"name": "table-dropdown-menu.tsx",
- "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { focusEditor, someNode, useEditorState } from '@udecode/plate-common';\nimport {\n deleteColumn,\n deleteRow,\n deleteTable,\n ELEMENT_TABLE,\n insertTable,\n insertTableColumn,\n insertTableRow,\n} from '@udecode/plate-table';\n\nimport { Icons, iconVariants } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorState();\n\n const tableSelected = someNode(editor, {\n match: { type: ELEMENT_TABLE },\n });\n\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n \n \n \n Table \n \n \n {\n insertTable(editor);\n focusEditor(editor);\n }}\n >\n \n Insert table\n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n\n \n \n \n Column \n \n \n {\n insertTableColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row \n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n \n \n \n );\n}\n"
+ "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport {\n focusEditor,\n someNode,\n useEditorRef,\n useEditorSelector,\n} from '@udecode/plate-common';\nimport {\n deleteColumn,\n deleteRow,\n deleteTable,\n ELEMENT_TABLE,\n insertTable,\n insertTableColumn,\n insertTableRow,\n} from '@udecode/plate-table';\n\nimport { Icons, iconVariants } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nexport function TableDropdownMenu(props: DropdownMenuProps) {\n const tableSelected = useEditorSelector(\n (editor) => someNode(editor, { match: { type: ELEMENT_TABLE } }),\n []\n );\n\n const editor = useEditorRef();\n const openState = useOpenState();\n\n return (\n \n \n \n \n \n \n\n \n \n \n \n Table \n \n \n {\n insertTable(editor);\n focusEditor(editor);\n }}\n >\n \n Insert table\n \n {\n deleteTable(editor);\n focusEditor(editor);\n }}\n >\n \n Delete table\n \n \n \n\n \n \n \n Column \n \n \n {\n insertTableColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Insert column after\n \n {\n deleteColumn(editor);\n focusEditor(editor);\n }}\n >\n \n Delete column\n \n \n \n\n \n \n \n Row \n \n \n {\n insertTableRow(editor);\n focusEditor(editor);\n }}\n >\n \n Insert row after\n \n {\n deleteRow(editor);\n focusEditor(editor);\n }}\n >\n \n Delete row\n \n \n \n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/table-element.json b/apps/www/public/registry/styles/default/table-element.json
index a119ed97df..13b6a7ebd6 100644
--- a/apps/www/public/registry/styles/default/table-element.json
+++ b/apps/www/public/registry/styles/default/table-element.json
@@ -9,7 +9,7 @@
"files": [
{
"name": "table-element.tsx",
- "content": "import React, { forwardRef } from 'react';\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { PopoverAnchor, PopoverContentProps } from '@radix-ui/react-popover';\nimport {\n isCollapsed,\n PlateElement,\n PlateElementProps,\n useEditorState,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common';\nimport {\n mergeTableCells,\n TTableElement,\n unmergeTableCells,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { cn } from '@/lib/utils';\nimport { Icons, iconVariants } from '@/components/icons';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\nimport { Separator } from './separator';\n\nconst TableBordersDropdownMenuContent = forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasOuterBorders,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n Bottom Border
\n \n \n \n Top Border
\n \n \n \n Left Border
\n \n \n \n Right Border
\n \n\n \n\n \n \n No Border
\n \n \n \n Outside Borders
\n \n \n );\n});\nTableBordersDropdownMenuContent.displayName = 'TableBordersDropdownMenuContent';\n\nconst TableFloatingToolbar = React.forwardRef<\n React.ElementRef,\n PopoverContentProps\n>(({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorState();\n\n const collapsed = !readOnly && selected && isCollapsed(editor.selection);\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n Borders\n \n \n\n \n \n \n \n\n \n \n Delete\n \n >\n );\n\n return (\n \n {children} \n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n});\nTableFloatingToolbar.displayName = 'TableFloatingToolbar';\n\nconst TableElement = React.forwardRef<\n React.ElementRef,\n PlateElementProps\n>(({ className, children, ...props }, ref) => {\n const { colSizes, isSelectingCell, minColumnWidth, marginLeft } =\n useTableElementState();\n const { props: tableProps, colGroupProps } = useTableElement();\n\n return (\n \n \n
\n \n \n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children} \n
\n \n
\n \n );\n});\nTableElement.displayName = 'TableElement';\n\nexport { TableElement, TableFloatingToolbar, TableBordersDropdownMenuContent };\n"
+ "content": "import React, { forwardRef } from 'react';\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';\nimport { PopoverAnchor, PopoverContentProps } from '@radix-ui/react-popover';\nimport {\n isSelectionExpanded,\n PlateElement,\n PlateElementProps,\n useEditorRef,\n useEditorSelector,\n useElement,\n useRemoveNodeButton,\n} from '@udecode/plate-common';\nimport {\n mergeTableCells,\n TTableElement,\n unmergeTableCells,\n useTableBordersDropdownMenuContentState,\n useTableElement,\n useTableElementState,\n useTableMergeState,\n} from '@udecode/plate-table';\nimport { useReadOnly, useSelected } from 'slate-react';\n\nimport { cn } from '@/lib/utils';\nimport { Icons, iconVariants } from '@/components/icons';\n\nimport { Button } from './button';\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n} from './dropdown-menu';\nimport { Popover, PopoverContent, popoverVariants } from './popover';\nimport { Separator } from './separator';\n\nconst TableBordersDropdownMenuContent = forwardRef<\n React.ElementRef,\n React.ComponentPropsWithoutRef\n>((props, ref) => {\n const {\n getOnSelectTableBorder,\n hasOuterBorders,\n hasBottomBorder,\n hasLeftBorder,\n hasNoBorders,\n hasRightBorder,\n hasTopBorder,\n } = useTableBordersDropdownMenuContentState();\n\n return (\n \n \n \n Bottom Border
\n \n \n \n Top Border
\n \n \n \n Left Border
\n \n \n \n Right Border
\n \n\n \n\n \n \n No Border
\n \n \n \n Outside Borders
\n \n \n );\n});\nTableBordersDropdownMenuContent.displayName = 'TableBordersDropdownMenuContent';\n\nconst TableFloatingToolbar = React.forwardRef<\n React.ElementRef,\n PopoverContentProps\n>(({ children, ...props }, ref) => {\n const element = useElement();\n const { props: buttonProps } = useRemoveNodeButton({ element });\n\n const selectionCollapsed = useEditorSelector(\n (editor) => !isSelectionExpanded(editor),\n []\n );\n\n const readOnly = useReadOnly();\n const selected = useSelected();\n const editor = useEditorRef();\n\n const collapsed = !readOnly && selected && selectionCollapsed;\n const open = !readOnly && selected;\n\n const { canMerge, canUnmerge } = useTableMergeState();\n\n const mergeContent = canMerge && (\n mergeTableCells(editor)}\n >\n \n Merge\n \n );\n\n const unmergeButton = canUnmerge && (\n unmergeTableCells(editor)}\n >\n \n Unmerge\n \n );\n\n const bordersContent = collapsed && (\n <>\n \n \n \n \n Borders\n \n \n\n \n \n \n \n\n \n \n Delete\n \n >\n );\n\n return (\n \n {children} \n {(canMerge || canUnmerge || collapsed) && (\n e.preventDefault()}\n {...props}\n >\n {unmergeButton}\n {mergeContent}\n {bordersContent}\n \n )}\n \n );\n});\nTableFloatingToolbar.displayName = 'TableFloatingToolbar';\n\nconst TableElement = React.forwardRef<\n React.ElementRef,\n PlateElementProps\n>(({ className, children, ...props }, ref) => {\n const { colSizes, isSelectingCell, minColumnWidth, marginLeft } =\n useTableElementState();\n const { props: tableProps, colGroupProps } = useTableElement();\n\n return (\n \n \n
\n \n \n {colSizes.map((width, index) => (\n \n ))}\n \n\n {children} \n
\n \n
\n \n );\n});\nTableElement.displayName = 'TableElement';\n\nexport { TableElement, TableFloatingToolbar, TableBordersDropdownMenuContent };\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/public/registry/styles/default/turn-into-dropdown-menu.json b/apps/www/public/registry/styles/default/turn-into-dropdown-menu.json
index 8a274b7346..82d4faeedc 100644
--- a/apps/www/public/registry/styles/default/turn-into-dropdown-menu.json
+++ b/apps/www/public/registry/styles/default/turn-into-dropdown-menu.json
@@ -12,7 +12,7 @@
"files": [
{
"name": "turn-into-dropdown-menu.tsx",
- "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';\nimport {\n collapseSelection,\n findNode,\n focusEditor,\n isBlock,\n isCollapsed,\n TElement,\n toggleNodeType,\n useEditorState,\n} from '@udecode/plate-common';\nimport { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading';\nimport { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n value: ELEMENT_PARAGRAPH,\n label: 'Paragraph',\n description: 'Paragraph',\n icon: Icons.paragraph,\n },\n {\n value: ELEMENT_H1,\n label: 'Heading 1',\n description: 'Heading 1',\n icon: Icons.h1,\n },\n {\n value: ELEMENT_H2,\n label: 'Heading 2',\n description: 'Heading 2',\n icon: Icons.h2,\n },\n {\n value: ELEMENT_H3,\n label: 'Heading 3',\n description: 'Heading 3',\n icon: Icons.h3,\n },\n {\n value: ELEMENT_BLOCKQUOTE,\n label: 'Quote',\n description: 'Quote (⌘+⇧+.)',\n icon: Icons.blockquote,\n },\n // {\n // value: 'ul',\n // label: 'Bulleted list',\n // description: 'Bulleted list',\n // icon: Icons.ul,\n // },\n // {\n // value: 'ol',\n // label: 'Numbered list',\n // description: 'Numbered list',\n // icon: Icons.ol,\n // },\n];\n\nconst defaultItem = items.find((item) => item.value === ELEMENT_PARAGRAPH)!;\n\nexport function TurnIntoDropdownMenu(props: DropdownMenuProps) {\n const editor = useEditorState();\n const openState = useOpenState();\n\n let value: string = ELEMENT_PARAGRAPH;\n if (isCollapsed(editor?.selection)) {\n const entry = findNode(editor!, {\n match: (n) => isBlock(editor, n),\n });\n if (entry) {\n value =\n items.find((item) => item.value === entry[0].type)?.value ??\n ELEMENT_PARAGRAPH;\n }\n }\n\n const selectedItem =\n items.find((item) => item.value === value) ?? defaultItem;\n const { icon: SelectedItemIcon, label: selectedItemLabel } = selectedItem;\n\n return (\n \n \n \n \n {selectedItemLabel} \n \n \n\n \n Turn into \n\n {\n // if (type === 'ul' || type === 'ol') {\n // if (settingsStore.get.checkedId(KEY_LIST_STYLE_TYPE)) {\n // toggleIndentList(editor, {\n // listStyleType: type === 'ul' ? 'disc' : 'decimal',\n // });\n // } else if (settingsStore.get.checkedId('list')) {\n // toggleList(editor, { type });\n // }\n // } else {\n // unwrapList(editor);\n toggleNodeType(editor, { activeType: type });\n // }\n\n collapseSelection(editor);\n focusEditor(editor);\n }}\n >\n {items.map(({ value: itemValue, label, icon: Icon }) => (\n \n \n {label}\n \n ))}\n \n \n \n );\n}\n"
+ "content": "import React from 'react';\nimport { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';\nimport { ELEMENT_BLOCKQUOTE } from '@udecode/plate-block-quote';\nimport {\n collapseSelection,\n findNode,\n focusEditor,\n isBlock,\n isCollapsed,\n TElement,\n toggleNodeType,\n useEditorRef,\n useEditorSelector,\n} from '@udecode/plate-common';\nimport { ELEMENT_H1, ELEMENT_H2, ELEMENT_H3 } from '@udecode/plate-heading';\nimport { ELEMENT_PARAGRAPH } from '@udecode/plate-paragraph';\n\nimport { Icons } from '@/components/icons';\n\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuLabel,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n useOpenState,\n} from './dropdown-menu';\nimport { ToolbarButton } from './toolbar';\n\nconst items = [\n {\n value: ELEMENT_PARAGRAPH,\n label: 'Paragraph',\n description: 'Paragraph',\n icon: Icons.paragraph,\n },\n {\n value: ELEMENT_H1,\n label: 'Heading 1',\n description: 'Heading 1',\n icon: Icons.h1,\n },\n {\n value: ELEMENT_H2,\n label: 'Heading 2',\n description: 'Heading 2',\n icon: Icons.h2,\n },\n {\n value: ELEMENT_H3,\n label: 'Heading 3',\n description: 'Heading 3',\n icon: Icons.h3,\n },\n {\n value: ELEMENT_BLOCKQUOTE,\n label: 'Quote',\n description: 'Quote (⌘+⇧+.)',\n icon: Icons.blockquote,\n },\n // {\n // value: 'ul',\n // label: 'Bulleted list',\n // description: 'Bulleted list',\n // icon: Icons.ul,\n // },\n // {\n // value: 'ol',\n // label: 'Numbered list',\n // description: 'Numbered list',\n // icon: Icons.ol,\n // },\n];\n\nconst defaultItem = items.find((item) => item.value === ELEMENT_PARAGRAPH)!;\n\nexport function TurnIntoDropdownMenu(props: DropdownMenuProps) {\n const value: string = useEditorSelector((editor) => {\n if (isCollapsed(editor.selection)) {\n const entry = findNode(editor, {\n match: (n) => isBlock(editor, n),\n });\n\n if (entry) {\n return (\n items.find((item) => item.value === entry[0].type)?.value ??\n ELEMENT_PARAGRAPH\n );\n }\n }\n\n return ELEMENT_PARAGRAPH;\n }, []);\n\n const editor = useEditorRef();\n const openState = useOpenState();\n\n const selectedItem =\n items.find((item) => item.value === value) ?? defaultItem;\n const { icon: SelectedItemIcon, label: selectedItemLabel } = selectedItem;\n\n return (\n \n \n \n \n {selectedItemLabel} \n \n \n\n \n Turn into \n\n {\n // if (type === 'ul' || type === 'ol') {\n // if (settingsStore.get.checkedId(KEY_LIST_STYLE_TYPE)) {\n // toggleIndentList(editor, {\n // listStyleType: type === 'ul' ? 'disc' : 'decimal',\n // });\n // } else if (settingsStore.get.checkedId('list')) {\n // toggleList(editor, { type });\n // }\n // } else {\n // unwrapList(editor);\n toggleNodeType(editor, { activeType: type });\n // }\n\n collapseSelection(editor);\n focusEditor(editor);\n }}\n >\n {items.map(({ value: itemValue, label, icon: Icon }) => (\n \n \n {label}\n \n ))}\n \n \n \n );\n}\n"
}
],
"type": "components:plate-ui"
diff --git a/apps/www/src/app/_components/installation-code.tsx b/apps/www/src/app/_components/installation-code.tsx
index 86c43a7225..d6466b29b2 100644
--- a/apps/www/src/app/_components/installation-code.tsx
+++ b/apps/www/src/app/_components/installation-code.tsx
@@ -39,6 +39,7 @@ export function InstallationCode({
__npmCommand__: code,
__pnpmCommand__: code.replaceAll('npm install', 'pnpm add'),
__yarnCommand__: code.replaceAll('npm install', 'yarn add'),
+ __bunCommand__: code.replaceAll('npm install', 'yarn add'),
}}
className={cn('absolute right-4 top-4')}
/>
diff --git a/apps/www/src/app/announcement-button.tsx b/apps/www/src/app/announcement-button.tsx
index 883e1d3f95..194312b9ab 100644
--- a/apps/www/src/app/announcement-button.tsx
+++ b/apps/www/src/app/announcement-button.tsx
@@ -1,7 +1,7 @@
'use client';
import * as React from 'react';
-import { ChevronRight } from 'lucide-react';
+import { ArrowRightIcon } from 'lucide-react';
import { settingsStore } from '@/components/context/settings-store';
import { Button } from '@/registry/default/plate-ui/button';
@@ -19,7 +19,7 @@ export function AnnouncementButton() {
>
🎉 Introducing
the interactive builder.
-
+
);
}
diff --git a/apps/www/src/app/docs/[[...slug]]/page.tsx b/apps/www/src/app/docs/[[...slug]]/page.tsx
index 822ed92a57..0bc97fc7b4 100644
--- a/apps/www/src/app/docs/[[...slug]]/page.tsx
+++ b/apps/www/src/app/docs/[[...slug]]/page.tsx
@@ -3,7 +3,7 @@ import '@/styles/mdx.css';
import Link from 'next/link';
import { notFound } from 'next/navigation';
import { allDocs } from 'contentlayer/generated';
-import { ChevronRight } from 'lucide-react';
+import { ChevronRight, ExternalLinkIcon } from 'lucide-react';
import Balancer from 'react-wrap-balancer';
import { docToPackage } from '@/config/doc-to-package';
@@ -14,7 +14,6 @@ import { absoluteUrl, cn } from '@/lib/utils';
import { PackageInfoType } from '@/hooks/use-package-info';
import { badgeVariants } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
-import { Icons } from '@/components/icons';
import { Mdx } from '@/components/mdx-components';
import { DocsPager } from '@/components/pager';
import { DashboardTableOfContents } from '@/components/toc';
@@ -32,7 +31,7 @@ async function getDocFromParams({ params }: DocPageProps) {
const doc = allDocs.find((_doc) => _doc.slugAsParams === slug);
if (!doc) {
- null;
+ return null;
}
return doc;
@@ -141,37 +140,28 @@ export default async function DocPage({ params }: DocPageProps) {
)}
- {doc.radix || doc.docs ? (
+ {doc.links ? (
- {doc.radix?.shadcn && (
+ {doc.links?.doc && (
- shadcn/ui
+ Docs
+
)}
- {doc.radix?.link && (
+ {doc.links?.api && (
-
- Radix UI
-
- )}
- {doc.radix?.api && (
-
API Reference
+
)}
{doc.docs?.map((item) => (
diff --git a/apps/www/src/app/docs/layout.tsx b/apps/www/src/app/docs/layout.tsx
index 5566dbbc16..4a8bdad89e 100644
--- a/apps/www/src/app/docs/layout.tsx
+++ b/apps/www/src/app/docs/layout.tsx
@@ -11,7 +11,7 @@ export default function DocsLayout({ children }: DocsLayoutProps) {