Skip to content
← PIN Input
Edit PIN Input
Name
Also known as (comma separated)
Brief definition
Numeric PIN entry.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "label", "type": "text", "label": "Label", "default": "Enter your 4-digit PIN" }, { "id": "masked", "type": "toggle", "label": "Mask digits", "default": true }, { "id": "variant", "type": "select", "label": "Style", "default": "boxes", "options": [ "boxes", "underline" ] }, { "id": "boxSize", "type": "number", "label": "Box size (px)", "default": 44, "min": 32, "max": 64, "step": 2 }, { "id": "accent", "type": "color", "label": "Focus colour", "default": "#F5C2E0", "presets": [ "#F5C2E0", "#A8E6C1", "#BFD9F2", "#D9C8F0", "#E8A020", "#241430" ] } ]
Templates (JSON object keyed by format)
{ "html": "<fieldset class=\"pin\">\n <legend class=\"pin__legend\">{{label}}</legend>\n <div class=\"pin__row\" style=\"--accent:{{accent}};--size:{{boxSize}}px;\">\n <input class=\"pin__box pin__box--{{variant}}\" type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 1\">\n <input class=\"pin__box pin__box--{{variant}}\" type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 2\">\n <input class=\"pin__box pin__box--{{variant}}\" type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 3\">\n <input class=\"pin__box pin__box--{{variant}}\" type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 4\">\n </div>\n</fieldset>\n<style>\n.pin { font: 14px system-ui, sans-serif; color: #241430; border: none; padding: 0; margin: 0; max-width: 260px; }\n.pin__legend { font-weight: 500; margin-bottom: 8px; padding: 0; }\n.pin__row { display: flex; gap: 8px; }\n.pin__box { width: var(--size); height: var(--size); box-sizing: border-box; text-align: center; font: inherit; font-size: 18px; color: #241430; background: #FAF7F2; }\n.pin__box--boxes { border: 1.5px solid #24143040; border-radius: 8px; }\n.pin__box--underline { border: none; border-bottom: 2px solid #24143040; border-radius: 0; }\n.pin__box:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent); }\n.pin__box--underline:focus-visible { box-shadow: none; }\n</style>", "tailwind": "<fieldset class=\"font-sans text-sm text-[#241430] border-0 p-0 m-0 max-w-[260px]\">\n <legend class=\"font-medium mb-2 p-0\">{{label}}</legend>\n <div class=\"flex gap-2\">\n <input type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 1\" class=\"pin-tw pin-tw--{{variant}} box-border text-center text-lg bg-[#FAF7F2] focus-visible:outline-none\" style=\"width:{{boxSize}}px;height:{{boxSize}}px;border-color:{{accent}};\">\n <input type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 2\" class=\"pin-tw pin-tw--{{variant}} box-border text-center text-lg bg-[#FAF7F2] focus-visible:outline-none\" style=\"width:{{boxSize}}px;height:{{boxSize}}px;border-color:{{accent}};\">\n <input type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 3\" class=\"pin-tw pin-tw--{{variant}} box-border text-center text-lg bg-[#FAF7F2] focus-visible:outline-none\" style=\"width:{{boxSize}}px;height:{{boxSize}}px;border-color:{{accent}};\">\n <input type=\"{{#if masked}}password{{/if}}{{#unless masked}}text{{/unless}}\" inputmode=\"numeric\" maxlength=\"1\" aria-label=\"PIN digit 4\" class=\"pin-tw pin-tw--{{variant}} box-border text-center text-lg bg-[#FAF7F2] focus-visible:outline-none\" style=\"width:{{boxSize}}px;height:{{boxSize}}px;border-color:{{accent}};\">\n </div>\n</fieldset>\n<style>\n.pin-tw--boxes { border: 1.5px solid #24143040; border-radius: 8px; }\n.pin-tw--underline { border: none; border-bottom: 2px solid #24143040; border-radius: 0; }\n</style>", "react": "export function PinInput({\n label = \"{{label}}\",\n masked = {{masked}},\n variant = \"{{variant}}\",\n boxSize = {{boxSize}},\n accent = \"{{accent}}\",\n}) {\n const boxStyle = {\n width: boxSize, height: boxSize, boxSizing: \"border-box\", textAlign: \"center\", font: \"inherit\", fontSize: 18,\n color: \"#241430\", background: \"#FAF7F2\",\n border: variant === \"underline\" ? \"none\" : `1.5px solid ${accent}`,\n borderBottom: variant === \"underline\" ? `2px solid ${accent}` : undefined,\n borderRadius: variant === \"underline\" ? 0 : 8,\n };\n return (\n <fieldset style={{ fontFamily: \"system-ui, sans-serif\", fontSize: 14, color: \"#241430\", border: \"none\", padding: 0, margin: 0, maxWidth: 260 }}>\n <legend style={{ fontWeight: 500, marginBottom: 8, padding: 0 }}>{label}</legend>\n <div style={{ display: \"flex\", gap: 8 }}>\n {[1, 2, 3, 4].map((n) => (\n <input key={n} type={masked ? \"password\" : \"text\"} inputMode=\"numeric\" maxLength={1} aria-label={`PIN digit ${n}`} style={boxStyle} />\n ))}\n </div>\n </fieldset>\n );\n}" }
Save
History