@genesislcap/grid-pro 15.21.1 → 15.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ ---
2
+ description: - When creating or editing an AG Grid embedded component in grid-pro (column filter, floating filter, tooltip, status panel), When styling such a component, When deciding between a plain class and a FAST FoundationElement, When wiring components into combineAllGridComponents or schema fallbacks
3
+ globs:
4
+ - "src/column-filters/**"
5
+ - "src/status-bar-components/**"
6
+ - "src/tooltips/**"
7
+ - "src/cell-editors/**"
8
+ - "src/cell-renderers/**"
9
+ - "src/grid-pro-beta.ts"
10
+ alwaysApply: false
11
+ ---
12
+ # AG-embedded components: class model and styling
13
+
14
+ > **Purpose**: grid-pro embeds two different kinds of components into AG Grid, and mixing up
15
+ > their rules produces runtime crashes ("Illegal constructor") or styling hacks that were already
16
+ > tried and reverted (an inject-styles helper with a rAF retry — see PR #2498, removed in commit
17
+ > `223771156`). Reference implementations: `src/column-filters/enum-column.filter.ts` (plain
18
+ > class) and `src/cell-editors/select.editor.ts` (FoundationElement).
19
+
20
+ ## Rule 1 — pick the right class model
21
+
22
+ **Auto-wired components** — anything the grid registers unconditionally in
23
+ `combineAllGridComponents` or swaps in itself (e.g. the schema filter fallbacks in
24
+ `GridProBeta.applyCommunityFilterFallbacks`): column filters, floating filters, tooltips, status
25
+ panels.
26
+
27
+ - MUST be plain classes implementing the AG interface (`IFilterComp`, `IFloatingFilterComp`,
28
+ `ITooltipComp`, `IStatusPanelComp`).
29
+ - MUST NOT extend `FoundationElement` (or any custom element). AG instantiates components with
30
+ `new`, and constructing a custom element that no design system has registered throws
31
+ `Illegal constructor`. Auto-wired components must work with **zero registration** — a
32
+ registration requirement recreates exactly the missing-module crash (AG error #200/#256) the
33
+ enum filter exists to remove.
34
+
35
+ **Opt-in components** — editors/renderers a consumer references deliberately (`selectEditor`,
36
+ `statusPill`, ...):
37
+
38
+ - These are FAST `FoundationElement`s composed with template + styles and registered per design
39
+ system (foundation/zero/rapid). Follow the existing `cell-editors`/`cell-renderers` pattern,
40
+ including exposure via `grid-components.ts`.
41
+
42
+ ## Rule 2 — style plain components with FAST css in their own shadow root
43
+
44
+ ```ts
45
+ const styles = css`
46
+ :host { /* container styles — the host element */ }
47
+ .my-part { /* inner parts by class */ }
48
+ `;
49
+
50
+ this.eGui = document.createElement('div');
51
+ this.eRoot = this.eGui.attachShadow({ mode: 'open' });
52
+ styles.addStylesTo(this.eRoot); // one constructable sheet, shared by every instance
53
+ ```
54
+
55
+ - The stylesheet travels with the element wherever AG attaches it, works while detached, and is
56
+ parsed once regardless of how many columns use the component.
57
+ - Theme with `--ag-*` custom properties (they inherit through shadow boundaries); always give
58
+ them fallbacks.
59
+
60
+ **Never**:
61
+
62
+ - append a `<style>` element per instance (duplicated per column, per popup open);
63
+ - inject styles into an ancestor root (`document.head` or the grid's shadow root). The grid
64
+ lives inside a design-system shadow root, so document styles don't reach it — and floating
65
+ filters get **no attach hook** from AG, so injection-on-attach degenerates into
66
+ `requestAnimationFrame` retry loops. This was implemented and reverted; don't reintroduce it.
67
+
68
+ ## Gotchas that already bit
69
+
70
+ - Listen for keyboard/DOM events on the **shadow root**, not the host — events retarget at the
71
+ shadow boundary, so a host listener sees `event.target === host` instead of the real control.
72
+ - AG's popup focus trap collects focusable elements with `querySelectorAll`, which does not
73
+ pierce a shadow root — a shadow-DOM popup component must trap Tab/Shift-Tab itself (see
74
+ `EnumColumnFilter.handleKeyDown`). Escape still reaches AG's popup handling, because keyboard
75
+ events are composed and bubble out of the root.
76
+ - On selection/state changes, update existing DOM in place instead of rebuilding lists —
77
+ rebuilding drops keyboard focus mid-interaction.
78
+ - `afterGuiAttached` is only called for filter popups. Floating filters, tooltips, and status
79
+ panels must be fully correct (styles included) straight out of `init()`.
80
+ - Tests: query content via `component.getGui().shadowRoot`, and read focus via
81
+ `shadowRoot.activeElement` (not `document.activeElement`, which reports the host).
82
+ - Render user-visible state as real text, not CSS `content` — generated content is invisible to
83
+ screen readers.