Add in-app help, formula reference outlines, underline and auto-closing
- Help dialog (?, F1, Datei > Hilfe): user topics, all shortcuts and the formula functions with one search over everything. Topics and shortcuts are plain data in data/help.ts; the function list comes from codeReference.ts so new built-ins appear by themselves. - While a formula is edited, the grid outlines each referenced cell/range in the colour of its position in the text, and the outline can be dragged to move or resize the reference, as in Excel. Point-mode picks (click, drag, arrow keys) are outlined too, so keyboard picking is no longer blind. - Underline as a cell format, plus Mod+Shift+B/I/U toggles that switch on unless every selected cell already has the format. - A formula committed with open parentheses or an open text literal gets the missing closers appended; anything that still doesn't parse is left alone so the usual error shows instead of a guess. - Cells and tables with a fill but no text colour get dark or light text by WCAG contrast instead of the theme colour (no black on black).
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { HELP_TOPICS, SHORTCUT_GROUPS, shortcutKeys } from '../help';
|
||||
|
||||
describe('in-app help content', () => {
|
||||
it('topics have unique ids that never clash with the fixed pages', () => {
|
||||
const ids = HELP_TOPICS.map((t) => t.id);
|
||||
expect(new Set(ids).size).toBe(ids.length);
|
||||
expect(ids).not.toContain('shortcuts');
|
||||
expect(ids).not.toContain('functions');
|
||||
});
|
||||
|
||||
it('no empty topics, sections, items or shortcuts', () => {
|
||||
for (const t of HELP_TOPICS) {
|
||||
expect(t.title.trim()).not.toBe('');
|
||||
expect(t.sections.length).toBeGreaterThan(0);
|
||||
for (const s of t.sections) {
|
||||
expect(s.items.length).toBeGreaterThan(0);
|
||||
for (const i of s.items) expect(i.trim()).not.toBe('');
|
||||
}
|
||||
}
|
||||
for (const g of SHORTCUT_GROUPS) {
|
||||
expect(g.shortcuts.length).toBeGreaterThan(0);
|
||||
for (const s of g.shortcuts) {
|
||||
expect(s.keys.trim()).not.toBe('');
|
||||
expect(s.description.trim()).not.toBe('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('inline markup is balanced, so nothing renders half-bold', () => {
|
||||
const all = HELP_TOPICS.flatMap((t) => t.sections.flatMap((s) => s.items));
|
||||
for (const text of all) {
|
||||
expect((text.match(/`/g) ?? []).length % 2, text).toBe(0);
|
||||
expect((text.match(/\*\*/g) ?? []).length % 2, text).toBe(0);
|
||||
}
|
||||
});
|
||||
|
||||
it('names the keys per platform: Strg on Windows/Linux, ⌘/⌥ and the Mac overrides on a Mac', () => {
|
||||
expect(shortcutKeys({ keys: 'Mod+Umschalt+U' }, 'pc')).toBe('Strg+Umschalt+U');
|
||||
expect(shortcutKeys({ keys: 'Mod+Umschalt+U' }, 'mac')).toBe('⌘+Umschalt+U');
|
||||
expect(shortcutKeys({ keys: 'Alt+Enter oder Mod+Enter' }, 'mac')).toBe('⌥+Enter oder ⌘+Enter');
|
||||
expect(shortcutKeys({ keys: 'Pos1 / Ende', mac: 'fn+← / fn+→' }, 'pc')).toBe('Pos1 / Ende');
|
||||
expect(shortcutKeys({ keys: 'Pos1 / Ende', mac: 'fn+← / fn+→' }, 'mac')).toBe('fn+← / fn+→');
|
||||
// running text: only whole words are key names
|
||||
expect(shortcutKeys('Alter mit Mod', 'mac')).toBe('Alter mit ⌘');
|
||||
});
|
||||
|
||||
it('no Windows/Linux key text is left with a Mac-only symbol, and vice versa', () => {
|
||||
for (const g of SHORTCUT_GROUPS) {
|
||||
for (const s of g.shortcuts) {
|
||||
expect(shortcutKeys(s, 'pc'), s.keys).not.toMatch(/[⌘⌥⌫]|\bfn\b/);
|
||||
expect(shortcutKeys(s, 'mac'), s.keys).not.toMatch(/\b(Strg|Mod|Alt)\b/);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user