Skip to content

Commit 2d1e1fb

Browse files
authored
feat: add aliases to heading toolbar (#814)
1 parent 3aece81 commit 2d1e1fb

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

src/bundle/config/w-heading-config.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const wHeading1ItemData: WToolbarListButtonItemData = {
2626
exec: (e) => e.actions.toH1.run(),
2727
isActive: (e) => e.actions.toH1.isActive(),
2828
isEnable: (e) => e.actions.toH1.isEnable(),
29+
aliases: ['h1'],
2930
preview: <HeadingPreview level={1} />,
3031
};
3132
export const wHeading2ItemData: WToolbarListButtonItemData = {
@@ -36,6 +37,7 @@ export const wHeading2ItemData: WToolbarListButtonItemData = {
3637
exec: (e) => e.actions.toH2.run(),
3738
isActive: (e) => e.actions.toH2.isActive(),
3839
isEnable: (e) => e.actions.toH2.isEnable(),
40+
aliases: ['h2'],
3941
preview: <HeadingPreview level={2} />,
4042
};
4143
export const wHeading3ItemData: WToolbarListButtonItemData = {
@@ -46,6 +48,7 @@ export const wHeading3ItemData: WToolbarListButtonItemData = {
4648
exec: (e) => e.actions.toH3.run(),
4749
isActive: (e) => e.actions.toH3.isActive(),
4850
isEnable: (e) => e.actions.toH3.isEnable(),
51+
aliases: ['h3'],
4952
preview: <HeadingPreview level={3} />,
5053
};
5154
export const wHeading4ItemData: WToolbarListButtonItemData = {
@@ -56,6 +59,7 @@ export const wHeading4ItemData: WToolbarListButtonItemData = {
5659
exec: (e) => e.actions.toH4.run(),
5760
isActive: (e) => e.actions.toH4.isActive(),
5861
isEnable: (e) => e.actions.toH4.isEnable(),
62+
aliases: ['h4'],
5963
preview: <HeadingPreview level={4} />,
6064
};
6165
export const wHeading5ItemData: WToolbarListButtonItemData = {
@@ -66,6 +70,7 @@ export const wHeading5ItemData: WToolbarListButtonItemData = {
6670
exec: (e) => e.actions.toH5.run(),
6771
isActive: (e) => e.actions.toH5.isActive(),
6872
isEnable: (e) => e.actions.toH5.isEnable(),
73+
aliases: ['h5'],
6974
preview: <HeadingPreview level={5} />,
7075
};
7176
export const wHeading6ItemData: WToolbarListButtonItemData = {
@@ -76,6 +81,7 @@ export const wHeading6ItemData: WToolbarListButtonItemData = {
7681
exec: (e) => e.actions.toH6.run(),
7782
isActive: (e) => e.actions.toH6.isActive(),
7883
isEnable: (e) => e.actions.toH6.isEnable(),
84+
aliases: ['h6'],
7985
preview: <HeadingPreview level={6} />,
8086
};
8187

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {
2+
wHeading1ItemData,
3+
wHeading2ItemData,
4+
wHeading3ItemData,
5+
wHeading4ItemData,
6+
wHeading5ItemData,
7+
wHeading6ItemData,
8+
} from '../../../bundle/config/w-heading-config';
9+
10+
import {filterActions} from './handler';
11+
12+
describe('Heading aliases', () => {
13+
it('should have correct aliases', () => {
14+
expect(wHeading1ItemData.aliases).toContain('h1');
15+
expect(wHeading2ItemData.aliases).toContain('h2');
16+
expect(wHeading3ItemData.aliases).toContain('h3');
17+
expect(wHeading4ItemData.aliases).toContain('h4');
18+
expect(wHeading5ItemData.aliases).toContain('h5');
19+
expect(wHeading6ItemData.aliases).toContain('h6');
20+
});
21+
22+
it('should filter commands by aliases', () => {
23+
const commands = [
24+
wHeading1ItemData,
25+
wHeading2ItemData,
26+
wHeading3ItemData,
27+
wHeading4ItemData,
28+
wHeading5ItemData,
29+
wHeading6ItemData,
30+
];
31+
32+
for (let i = 1; i <= 6; i++) {
33+
expect(filterActions(commands, `h${i}`)).toHaveLength(1);
34+
expect(filterActions(commands, `h${i}`)[0]).toBe(commands[i - 1]);
35+
}
36+
37+
expect(filterActions(commands, 'h')).toHaveLength(6); // Should match all h1-h6
38+
});
39+
});

src/extensions/behavior/CommandMenu/handler.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,18 @@ export class CommandHandler implements AutocompleteHandler {
252252
}
253253
}
254254

255-
function filterActions(actions: readonly CommandAction[], text: string): CommandAction[] {
256-
return actions.filter(
257-
(action) =>
258-
action.id.toLowerCase().includes(text) ||
259-
(isFunction(action.title) ? action.title() : action.title).toLowerCase().includes(text),
260-
);
255+
export function filterActions(actions: readonly CommandAction[], text: string): CommandAction[] {
256+
return actions.filter((action) => {
257+
const lowerText = text.toLowerCase();
258+
const matchesId = action.id.toLowerCase().includes(lowerText);
259+
const matchesTitle = (isFunction(action.title) ? action.title() : action.title)
260+
.toLowerCase()
261+
.includes(lowerText);
262+
const matchesAliases =
263+
action.aliases?.some((alias) => alias.toLowerCase().includes(lowerText)) ?? false;
264+
265+
return matchesId || matchesTitle || matchesAliases;
266+
});
261267
}
262268

263269
const CHARS_TO_HIDE = 4;

src/toolbar/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export type ToolbarItemData<E> = QAProps & {
2020
hint?: string | (() => string);
2121
hotkey?: HotkeyProps['value'];
2222
preview?: React.ReactNode;
23+
/**
24+
* Alternative IDs that can be used to find this command
25+
*/
26+
aliases?: string[];
2327
/**
2428
* Show hint when _isEnable()_ returns false
2529
*

0 commit comments

Comments
 (0)