Hidden Content Check

Opens an .xlsx, .docx or .pptx in the browser before it is shared and lists what is hidden inside: sheets, rows, comments, notes, tracked deletions, author details.

StopsHidden tab leaked staff names

Reply to FOI request #0841

“How many officers hold each rank?” · published on WhatDoTheyKnow

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/hidden-content-check.json

The files land in your project. They're yours to edit.

Usage

hidden-content-check-usage.tsx
import { HiddenContentCheck, type HiddenFinding } from "@/components/ui/hidden-content-check"

<HiddenContentCheck
  file={file}
  audience="anyone on the internet"
  onRemove={remove}
  onShare={async () => {
    await new Promise((r) => setTimeout(r, 600))
    setShared(true)
  }}
/>

What it catches

  • Hidden and very hidden sheets, with their real first rows shown
  • Hidden rows and columns, hidden text and tracked deletions
  • Comments, speaker notes and hidden slides
  • Embedded workbooks (for example a chart's source data in a deck)
  • Links to internal drives and author metadata
  • Share pressed with items still open: asks for a second press

Props

HiddenContentCheck props
PropTypeDefault
file* (required)

The .xlsx, .docx or .pptx about to be shared. `null` clears the check.

File | Blob | null | undefined—
fileName

Name to show when `file` is a Blob without one.

string—
audience

Who will receive it, e.g. "the public". Named in the summary when set.

string—
onShare

Shares the file. May return a Promise; the button shows a pending state and can't fire twice.

(report: HiddenReport) => void | Promise<void>—
onRemove

Removes one finding and returns the cleaned file. The result is re-checked before it counts.

(finding: HiddenFinding, file: File | Blob) => Promise<File | Blob>—
onReportChange

Fires with each report, including after a removal.

(report: HiddenReport) => void—
messages

Override any visible string, including per-kind finding text.

Partial<Omit<Messages, "kind">> & { kind?: Partial<Record<HiddenKind, string>> }—

* required. Also accepts the native props of <section> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Results are labelled by the summary; each finding is a focusable labelled region
  • Expanders use aria-expanded and aria-controls; remove buttons show aria-busy while working
  • Errors use role=alert; focus moves to the next open finding or the share button
  • Animations are skipped under reduced motion

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: If files are shared through your servers, scan and strip metadata there too; the client check can be skipped.

  • Office Open XML only (.xlsx, .docx, .pptx); not .xls, .doc, PDF or images
  • Removal is done by your onRemove; the component re-checks whatever file you hand back
  • Does not detect sensitive data in visible cells, or white-on-white text

What it stops

Hidden tab leaked staff names

Also known as

xlsx · docx · pptx · excel · word · powerpoint · document inspector · metadata

Field type

Dependencies

Pairs well with