feat(editor): add collapse/expand toggle for groups with caching (#12671)

https://github.com/user-attachments/assets/4ef71704-57bb-45b8-9e73-8a51c67fb158

Adds a collapsible toggle for group-by groups.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Collapsible groups for desktop and mobile table views with persistent
per-view collapsed state and a keyboard-accessible toggle button.

- **Bug Fixes**
  - Group title icons now render consistently across variants.

- **Tests**
- Added unit tests verifying collapse/expand behavior for group
components.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: 3720 <zuozijian1994@gmail.com>
Co-authored-by: L-Sun <zover.v@gmail.com>
This commit is contained in:
Richard Lora
2025-11-14 00:21:13 -04:00
committed by GitHub
parent 6ec1948f62
commit e379da200e
5 changed files with 284 additions and 25 deletions
@@ -0,0 +1,36 @@
import { describe, expect, test } from 'vitest';
import { mobileEffects } from '../view-presets/table/mobile/effect.js';
import type { MobileTableGroup } from '../view-presets/table/mobile/group.js';
import { pcEffects } from '../view-presets/table/pc/effect.js';
import type { TableGroup } from '../view-presets/table/pc/group.js';
/** @vitest-environment happy-dom */
describe('TableGroup', () => {
test('toggle collapse on pc', () => {
pcEffects();
const group = document.createElement(
'affine-data-view-table-group'
) as TableGroup;
expect(group.collapsed$.value).toBe(false);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(true);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(false);
});
test('toggle collapse on mobile', () => {
mobileEffects();
const group = document.createElement(
'mobile-table-group'
) as MobileTableGroup;
expect(group.collapsed$.value).toBe(false);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(true);
(group as any)._toggleCollapse();
expect(group.collapsed$.value).toBe(false);
});
});