diff --git a/packages/super-editor/src/editors/v1/components/toolbar/BulletStyleButtons.vue b/packages/super-editor/src/editors/v1/components/toolbar/BulletStyleButtons.vue new file mode 100644 index 0000000000..e9dc1e5e9b --- /dev/null +++ b/packages/super-editor/src/editors/v1/components/toolbar/BulletStyleButtons.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/packages/super-editor/src/editors/v1/components/toolbar/NumberedStyleButtons.vue b/packages/super-editor/src/editors/v1/components/toolbar/NumberedStyleButtons.vue new file mode 100644 index 0000000000..2281d02914 --- /dev/null +++ b/packages/super-editor/src/editors/v1/components/toolbar/NumberedStyleButtons.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/packages/super-editor/src/editors/v1/components/toolbar/defaultItems.js b/packages/super-editor/src/editors/v1/components/toolbar/defaultItems.js index a16e4b00dc..5ae142f028 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/defaultItems.js +++ b/packages/super-editor/src/editors/v1/components/toolbar/defaultItems.js @@ -4,6 +4,8 @@ import { sanitizeNumber } from './helpers'; import { useToolbarItem } from './use-toolbar-item'; import AIWriter from './AIWriter.vue'; import AlignmentButtons from './AlignmentButtons.vue'; +import BulletStyleButtons from './BulletStyleButtons.vue'; +import NumberedStyleButtons from './NumberedStyleButtons.vue'; import DocumentMode from './DocumentMode.vue'; import LinkedStyle from './LinkedStyle.vue'; import LinkInput from './LinkInput.vue'; @@ -630,30 +632,66 @@ export const makeDefaultItems = ({ // bullet list const bulletedList = useToolbarItem({ - type: 'button', + type: 'dropdown', name: 'list', - command: 'toggleBulletList', + command: 'toggleBulletListStyle', icon: toolbarIcons.bulletList, - active: false, + hasCaret: true, tooltip: toolbarTexts.bulletList, restoreEditorFocus: true, + suppressActiveHighlight: true, attributes: { ariaLabel: 'Bullet list', }, + options: [ + { + type: 'render', + key: 'bullet-style-buttons', + render: () => { + const handleSelect = (style) => { + closeDropdown(bulletedList); + const item = { ...bulletedList, command: 'toggleBulletListStyle' }; + superToolbar.emitCommand({ item, argument: style }); + }; + return h(BulletStyleButtons, { + selectedStyle: bulletedList.selectedValue.value, + onSelect: handleSelect, + }); + }, + }, + ], }); // number list const numberedList = useToolbarItem({ - type: 'button', + type: 'dropdown', name: 'numberedlist', - command: 'toggleOrderedList', + command: 'toggleOrderedListStyle', icon: toolbarIcons.numberedList, - active: false, + hasCaret: true, tooltip: toolbarTexts.numberedList, restoreEditorFocus: true, + suppressActiveHighlight: true, attributes: { ariaLabel: 'Numbered list', }, + options: [ + { + type: 'render', + key: 'numbered-style-buttons', + render: () => { + const handleSelect = (style) => { + closeDropdown(numberedList); + const item = { ...numberedList, command: 'toggleOrderedListStyle' }; + superToolbar.emitCommand({ item, argument: style }); + }; + return h(NumberedStyleButtons, { + selectedStyle: numberedList.selectedValue.value, + onSelect: handleSelect, + }); + }, + }, + ], }); // indent left diff --git a/packages/super-editor/src/editors/v1/components/toolbar/super-toolbar.js b/packages/super-editor/src/editors/v1/components/toolbar/super-toolbar.js index 3457ea05c6..06d2c374ae 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/super-toolbar.js +++ b/packages/super-editor/src/editors/v1/components/toolbar/super-toolbar.js @@ -20,6 +20,7 @@ import { useToolbarItem } from '@components/toolbar/use-toolbar-item'; import { calculateResolvedParagraphProperties } from '@extensions/paragraph/resolvedPropertiesCache.js'; import { parseSizeUnit } from '@core/utilities'; import { findElementBySelector, getParagraphFontFamilyFromProperties } from './helpers/general.js'; +import { markerTextToBulletStyle } from '@helpers/list-numbering-helpers.js'; /** * @typedef {function(CommandItem): void} CommandCallback @@ -622,6 +623,24 @@ export class SuperToolbar extends EventEmitter { if (commandState?.value != null) item.activate({ styleId: commandState.value }); else item.label.value = this.config.texts?.formatText || 'Format text'; }, + list: () => { + if (commandState?.active) { + item.activate(); + item.selectedValue.value = markerTextToBulletStyle(commandState.value); + } else { + item.deactivate(); + item.selectedValue.value = null; + } + }, + numberedlist: () => { + if (commandState?.active) { + item.activate(); + item.selectedValue.value = commandState.value; + } else { + item.deactivate(); + item.selectedValue.value = null; + } + }, default: () => { if (commandState?.active) item.activate(); else item.deactivate(); diff --git a/packages/super-editor/src/editors/v1/components/toolbar/toolbarIcons.js b/packages/super-editor/src/editors/v1/components/toolbar/toolbarIcons.js index 70f62342f4..275a39e5e8 100644 --- a/packages/super-editor/src/editors/v1/components/toolbar/toolbarIcons.js +++ b/packages/super-editor/src/editors/v1/components/toolbar/toolbarIcons.js @@ -2,7 +2,16 @@ import boldIconSvg from '@superdoc/common/icons/bold-solid.svg?raw'; import italicIconSvg from '@superdoc/common/icons/italic-solid.svg?raw'; import underlineIconSvg from '@superdoc/common/icons/underline-solid.svg?raw'; import listIconSvg from '@superdoc/common/icons/list-solid.svg?raw'; +import listCircleIconSvg from '@superdoc/common/icons/list-circle-solid.svg?raw'; +import listSquareIconSvg from '@superdoc/common/icons/list-square-solid.svg?raw'; import listOlIconSvg from '@superdoc/common/icons/list-ol-solid.svg?raw'; +import listDecimalIconSvg from '@superdoc/common/icons/list-decimal-solid.svg?raw'; +import listDecimalParenIconSvg from '@superdoc/common/icons/list-decimal-paren-solid.svg?raw'; +import listUpperRomanIconSvg from '@superdoc/common/icons/list-upper-roman-solid.svg?raw'; +import listLowerRomanIconSvg from '@superdoc/common/icons/list-lower-roman-solid.svg?raw'; +import listUpperAlphaIconSvg from '@superdoc/common/icons/list-upper-alpha-solid.svg?raw'; +import listLowerAlphaIconSvg from '@superdoc/common/icons/list-lower-alpha-solid.svg?raw'; +import listLowerAlphaParenIconSvg from '@superdoc/common/icons/list-lower-alpha-paren-solid.svg?raw'; import imageIconSvg from '@superdoc/common/icons/image-solid.svg?raw'; import linkIconSvg from '@superdoc/common/icons/link-solid.svg?raw'; import alignLeftIconSvg from '@superdoc/common/icons/align-left-solid.svg?raw'; @@ -64,7 +73,17 @@ export const toolbarIcons = { alignCenter: alignCenterIconSvg, alignJustify: alignJustifyIconSvg, bulletList: listIconSvg, + bulletListDisc: listIconSvg, + bulletListCircle: listCircleIconSvg, + bulletListSquare: listSquareIconSvg, numberedList: listOlIconSvg, + numberedListDecimal: listDecimalIconSvg, + numberedListDecimalParen: listDecimalParenIconSvg, + numberedListUpperRoman: listUpperRomanIconSvg, + numberedListLowerRoman: listLowerRomanIconSvg, + numberedListUpperAlpha: listUpperAlphaIconSvg, + numberedListLowerAlpha: listLowerAlphaIconSvg, + numberedListLowerAlphaParen: listLowerAlphaParenIconSvg, indentLeft: outdentIconSvg, indentRight: indentIconSvg, pageBreak: fileHalfDashedIconSvg, diff --git a/packages/super-editor/src/editors/v1/core/commands/toggleList.js b/packages/super-editor/src/editors/v1/core/commands/toggleList.js index 048bd03ec0..4eeccdbb9f 100644 --- a/packages/super-editor/src/editors/v1/core/commands/toggleList.js +++ b/packages/super-editor/src/editors/v1/core/commands/toggleList.js @@ -1,6 +1,6 @@ // @ts-check import { updateNumberingProperties } from './changeListLevel.js'; -import { ListHelpers } from '@helpers/list-numbering-helpers.js'; +import { ListHelpers, markerTextToBulletStyle, numberingInfoToOrderedStyle } from '@helpers/list-numbering-helpers.js'; import { getResolvedParagraphProperties } from '@extensions/paragraph/resolvedPropertiesCache.js'; import { isVisuallyEmptyParagraph } from './removeNumberingProperties.js'; import { Selection, TextSelection } from 'prosemirror-state'; @@ -26,11 +26,28 @@ function getParagraphListKind(node, editor) { return numFmtIsBullet(fmt) ? 'bullet' : 'ordered'; } -function paragraphMatchesToggleListType(node, editor, listType) { +/** + * @param {any} node + * @param {any} editor + * @param {string} listType + * @param {'disc'|'circle'|'square'|null} [bulletStyle] + * @param {import('../../extensions/types/paragraph-commands.js').OrderedListStyle|null} [orderedStyle] + */ +function paragraphMatchesToggleListType(node, editor, listType, bulletStyle, orderedStyle) { const kind = getParagraphListKind(node, editor); if (!kind) return false; - if (listType === 'bulletList') return kind === 'bullet'; - if (listType === 'orderedList') return kind === 'ordered'; + if (listType === 'bulletList') { + if (kind !== 'bullet') return false; + if (!bulletStyle) return true; + const markerText = node.attrs.listRendering?.markerText; + return markerTextToBulletStyle(markerText) === bulletStyle; + } + if (listType === 'orderedList') { + if (kind !== 'ordered') return false; + if (!orderedStyle) return true; + const { numberingType, markerText } = node.attrs.listRendering ?? {}; + return numberingInfoToOrderedStyle(numberingType, markerText) === orderedStyle; + } return false; } @@ -59,14 +76,19 @@ function getPrecedingParagraphForListReuse(doc, from, paragraphsInSelection) { return nb?.type?.name === 'paragraph' ? nb : null; } +/** + * @param {string} listType + * @param {'disc'|'circle'|'square'|null} [bulletStyle] + * @param {import('../../extensions/types/paragraph-commands.js').OrderedListStyle|null} [orderedStyle] + */ export const toggleList = - (listType) => + (listType, bulletStyle, orderedStyle) => ({ editor, state, tr, dispatch }) => { if (listType !== 'orderedList' && listType !== 'bulletList') { return false; } - const predicate = (n) => paragraphMatchesToggleListType(n, editor, listType); + const predicate = (n) => paragraphMatchesToggleListType(n, editor, listType, bulletStyle, orderedStyle); const { selection } = state; const { from, to } = selection; let firstListNode = null; @@ -127,7 +149,7 @@ export const toggleList = if (mode === 'create') { const numId = ListHelpers.getNewListId(editor); - ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor }); + ListHelpers.generateNewListDefinition({ numId: Number(numId), listType, editor, bulletStyle, orderedStyle }); sharedNumberingProperties = { numId: Number(numId), ilvl: 0, diff --git a/packages/super-editor/src/editors/v1/core/helpers/list-numbering-helpers.js b/packages/super-editor/src/editors/v1/core/helpers/list-numbering-helpers.js index 016e536f55..84cddff10a 100644 --- a/packages/super-editor/src/editors/v1/core/helpers/list-numbering-helpers.js +++ b/packages/super-editor/src/editors/v1/core/helpers/list-numbering-helpers.js @@ -5,7 +5,6 @@ import { translator as wNumTranslator } from '@core/super-converter/v3/handlers/ import { baseBulletList, baseOrderedListDef } from './baseListDefinitions'; import { updateNumberingProperties } from '@core/commands/changeListLevel'; import { findParentNode } from './findParentNode.js'; - import { generateNewListDefinition as pureGenerateNewListDefinition, changeNumIdSameAbstract as pureChangeNumIdSameAbstract, @@ -29,6 +28,37 @@ import { mutateNumbering } from '@core/parts/adapters/numbering-mutation'; // Shims will be removed as callers migrate in Phases 1b–1d. // --------------------------------------------------------------------------- +/** + * Maps a bullet marker character (from `listRendering.markerText`) to its named bullet style. + * Returns null for unrecognized markers. + * @param {string|null|undefined} markerText + * @returns {'disc'|'circle'|'square'|null} + */ +export function markerTextToBulletStyle(markerText) { + const map = { '•': 'disc', '◦': 'circle', '▪': 'square' }; + return map[markerText] ?? null; +} + +/** + * Maps `listRendering.numberingType` + last char of `listRendering.markerText` to a named ordered style. + * Returns null for unrecognized combinations. + * @param {import('../../extensions/types/paragraph-commands.js').OrderedListStyle|null|undefined} numberingType + * @param {string|null|undefined} markerText + * @returns {import('../../extensions/types/paragraph-commands.js').OrderedListStyle|null} + */ +export function numberingInfoToOrderedStyle(numberingType, markerText) { + const suffix = markerText?.slice(-1); + /** @type {Record>} */ + const map = { + decimal: { '.': 'decimal', ')': 'decimal-paren' }, + upperRoman: { '.': 'upper-roman' }, + lowerRoman: { '.': 'lower-roman' }, + upperLetter: { '.': 'upper-alpha' }, + lowerLetter: { '.': 'lower-alpha', ')': 'lower-alpha-paren' }, + }; + return map[numberingType]?.[suffix] ?? null; +} + /** * Generate a new list definition for the given list type. * @param {Object} param0 @@ -39,10 +69,23 @@ import { mutateNumbering } from '@core/parts/adapters/numbering-mutation'; * @param {string} [param0.text] * @param {string} [param0.fmt] * @param {string} [param0.markerFontFamily] + * @param {'disc'|'circle'|'square'} [param0.bulletStyle] + * @param {import('../../extensions/types/paragraph-commands.js').OrderedListStyle} [param0.orderedStyle] * @param {import('../Editor').Editor} param0.editor * @returns {Object} The new abstract and num definitions. */ -export const generateNewListDefinition = ({ numId, listType, level, start, text, fmt, editor, markerFontFamily }) => { +export const generateNewListDefinition = ({ + numId, + listType, + level, + start, + text, + fmt, + editor, + markerFontFamily, + bulletStyle, + orderedStyle, +}) => { /** @type {{ abstractDef: any, numDef: any }} */ let resultDefs; @@ -55,6 +98,8 @@ export const generateNewListDefinition = ({ numId, listType, level, start, text, text, fmt, markerFontFamily, + bulletStyle, + orderedStyle, }); resultDefs = { abstractDef: result.abstractDef, numDef: result.numDef }; }); diff --git a/packages/super-editor/src/editors/v1/core/parts/adapters/numbering-transforms.ts b/packages/super-editor/src/editors/v1/core/parts/adapters/numbering-transforms.ts index 84d16a318f..929a138b94 100644 --- a/packages/super-editor/src/editors/v1/core/parts/adapters/numbering-transforms.ts +++ b/packages/super-editor/src/editors/v1/core/parts/adapters/numbering-transforms.ts @@ -12,6 +12,7 @@ */ import { baseBulletList, baseOrderedListDef } from '../../helpers/baseListDefinitions.js'; +import type { OrderedListStyle } from '../../../extensions/types/paragraph-commands.js'; // --------------------------------------------------------------------------- // Types @@ -30,8 +31,26 @@ interface GenerateOptions { text?: string | null; fmt?: string | null; markerFontFamily?: string | null; + bulletStyle?: 'disc' | 'circle' | 'square' | null; + orderedStyle?: OrderedListStyle | null; } +const BULLET_STYLE_CHARS: Record = { + disc: '•', + circle: '◦', + square: '▪', +}; + +const ORDERED_LIST_STYLES: Record = { + decimal: { fmt: 'decimal', text: '%1.' }, + 'decimal-paren': { fmt: 'decimal', text: '%1)' }, + 'upper-roman': { fmt: 'upperRoman', text: '%1.' }, + 'lower-roman': { fmt: 'lowerRoman', text: '%1.' }, + 'upper-alpha': { fmt: 'upperLetter', text: '%1.' }, + 'lower-alpha': { fmt: 'lowerLetter', text: '%1.' }, + 'lower-alpha-paren': { fmt: 'lowerLetter', text: '%1)' }, +}; + interface GenerateResult { numId: number; abstractId: number; @@ -72,7 +91,7 @@ function buildNumDef(numId: number, abstractId: number): any { */ export function generateNewListDefinition(numbering: NumberingModel, options: GenerateOptions): GenerateResult { let { listType } = options; - const { numId, level, start, text, fmt, markerFontFamily } = options; + const { numId, level, start, text, fmt, markerFontFamily, bulletStyle, orderedStyle } = options; if (typeof listType !== 'string') listType = (listType as any).name; const definition = listType === 'orderedList' ? baseOrderedListDef : baseBulletList; @@ -86,6 +105,43 @@ export function generateNewListDefinition(numbering: NumberingModel, options: Ge }), ); + // Override the bullet style for the new list if a bullet style is provided + const shouldOverrideBulletStyle = bulletStyle && listType !== 'orderedList'; + if (shouldOverrideBulletStyle) { + const char = BULLET_STYLE_CHARS[bulletStyle]; + + if (char) { + const lvl0 = newAbstractDef.elements.find((el: any) => el.name === 'w:lvl' && el.attributes['w:ilvl'] === '0'); + + if (lvl0) { + const lvlText = lvl0.elements.find((el: any) => el.name === 'w:lvlText'); + if (lvlText) lvlText.attributes['w:val'] = char; + + // Remove any inherited font so the Unicode char renders in the document's default font + const rPr = lvl0.elements.find((el: any) => el.name === 'w:rPr'); + if (rPr) rPr.elements = rPr.elements.filter((el: any) => el.name !== 'w:rFonts'); + } + } + } + + // Override the ordered list style for the new list if an ordered style is provided + const shouldOverrideOrderedStyle = orderedStyle && listType === 'orderedList'; + if (shouldOverrideOrderedStyle) { + const styleConfig = ORDERED_LIST_STYLES[orderedStyle]; + + if (styleConfig) { + const lvl0 = newAbstractDef.elements.find((el: any) => el.name === 'w:lvl' && el.attributes['w:ilvl'] === '0'); + + if (lvl0) { + const numFmt = lvl0.elements.find((el: any) => el.name === 'w:numFmt'); + if (numFmt) numFmt.attributes['w:val'] = styleConfig.fmt; + + const lvlText = lvl0.elements.find((el: any) => el.name === 'w:lvlText'); + if (lvlText) lvlText.attributes['w:val'] = styleConfig.text; + } + } + } + if (level != null && start != null && text != null && fmt != null) { if (numbering.definitions[numId]) { const abstractId = numbering.definitions[numId]?.elements[0]?.attributes['w:val']; diff --git a/packages/super-editor/src/editors/v1/extensions/paragraph/paragraph.js b/packages/super-editor/src/editors/v1/extensions/paragraph/paragraph.js index 62525501c8..f8e8de976a 100644 --- a/packages/super-editor/src/editors/v1/extensions/paragraph/paragraph.js +++ b/packages/super-editor/src/editors/v1/extensions/paragraph/paragraph.js @@ -173,6 +173,7 @@ export const Paragraph = OxmlNode.create({ listRendering: { keepOnSplit: false, renderDOM: ({ listRendering }) => { + console.log('listRendering', listRendering); return { 'data-marker-type': listRendering?.markerText, 'data-list-level': listRendering?.path ? JSON.stringify(listRendering.path) : null, @@ -323,6 +324,26 @@ export const Paragraph = OxmlNode.create({ return toggleList('bulletList')(params); }, + /** + * Toggle a bullet list with a specific bullet style at the current selection + * @category Command + * @example + * editor.commands.toggleBulletListStyle('disc') + * @note Style can be 'disc' (•), 'circle' (◦), or 'square' (▪) + */ + toggleBulletListStyle: (style) => (params) => { + return toggleList('bulletList', style)(params); + }, + /** + * Toggle an ordered list with a specific numbering style at the current selection + * @category Command + * @example + * editor.commands.toggleOrderedListStyle('upper-roman') + */ + toggleOrderedListStyle: (style) => (params) => { + return toggleList('orderedList', null, style)(params); + }, + /** * Restart numbering for the current list * @category Command diff --git a/packages/super-editor/src/editors/v1/extensions/types/paragraph-commands.ts b/packages/super-editor/src/editors/v1/extensions/types/paragraph-commands.ts index a8f68ec827..c06b7fcc65 100644 --- a/packages/super-editor/src/editors/v1/extensions/types/paragraph-commands.ts +++ b/packages/super-editor/src/editors/v1/extensions/types/paragraph-commands.ts @@ -4,6 +4,15 @@ * @module ParagraphCommands */ +export type OrderedListStyle = + | 'decimal' + | 'decimal-paren' + | 'upper-roman' + | 'lower-roman' + | 'upper-alpha' + | 'lower-alpha' + | 'lower-alpha-paren'; + export interface ParagraphCommands { // ============================================ // LIST COMMANDS @@ -15,6 +24,12 @@ export interface ParagraphCommands { /** Toggle bullet list formatting on the current selection */ toggleBulletList: () => boolean; + /** Toggle a bullet list with a specific style ('disc' | 'circle' | 'square') */ + toggleBulletListStyle: (style: 'disc' | 'circle' | 'square') => boolean; + + /** Toggle an ordered list with a specific numbering style */ + toggleOrderedListStyle: (style: OrderedListStyle) => boolean; + /** Restart numbering for the current list item */ restartNumbering: () => boolean; diff --git a/packages/super-editor/src/headless-toolbar/create-headless-toolbar.test.ts b/packages/super-editor/src/headless-toolbar/create-headless-toolbar.test.ts index 53019dbe9d..f035397218 100644 --- a/packages/super-editor/src/headless-toolbar/create-headless-toolbar.test.ts +++ b/packages/super-editor/src/headless-toolbar/create-headless-toolbar.test.ts @@ -473,10 +473,10 @@ describe('createHeadlessToolbar', () => { }); it('executes bullet-list through the registry direct command path', () => { - const toggleBulletList = vi.fn(() => true); + const toggleBulletListStyle = vi.fn(() => true); const superdoc = createActiveEditorHost({ commands: { - toggleBulletList, + toggleBulletListStyle, }, state: createSelectionState({ empty: true, @@ -495,16 +495,16 @@ describe('createHeadlessToolbar', () => { }); expect(controller.execute?.('bullet-list')).toBe(true); - expect(toggleBulletList).toHaveBeenCalledTimes(1); + expect(toggleBulletListStyle).toHaveBeenCalledTimes(1); controller.destroy(); }); it('executes numbered-list through the registry direct command path', () => { - const toggleOrderedList = vi.fn(() => true); + const toggleOrderedListStyle = vi.fn(() => true); const superdoc = createActiveEditorHost({ commands: { - toggleOrderedList, + toggleOrderedListStyle, }, state: createSelectionState({ empty: true, @@ -523,7 +523,7 @@ describe('createHeadlessToolbar', () => { }); expect(controller.execute?.('numbered-list')).toBe(true); - expect(toggleOrderedList).toHaveBeenCalledTimes(1); + expect(toggleOrderedListStyle).toHaveBeenCalledTimes(1); controller.destroy(); }); diff --git a/packages/super-editor/src/headless-toolbar/helpers/paragraph.ts b/packages/super-editor/src/headless-toolbar/helpers/paragraph.ts index 9327cb71fd..785a7d1433 100644 --- a/packages/super-editor/src/headless-toolbar/helpers/paragraph.ts +++ b/packages/super-editor/src/headless-toolbar/helpers/paragraph.ts @@ -1,4 +1,6 @@ import { isList } from '../../editors/v1/core/commands/list-helpers/is-list.js'; +import { numberingInfoToOrderedStyle } from '../../editors/v1/core/helpers/list-numbering-helpers.js'; +import type { OrderedListStyle } from '../../editors/v1/extensions/types/paragraph-commands.js'; import { twipsToLines } from '../../editors/v1/core/super-converter/helpers.js'; import { getQuickFormatList } from '../../editors/v1/extensions/linked-styles/index.js'; import { getCurrentParagraphParent, getCurrentResolvedParagraphProperties, resolveStateEditor } from './context.js'; @@ -117,10 +119,17 @@ export const createListStateDeriver = ? activeNumberingType === 'bullet' : activeNumberingType != null && activeNumberingType !== 'bullet'; - return { - active: isActive, - disabled: false, - }; + if (numberingType === 'bullet') { + const markerText = isActive ? (paragraphNode?.attrs?.listRendering?.markerText ?? null) : null; + return { active: isActive, disabled: false, value: markerText }; + } + + const activeNumberingFmt = isActive ? (paragraphNode?.attrs?.listRendering?.numberingType ?? null) : null; + const activeMarkerText = isActive ? (paragraphNode?.attrs?.listRendering?.markerText ?? null) : null; + const orderedStyleValue = ( + activeNumberingFmt && activeMarkerText ? numberingInfoToOrderedStyle(activeNumberingFmt, activeMarkerText) : null + ) as OrderedListStyle | null; + return { active: isActive, disabled: false, value: orderedStyleValue }; }; export const createIndentIncreaseExecute = diff --git a/packages/super-editor/src/headless-toolbar/toolbar-registry.test.ts b/packages/super-editor/src/headless-toolbar/toolbar-registry.test.ts index a0a75f3510..391142e6a5 100644 --- a/packages/super-editor/src/headless-toolbar/toolbar-registry.test.ts +++ b/packages/super-editor/src/headless-toolbar/toolbar-registry.test.ts @@ -542,6 +542,7 @@ describe('createToolbarRegistry', () => { expect(state).toEqual({ active: true, disabled: false, + value: null, }); }); @@ -565,6 +566,7 @@ describe('createToolbarRegistry', () => { attrs: { listRendering: { numberingType: 'decimal', + markerText: '1.', }, paragraphProperties: { numberingProperties: { @@ -588,6 +590,7 @@ describe('createToolbarRegistry', () => { expect(state).toEqual({ active: true, disabled: false, + value: 'decimal', }); }); diff --git a/packages/super-editor/src/headless-toolbar/toolbar-registry.ts b/packages/super-editor/src/headless-toolbar/toolbar-registry.ts index a06a49ef71..a6c7943eac 100644 --- a/packages/super-editor/src/headless-toolbar/toolbar-registry.ts +++ b/packages/super-editor/src/headless-toolbar/toolbar-registry.ts @@ -119,12 +119,12 @@ export const createToolbarRegistry = (): Partial diff --git a/shared/common/icons/list-decimal-paren-solid.svg b/shared/common/icons/list-decimal-paren-solid.svg new file mode 100644 index 0000000000..799e9a7438 --- /dev/null +++ b/shared/common/icons/list-decimal-paren-solid.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/shared/common/icons/list-decimal-solid.svg b/shared/common/icons/list-decimal-solid.svg new file mode 100644 index 0000000000..3fd9c615c1 --- /dev/null +++ b/shared/common/icons/list-decimal-solid.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/shared/common/icons/list-lower-alpha-paren-solid.svg b/shared/common/icons/list-lower-alpha-paren-solid.svg new file mode 100644 index 0000000000..cb808f946f --- /dev/null +++ b/shared/common/icons/list-lower-alpha-paren-solid.svg @@ -0,0 +1,6 @@ + + + a) + b) + c) + diff --git a/shared/common/icons/list-lower-alpha-solid.svg b/shared/common/icons/list-lower-alpha-solid.svg new file mode 100644 index 0000000000..a68f8f6037 --- /dev/null +++ b/shared/common/icons/list-lower-alpha-solid.svg @@ -0,0 +1,6 @@ + + + a. + b. + c. + diff --git a/shared/common/icons/list-lower-roman-solid.svg b/shared/common/icons/list-lower-roman-solid.svg new file mode 100644 index 0000000000..8043cb4059 --- /dev/null +++ b/shared/common/icons/list-lower-roman-solid.svg @@ -0,0 +1,6 @@ + + + i. + ii. + iii. + diff --git a/shared/common/icons/list-square-solid.svg b/shared/common/icons/list-square-solid.svg new file mode 100644 index 0000000000..dd35473232 --- /dev/null +++ b/shared/common/icons/list-square-solid.svg @@ -0,0 +1 @@ + diff --git a/shared/common/icons/list-upper-alpha-solid.svg b/shared/common/icons/list-upper-alpha-solid.svg new file mode 100644 index 0000000000..08ddfeeba1 --- /dev/null +++ b/shared/common/icons/list-upper-alpha-solid.svg @@ -0,0 +1,6 @@ + + + A. + B. + C. + diff --git a/shared/common/icons/list-upper-roman-solid.svg b/shared/common/icons/list-upper-roman-solid.svg new file mode 100644 index 0000000000..e74d50cc38 --- /dev/null +++ b/shared/common/icons/list-upper-roman-solid.svg @@ -0,0 +1,6 @@ + + + I. + II. + III. +