OptionalmobileMobile toolbar (bottom pill) integration.
When declared, the registry renders a button in the mobile pill using
the provided icon and label. The button is hidden when the profile key
evaluates to false.
SVG icon markup rendered inside the pill button.
This field must be a static, hardcoded SVG string
written by the module developer. Never assign content that
originates from user input, network responses, URL parameters, or
profile data — SVG markup can carry executable payloads (XSS via
inline event handlers, <script> elements, or href="javascript:").
i18n key resolved at render time to produce the button's accessible label.
Dot-notation profile configuration key that controls visibility.
When config.get(profileKey) evaluates to false, the icon is hidden.
OptionaldefaultVisible?: booleanWhether the icon is visible when profileKey is absent from the profile.
OptionalrequiresPlugin?: stringOptional plugin identifier that must be loaded for this icon to appear.
When set, GeoLeaf.plugins.isLoaded(requiresPlugin) must return true.
Use for toolbar buttons backed by external plugins (not core built-ins).
Optionalaction?: stringOptional toolbar action identifier mapped to data-gl-toolbar-action.
When set, the click handler dispatches the named action (e.g. "search")
instead of opening a sheet modal. Also enables action-specific CSS rules.
Optionalorder?: numberRender order in the mobile pill. Lower values appear first.
Same semantics as IModuleUISlot.filterTab.order — this field aligns the
two halves of the same interface, which declared an explicit order on one side and
relied on an implicit one on the other.
⚠️ Without it, pills render in module registration order, which is an emergent
property of the manifest: presets/manifest.full.ts orders its installers for
load-bearing reasons of its own (see that file's header — it is the registry), and the
toolbar layout was one more meaning silently riding on the same list. Reordering the
manifest for any of the others moved the buttons.
⚠️ This sentence carried a count and a list until 08/08/2026 — « three unrelated
load-bearing reasons (topo-sort tie-breaks, sharedLifecycle sequencing, dependency
edges) » — and BOTH were wrong. sharedLifecycle sequencing was refuted by socle-init
7.4 (__tests__/presets/shared-lifecycle-order.test.ts), and « dependency edges » was
never one of the manifest's stated reasons at all — it was invented here, and copied
from here into scripts/gen-entry.cjs. B-43: the count is gone rather than corrected,
because a second copy of a list can only drift from the list.
Modules that omit it keep the previous behaviour: they render after every ordered one, in registration order.
OptionaldesktopDesktop tab-strip button integration.
When declared, the registry renders an icon button in the right-hand
desktop tab strip (.gl-rp-tabs), inserted above the share button.
On mobile the button is hidden — only mobileIcon is shown on small
screens.
Shares the same guard semantics as mobileIcon: profileKey controls
config-driven visibility, requiresPlugin gates on plugin presence.
SVG icon markup. Same security constraints as mobileIcon.icon:
must be a static, hardcoded string — never user-supplied content.
i18n key resolved at render time for the button's accessible label.
OptionalprofileKey?: stringDot-notation profile key controlling visibility.
When config.get(profileKey) evaluates to false, the button is hidden.
OptionaldefaultVisible?: booleanWhether the button is visible when profileKey is absent.
OptionalrequiresPlugin?: stringPlugin identifier that must be loaded for this button to appear.
Same semantics as mobileIcon.requiresPlugin.
Optionalaction?: stringToolbar action dispatched on click via geoleaf:toolbar:action.
Optionalvariant?: "icon" | "tab"Visual rendering in the desktop tab strip.
"icon" (default): a 28×28 icon button in the bottom stack (.gl-rp-tab-btn),
using icon."tab": a vertical-text tab matching the built-in Filtrer/Couches/Légende
tabs (.gl-rp-tab), showing labelKey as text (the icon is ignored).
Use when the slot replaces a former core tab (e.g. the extracted Table).OptionalfilterDesktop filter panel tab integration.
When declared, the registry renders a tab in the right-hand filter panel.
Tabs are sorted by order (ascending) before rendering.
render is required — it may not be omitted when filterTab is declared.
TypeScript enforces this at compile time. The registry calls render()
exactly once (lazy, returned element is cached), which guarantees
performance and enables straightforward unit testing:
const el = module.ui.filterTab.render().
i18n key resolved at render time to produce the tab title.
Optionalorder?: numberInsertion order relative to other filter tabs. Lower values appear first.
Renders and returns the tab content as an HTMLElement.
Called exactly once by the registry (returned element is cached).
The module is responsible for the full lifecycle of the returned DOM —
destroy() must clean up anything created here.
The root element of the tab content.
UI integration slot declared by a module.
A module may optionally declare:
Both are opt-in. A module that declares neither simply has no UI presence (e.g. a data connector module).
Example