Advanced list styling capabilities including list styles, start index, and reversed numbering for enhanced list customization.
Main plugin that adds list styling capabilities to CKEditor 5.
/**
* The list properties feature.
* This is a "glue" plugin that loads the list properties editing feature and list properties UI feature.
*/
class ListProperties extends Plugin {
/** @inheritDoc */
static get requires(): readonly [typeof ListPropertiesEditing, typeof ListPropertiesUI];
/** @inheritDoc */
static get pluginName(): "ListProperties";
/** @inheritDoc */
static override get isOfficialPlugin(): true;
}Core editing functionality for list properties including style, start, and reversed attributes.
/**
* The editing part of the list properties feature. It handles creating, editing and removing list properties.
*/
class ListPropertiesEditing extends Plugin {
/** @inheritDoc */
static get pluginName(): "ListPropertiesEditing";
/** @inheritDoc */
static get requires(): readonly [typeof ListEditing, typeof ListPropertiesUtils];
}Attribute Strategy Type:
interface AttributeStrategy {
scope: 'list' | 'listItem';
attributeName: string;
defaultValue: unknown;
viewConsumables: Array<string>;
modelToViewConverter: (attributeValue: unknown, conversionApi: DowncastConversionApi) => void;
upcastConverter: (element: ViewElement, conversionApi: UpcastConversionApi) => boolean;
}User interface for list properties including dropdowns and forms.
/**
* The list properties UI feature. It introduces the list properties dropdown to the toolbar.
*/
class ListPropertiesUI extends Plugin {
/** @inheritDoc */
static get pluginName(): "ListPropertiesUI";
/** @inheritDoc */
static get requires(): readonly [typeof ListPropertiesEditing];
}Utility functions for list properties operations.
/**
* A set of helpers related to list properties.
*/
class ListPropertiesUtils extends Plugin {
/** @inheritDoc */
static get pluginName(): "ListPropertiesUtils";
/**
* Gets the normalized configuration for the given list type.
*/
getNormalizedConfig(listType: ListPropertiesStyleListType): NormalizedListPropertiesConfig;
/**
* Gets all supported style types for the given list type.
*/
getAllSupportedStyleTypes(listType: ListPropertiesStyleListType): Array<string>;
}Changes list style (disc, decimal, etc.).
/**
* The list style command. It changes the `listStyle` attribute of the selected list items.
*/
class ListStyleCommand extends Command {
/**
* @inheritDoc
*/
constructor(editor: Editor);
/**
* Executes the list style command.
* @param options Command execution options
* @param options.type The list style type to apply
*/
execute(options?: { type?: string }): void;
/**
* The current value of the command.
*/
value: string | null;
/**
* Checks whether the command can be enabled in the current context.
*/
isEnabled: boolean;
}Sets start index for numbered lists.
/**
* The list start command. It changes the `listStart` attribute of the selected list items.
*/
class ListStartCommand extends Command {
/**
* @inheritDoc
*/
constructor(editor: Editor);
/**
* Executes the list start command.
* @param options Command execution options
* @param options.startIndex The starting index value
*/
execute(options?: { startIndex?: number }): void;
/**
* The current value of the command.
*/
value: number | null;
/**
* Checks whether the command can be enabled in the current context.
*/
isEnabled: boolean;
}Toggles reversed numbering for numbered lists.
/**
* The list reversed command. It changes the `listReversed` attribute of the selected list items.
*/
class ListReversedCommand extends Command {
/**
* @inheritDoc
*/
constructor(editor: Editor);
/**
* Executes the list reversed command.
* @param options Command execution options
* @param options.reversed Whether the list should be reversed
*/
execute(options?: { reversed?: boolean }): void;
/**
* The current value of the command.
*/
value: boolean | null;
/**
* Checks whether the command can be enabled in the current context.
*/
isEnabled: boolean;
}Main UI view for list properties form.
/**
* The list properties view.
*/
class ListPropertiesView extends View {
/**
* Creates an instance of the list properties view.
*/
constructor(locale: Locale, options: ListPropertiesViewOptions);
/**
* Focuses the view.
*/
focus(): void;
}Events:
interface ListPropertiesViewListStartEvent {
readonly name: 'listStart';
readonly args: [data: { startIndex: number }];
}
interface ListPropertiesViewListReversedEvent {
readonly name: 'listReversed';
readonly args: [data: { reversed: boolean }];
}View component for style selection.
/**
* The styles view for list properties.
*/
class StylesView extends View {
/**
* Creates an instance of the styles view.
*/
constructor(locale: Locale, styleDefinitions: Array<ListStyleDefinition>);
}interface ListPropertiesConfig {
styles?: boolean | ListPropertiesStyleConfig | ArrayOrItem<ListPropertiesStyleListType>;
startIndex?: boolean;
reversed?: boolean;
}
interface ListPropertiesStyleConfig {
listTypes?: ArrayOrItem<ListPropertiesStyleListType>;
useAttribute?: boolean;
listStyleTypes?: ListStyleTypesConfig;
}
interface ListStyleTypesConfig {
numbered?: Array<NumberedListStyleType>;
bulleted?: Array<BulletedListStyleType>;
}
interface NormalizedListPropertiesConfig {
styles: {
[key in ListPropertiesStyleListType]: Array<string>;
};
startIndex: boolean;
reversed: boolean;
useAttribute: boolean;
}type ListPropertiesStyleListType = 'numbered' | 'bulleted';
type NumberedListStyleType =
| 'decimal'
| 'decimal-leading-zero'
| 'lower-roman'
| 'upper-roman'
| 'lower-latin'
| 'upper-latin';
type BulletedListStyleType =
| 'disc'
| 'circle'
| 'square';import { ClassicEditor } from "@ckeditor/ckeditor5-editor-classic";
import { List, ListProperties } from "@ckeditor/ckeditor5-list";
ClassicEditor
.create(document.querySelector('#editor'), {
plugins: [List, ListProperties],
toolbar: ['numberedList', 'bulletedList'],
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
}
})
.then(editor => {
console.log('Editor with list properties initialized');
});ClassicEditor
.create(document.querySelector('#editor'), {
plugins: [List, ListProperties],
list: {
properties: {
styles: {
listTypes: ['numbered', 'bulleted'],
useAttribute: false,
listStyleTypes: {
numbered: ['decimal', 'lower-roman', 'upper-roman'],
bulleted: ['disc', 'circle']
}
},
startIndex: true,
reversed: true
}
}
});// Get list property commands
const styleCommand = editor.commands.get('listStyle');
const startCommand = editor.commands.get('listStart');
const reversedCommand = editor.commands.get('listReversed');
// Apply different styles
styleCommand.execute({ type: 'lower-roman' });
startCommand.execute({ startIndex: 5 });
reversedCommand.execute({ reversed: true });
// Check current values
console.log('Current style:', styleCommand.value);
console.log('Current start index:', startCommand.value);
console.log('Is reversed:', reversedCommand.value);import { Plugin } from 'ckeditor5/src/core';
class CustomListStylePlugin extends Plugin {
static get requires() {
return [ListProperties];
}
init() {
const editor = this.editor;
// Add custom toolbar button for specific style
editor.ui.componentFactory.add('romanList', locale => {
const button = new ButtonView(locale);
const command = editor.commands.get('listStyle');
button.set({
label: 'Roman Numerals',
icon: romanIcon,
tooltip: true,
isToggleable: true
});
button.bind('isOn').to(command, 'value', value => value === 'lower-roman');
button.bind('isEnabled').to(command, 'isEnabled');
button.on('execute', () => {
if (command.value === 'lower-roman') {
command.execute({ type: null }); // Remove style
} else {
command.execute({ type: 'lower-roman' });
}
});
return button;
});
}
}// Listen to property command changes
const commands = ['listStyle', 'listStart', 'listReversed'];
commands.forEach(commandName => {
const command = editor.commands.get(commandName);
command.on('change:value', () => {
console.log(`${commandName} changed to:`, command.value);
});
command.on('change:isEnabled', () => {
console.log(`${commandName} enabled:`, command.isEnabled);
});
});
// Update UI based on property states
function updatePropertyUI() {
const styleCommand = editor.commands.get('listStyle');
const startCommand = editor.commands.get('listStart');
const reversedCommand = editor.commands.get('listReversed');
// Update style dropdown
const styleDropdown = document.querySelector('#style-dropdown');
styleDropdown.value = styleCommand.value || '';
styleDropdown.disabled = !styleCommand.isEnabled;
// Update start index input
const startInput = document.querySelector('#start-input');
startInput.value = startCommand.value || 1;
startInput.disabled = !startCommand.isEnabled;
// Update reversed checkbox
const reversedCheckbox = document.querySelector('#reversed-checkbox');
reversedCheckbox.checked = reversedCommand.value || false;
reversedCheckbox.disabled = !reversedCommand.isEnabled;
}
editor.model.document.selection.on('change', updatePropertyUI);