Secret Field
Shows an API key or other secret masked, with buttons to reveal it, copy it and ask for a new one.
c2-secret-field shows a secret the app already has, such as an API key, a webhook signing secret or a recovery code, the way the Stripe and OpenAI key pages do. It is masked by default, the eye button shows it, the copy button copies all of it whether it is shown or not, and regenerable adds a button that asks for a new one. It is a read-only display; use c2-password-field for a secret the user types.
The mask keeps reveal-start leading and reveal-end (default 4) trailing characters and draws the rest as twelve bullets whatever its length, so it does not give the length away. A screen reader hears “Hidden, ends with 4242” instead of the bullets, the show button is a toggle with a pressed state, and a copy is announced. The built-in labels are English and translatable.
The regenerate button only fires regenerate. Your app confirms it (a c2-confirm-dialog fits: the old secret stops working), fetches the new secret and sets value, usually with revealed and a help line saying it is shown once.
Import
import '@c2n/components/secret-field'Usage
Starts with acme_live_, hidden, ends with 4242
Starts with acme_hook_, hidden, ends with 9b8a
acme_test_4eC39HqLyjWDarjtT1zdp7dc
Press the eye to show a secret and again to hide it; the copy button works either way.
Regenerating
<c2-secret-field id="key" label="Secret key" value="acme_live_…" reveal-start="10" regenerable></c2-secret-field>
<c2-confirm-dialog id="confirm" heading="Regenerate this key?" message="The current key stops working at once." confirm-label="Regenerate" destructive></c2-confirm-dialog>
<script type="module">
const field = document.querySelector('#key')
const dialog = document.querySelector('#confirm')
field.addEventListener('regenerate', async () => {
if (!(await dialog.show())) return
field.value = await rollKey() // your API call
field.revealed = true
})
</script>