It's also easily misused. Take the regular expression validator for passwords on the California DMV website, for example. The website states "Must include at least 4 alpha characters". But the validation pattern
^(?=(.*[a-zA-Z]){4,})(?=.*[0-9!#$%]).+$
requires that these characters appear consecutively.
Yep, and the .* means "0 or more of anything", so it's 4 or more groups that each end with a letter. They can be consecutive or not and a group can be a single letter but doesn't need to be - so whatever the failure was, it wasn't that (or the regex was typo'd here to be correct instead of what was actually on the site).
AFAIK customValidity is not an attribute and you can only use an imperative setCustomValidity API which is terrible cumbersome to use in a declarative framework like React.