Skip to content

feat: per-category hidden flag for settings modal - #6

Merged
reatlat merged 1 commit into
mainfrom
feature/hide-categories
Jul 7, 2026
Merged

feat: per-category hidden flag for settings modal#6
reatlat merged 1 commit into
mainfrom
feature/hide-categories

Conversation

@reatlat

@reatlat reatlat commented Jul 7, 2026

Copy link
Copy Markdown
Member

Closes #5.

What

Add categories.<id>.hidden: true to remove a consent category from the settings modal. Hidden categories are forced to false (rejected) in the consent state — a visitor can never accept a toggle they cannot see. Essential cannot be hidden; the flag is ignored for it.

Why

Sites that only use 1-2 consent categories currently show all four toggles in the settings modal. Empty toggles for categories the site does not use are confusing and arguably misleading (they imply data processing that is not happening). See #5 for the original request.

How

  • categories.analytics.hidden: true in window.ZestConfig (JS config)
  • data-hide-categories="analytics,marketing" on the script tag (data attribute)
  • Both sources deep-merge, so a label/description override in window.ZestConfig.categories survives when data-hide-categories is also set

Hidden categories are forced to false in every consent path: loadConsent, updateConsent, acceptAll, saveConsent. The modal filters them from rendering. getSelections() explicitly sets them to false so updateConsent receives a complete consent object.

Files

  • src/core/categories.jshidden: false in defaults, getDefaultConsent() forces false, getHiddenCategoryIds()
  • src/storage/consent-store.jssetHiddenCategoryIds(), applyHiddenOverride() in all consent write paths
  • src/core-lifecycle.js — wire setHiddenCategoryIds in coreInit, hasNonEssential now checks result.current
  • src/ui/modal.js — filter hidden from render, getSelections() sets hidden to false
  • src/config/parser.js — parse data-hide-categories, deep-merge categories from window + data sources
  • zest.config.schema.jsonhidden in category definition
  • src/types/zest.d.tsCategoryConfig interface, categories in InitOptions
  • README.md — document both config and data attribute
  • CHANGELOG.md — unreleased entry
  • tests/hide-categories.test.js — 21 tests

Tests

98 pass, build OK. Lint is pre-existing broken on main (ESLint v10 config migration).

Add categories.<id>.hidden: true config option to remove consent
categories from the settings modal. Hidden categories are forced to
false (rejected) in the consent state — a visitor can never accept a
toggle they cannot see. Essential cannot be hidden.

Also accepts data-hide-categories="analytics,marketing" data attribute
(comma-separated list of category IDs) for script-tag-only setups.

Changes:
- src/core/categories.js: hidden flag in DEFAULT_CATEGORIES,
  getDefaultConsent() forces false for hidden, getHiddenCategoryIds()
- src/storage/consent-store.js: setHiddenCategoryIds() setter,
  applyHiddenOverride() in load/save/update/acceptAll
- src/core-lifecycle.js: wire setHiddenCategoryIds in coreInit,
  hasNonEssential now checks result.current instead of selections
- src/ui/modal.js: filter hidden categories from rendering,
  getSelections() explicitly sets hidden categories to false
- src/config/parser.js: parse data-hide-categories attribute
- zest.config.schema.json: hidden property in category definition
- src/types/zest.d.ts: CategoryConfig interface, categories in InitOptions
- README.md: document categories config and data-hide-categories
- CHANGELOG.md: unreleased entry
- tests/hide-categories.test.js: 20 tests covering all paths

Closes #5
@reatlat
reatlat merged commit 6c32e64 into main Jul 7, 2026
1 check passed
@reatlat
reatlat deleted the feature/hide-categories branch July 7, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: allow hiding unused consent categories from the settings modal

1 participant