{"id":16600501,"url":"https://github.com/willmartian/error-label","last_synced_at":"2026-04-20T00:34:43.574Z","repository":{"id":110243637,"uuid":"363303381","full_name":"willmartian/error-label","owner":"willmartian","description":"\u003cerror-label\u003e is a web component for simple, declarative, and accessible error labeling.","archived":false,"fork":false,"pushed_at":"2021-08-11T19:19:32.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-17T06:46:30.303Z","etag":null,"topics":["component","customelement","error","error-label","error-messages","form","forms","headless","html","validation","webcomponent","webcomponents"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willmartian.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-05-01T02:09:11.000Z","updated_at":"2022-01-21T17:00:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"96d638d4-4bc6-490a-9651-94cd71ab010a","html_url":"https://github.com/willmartian/error-label","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willmartian%2Ferror-label","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willmartian%2Ferror-label/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willmartian%2Ferror-label/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willmartian%2Ferror-label/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willmartian","download_url":"https://codeload.github.com/willmartian/error-label/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242582731,"owners_count":20153308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","customelement","error","error-label","error-messages","form","forms","headless","html","validation","webcomponent","webcomponents"],"created_at":"2024-10-12T00:14:46.057Z","updated_at":"2026-04-20T00:34:43.528Z","avatar_url":"https://github.com/willmartian.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Built With Stencil](https://img.shields.io/badge/-Built%20With%20Stencil-16161d.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjIuMSwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI%2BCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI%2BCgkuc3Qwe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU%2BCjxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik00MjQuNywzNzMuOWMwLDM3LjYtNTUuMSw2OC42LTkyLjcsNjguNkgxODAuNGMtMzcuOSwwLTkyLjctMzAuNy05Mi43LTY4LjZ2LTMuNmgzMzYuOVYzNzMuOXoiLz4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQyNC43LDI5Mi4xSDE4MC40Yy0zNy42LDAtOTIuNy0zMS05Mi43LTY4LjZ2LTMuNkgzMzJjMzcuNiwwLDkyLjcsMzEsOTIuNyw2OC42VjI5Mi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNDI0LjcsMTQxLjdIODcuN3YtMy42YzAtMzcuNiw1NC44LTY4LjYsOTIuNy02OC42SDMzMmMzNy45LDAsOTIuNywzMC43LDkyLjcsNjguNlYxNDEuN3oiLz4KPC9zdmc%2BCg%3D%3D\u0026colorA=16161d\u0026style=flat-square)](https://stenciljs.com)\n\n# `\u003cerror-label\u003e`\n\n_Simple, declarative, accessible error labeling._\n\n```html\n\u003cform\u003e\n  \u003clabel for=\"email-input\"\u003eEmail\u003c/label\u003e\n  \u003cinput id=\"email-input\" type=\"email\"\u003e\n  \u003cerror-label for=\"email-input\" type=\"typeMismatch\"\u003eNot a valid email.\u003c/error-label\u003e\n\u003c/form\u003e\n```\n\nForm validation with descriptive error messages is an annoying task that is [necessary](https://www.nngroup.com/articles/visibility-system-status/) in almost _every_ web development project.\n\nThe `\u003cerror-label\u003e` custom element builds off of the browser's default `\u003clabel\u003e` element and [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/API/Constraint_validation) to take the effort out of this common task, allowing developers to stay [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). \n\n[**Live Demo on Codepen**](https://codepen.io/willmartian/pen/BaRYvRy)\n\n**The guiding philosopy of this project is that good error labels should require little to no custom JavaScript.**\n\n- [Features](#features)\n  - [Default Errors](#default-errors)\n  - [Custom Error Messages](#custorm-error-messages)\n  - [Custom Error Types](#custrom-error-types)\n  - [Error Groups](#error-groups)\n  - [Styling](#styling)\n- [Using this component](#using-this-component)\n  - [Licenses](#licenses)\n\n## Features\n### Overview \n\nThe `\u003cerror-label\u003e` custom element works much like the default `\u003clabel\u003e` element. Error labels are linked to inputs using the `for` attribute: `\u003cerror-label for=\"inputId\"\u003e\u003c/error-label\u003e`\n\nHowever, error labels are not displayed to the user by default. They are only visible if the error designated in the `type` attribute has occured: `\u003cerror-label for=\"inputId\" type=\"errorId\"\u003e\u003c/error-label\u003e`\n\n### Default Errors\nWithout providing any [custom errors](), the `\u003cerror-label\u003e` component will support all of the default errors defined by the [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState#properties):\n\n- `badInput`\n- `patternMismatch`\n- `rangeOverflow`\n- `rangeUnderflow`\n- `stepMismatch`\n- `tooLong`\n- `tooShort`\n- `typeMismatch`\n- `valid`\n- `valueMissing`\n\n#### Example\n```html\n\u003cform\u003e\n  \u003clabel for=\"password-input\"\u003ePassword\u003c/label\u003e\n  \u003cinput id=\"password-input\" type=\"password\" minlength=\"6\"\u003e\n  \u003cerror-label for=\"password-input\" type=\"tooShort\"\u003eYour password must be at least 6 characters long.\u003c/error-label\u003e\n\u003c/form\u003e\n```\n\n### Custom Error Messages\n\nYou can provide any custom message or HTML inside of an `\u003cerror-label\u003e`. \n\nIn addition to this, you can also use the `{{value}}` variable to access the raw user input value, or the `{{length}}` variable to access its length. \n\n#### Example\n```html\n\u003cform\u003e\n  \u003clabel for=\"num-input\"\u003eEnter a number\u003c/label\u003e\n  \u003cinput id=\"num-input\" type=\"number\"\u003e\n  \u003cerror-label for=\"num-input\" type=\"badInput\"\u003e{{value}} is not a number.\u003c/error-label\u003e\n\u003c/form\u003e\n```\n\n### Custom Error Types\n\nYou can also provide your own custom error types by providing a config object to the parent `\u003cform\u003e` element's `data-error-config` attribute.\n```html\n\u003cform data-error-config=\"errorLabelConfig\"\u003e\n  \u003clabel for=\"name-input\"\u003eName\u003c/label\u003e\n  \u003cinput id=\"name-input\"\u003e\n  \u003cerror-label for=\"name-input\" type=\"badLang\"\u003ePlease don't say that.\u003c/error-label\u003e\n\u003c/form\u003e\n\n\u003cscript\u003e\nerrorLabelConfig = {\n  errors: {\n    'badLang': target =\u003e target.value.includes('butt'),\n  }\n} \n\u003c/script\u003e\n```\nCustom errors are added to the config objects `error` property. Custom errors are represented as functions that return a boolean value, where a truthy return value indicates the error is present.\n\nReturning a non-empty string will use it as the default message for that error:\n```html\n\u003cform data-error-config=\"errorLabelConfig\"\u003e\n  \u003clabel for=\"name-input\"\u003eName\u003c/label\u003e\n  \u003cinput id=\"name-input\"\u003e\n  \u003cerror-label for=\"name-input\" type=\"badLang\"\u003e\u003c/error-label\u003e\n\u003c/form\u003e\n\n\u003cscript\u003e\nerrorLabelConfig = {\n  errors: {\n    'badLang': target =\u003e target.value.includes('butt') ? `Please don't say ${target.value}.` : false,\n  }\n} \n\u003c/script\u003e\n```\n\n### Error Groups\n\nError labels can also be grouped together to avoid repetition. Attributes defined on the group will be inherited by the error labels within.\n\n```html\n\u003clabel for=\"email-input2\"\u003eError-Group Email\u003c/label\u003e\n\u003cinput id=\"email-input2\" minlength=\"5\" type=\"email\"\u003e\n\u003cerror-label-group for=\"email-input2\"\u003e\n  \u003cerror-label type=\"typeMismatch\"\u003eNot a valid email.\u003c/error-label\u003e\n  \u003cerror-label type=\"tooShort\"\u003eWay too short buddy!\u003c/error-label\u003e\n\u003c/error-label-group\u003e\n```\n\n#### Templates\n\nError groups can also copy content from `\u003ctemplate\u003e` elements, to allow for reusable default messages.\n\n```html\n\u003ctemplate id=\"default-errors\"\u003e\n  \u003cerror-label type=\"typeMismatch\"\u003eNot a valid email.\u003c/error-label\u003e\n  \u003cerror-label type=\"tooShort\"\u003eWay too short!\u003c/error-label\u003e\n\u003c/template\u003e\n```\n\n```html\n\u003cerror-label-group template=\"default-errors\" for=\"email-input\"\u003e\u003c/error-label-group\u003e\n```\n\n### Styling\n\nError labels and groups can be styled using plain CSS:\n```html\n\u003cstyle\u003e\n  error-label {\n    color: red;\n    display: block;\n    margin: .5em;\n    margin-top: 1em;\n  }\n\n  error-label:not([hidden])::before {\n    content: '* '\n  }\n\n  error-label-group {\n    display: block;\n  }\n\u003c/style\u003e\n```\n\n## Using this component\n\nInclude the following at the top of your HTML file:\n\n```html\n\u003cscript type=\"module\" src=\"https://unpkg.com/error-label/dist/error-label/error-label.esm.js\"\u003e\u003c/script\u003e\n```\n\n### Licenses\n\n#### Community License\n\nhttps://www.gnu.org/licenses/gpl-3.0.en.html\n\n#### Enterprise License\n\nA more permissive enterprise license is also available. Please direct all related inquiries [here.](https://willmartian.com/contact)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillmartian%2Ferror-label","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillmartian%2Ferror-label","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillmartian%2Ferror-label/lists"}