From d1680f53a2c905613b04f1506b9b9b5c7997fa2f Mon Sep 17 00:00:00 2001 From: ruslan-amboss Date: Sat, 12 Apr 2025 21:11:19 +0200 Subject: [PATCH] feat(ui): custom ordering for rte fixed toolbar --- .../features/toolbars/fixed/server/index.ts | 7 +++++ .../src/lexical/config/client/sanitize.ts | 29 ++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/richtext-lexical/src/features/toolbars/fixed/server/index.ts b/packages/richtext-lexical/src/features/toolbars/fixed/server/index.ts index c87f33829b7..f8c6a0d1991 100644 --- a/packages/richtext-lexical/src/features/toolbars/fixed/server/index.ts +++ b/packages/richtext-lexical/src/features/toolbars/fixed/server/index.ts @@ -9,6 +9,12 @@ export type FixedToolbarFeatureProps = { * This means that if the editor has a child-editor, and the child-editor is focused, the toolbar will apply to the child-editor, not the parent editor with this feature added. */ applyToFocusedEditor?: boolean + /** + * Custom ordering for toolbar groups + * Key is the group key (e.g. 'format', 'text', 'align') + * Value is the new order number + */ + customGroupOrders?: Record /** * @default false * @@ -26,6 +32,7 @@ export const FixedToolbarFeature = createServerFeature< const sanitizedProps: FixedToolbarFeatureProps = { applyToFocusedEditor: props?.applyToFocusedEditor === undefined ? false : props.applyToFocusedEditor, + customGroupOrders: props?.customGroupOrders, disableIfParentHasFixedToolbar: props?.disableIfParentHasFixedToolbar === undefined ? false diff --git a/packages/richtext-lexical/src/lexical/config/client/sanitize.ts b/packages/richtext-lexical/src/lexical/config/client/sanitize.ts index 294683cd3ba..68e2446d975 100644 --- a/packages/richtext-lexical/src/lexical/config/client/sanitize.ts +++ b/packages/richtext-lexical/src/lexical/config/client/sanitize.ts @@ -31,6 +31,19 @@ export const sanitizeClientFeatures = ( }, } + // Find custom group orders if they exist in any feature + let customGroupOrders: Record = {} + + // First pass to collect custom orders from features + features.forEach((feature) => { + if (feature.key === 'toolbarFixed' && feature.sanitizedClientFeatureProps?.customGroupOrders) { + customGroupOrders = { + ...customGroupOrders, + ...feature.sanitizedClientFeatureProps.customGroupOrders, + } + } + }) + if (!features?.size) { return sanitized } @@ -170,13 +183,21 @@ export const sanitizeClientFeatures = ( return 0 } }) + // Sort sanitized.toolbarFixed.groups by order property sanitized.toolbarFixed.groups.sort((a, b) => { - if (a.order && b.order) { - return a.order - b.order - } else if (a.order) { + const aCustomOrder = customGroupOrders[a.key] + const bCustomOrder = customGroupOrders[b.key] + + // Use custom orders if available, otherwise fall back to default logic + const aOrder = aCustomOrder !== undefined ? aCustomOrder : a.order + const bOrder = bCustomOrder !== undefined ? bCustomOrder : b.order + + if (aOrder && bOrder) { + return aOrder - bOrder + } else if (aOrder) { return -1 - } else if (b.order) { + } else if (bOrder) { return 1 } else { return 0