semantic-forms 5.3.5 → 5.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../styles/globals.scss","../styles/inputs.scss","../styles/labels.scss","../styles/colspan.scss","../styles/lowFlow.scss","../semanticForms.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EACE;EACA;EACA;;AAIF;EAnDF;AAAA;AAAA;IAoDI;;;AAIF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAYE;EACA;EACA;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AAmCJ;EAGM;IAjCJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;;AAgBA;EA1CF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAsBJ;AAAA;EAhDE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;;ACpHF;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAIJ;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAIE;AAAA;AAAA;AAAA;AAAA;EACE;;AAKJ;AAAA;AAAA;EACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;EACA;;AAEA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;;AAKN;EACE;;AAGA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;AAMR;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAKJ;EACE;;AAIF;AAAA;AAAA;AAAA;EAIE;;AAIF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;;AAIJ;EACE;;AAEA;EAEE;;AAKJ;EACE;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;EAEE;;AAEA;AAAA;AAAA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;AAIJ;AAAA;AAAA;EACE;;AAEA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;;AAMN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAYE;EACA;EACA;EACA;;AAIF;EACE;IACE;;EAEA;IACE;IACA;IACA;IACA;IACA;IACA;;EAIJ;IACE;;;;ACjTJ;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;EACE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAOF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AASF;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAQF;AAAA;AAAA;AAAA;AAAA;EAEE;;AAIJ;EAEE;;AAGF;AAAA;EAEE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAQJ;EACE;;AAGF;EACE;;AAEA;EACE;;AAMF;EACE;;AAMN;EACE;EACA;EACA;EACA;;AAGF;AAAA;AAAA;EAGE;;AAGF;AAAA;EAEE;;AAGA;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAKA;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAMN;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAKF;EACE;;AAKF;EACE;;AAMN;EACE;EACA;;AAEA;EACE;;AAEA;EAEE;EACA;EACA;;AAON;EACE;EACA;;;ACtRJ;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAMF;AAAA;EACE;;AAIJ;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAKA;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;;AAKN;AAAA;EAEE;;AAGA;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;AAAA;AAAA;IAIE;;EAEA;AAAA;AAAA;AAAA;AAAA;IACE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAME;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAEE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAQE;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAGE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAUE;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAIE;;;;AChQR;AAAA;EAEE;;AAEA;AAAA;EACE;EACA;;AAIF;AAAA;EACE;;AAEA;AAAA;EACE;;AAIA;AAAA;EACE;EACA;EACA;;AAIJ;AAAA;EACE;;AAGA;AAAA;EACE;EACA;EACA;;AAKN;AAAA;EACE;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;EACA;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;;AAEA;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;AAAA;EACE;EACA;;AASF;AAAA;AAAA;EACE;;AAKN;AAAA;EACE;EACA;;AAGA;AAAA;AAAA;EAEE;;AAGE;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAKJ;AAAA;AAAA;EACE;EACA;;AAKJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIF;AAAA;EACE;EACA;EACA;EACA;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKN;AAAA;EAEE;;;ACnJA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAGA;AAAA;AAAA;EAGE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EAnBF;IAoBI;;EAEA;IACE;IACA;IACA;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;;AAGF;EACE;IACE;;;AAKF;EACE;;AAIJ;EACE;EACA;;AAKN;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAEA;EAEE;EACA;EACA;;AAKN;EAEE;;AAKA;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGA;EAEE;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKJ;EACE;EACA;EACA;;AAKJ;EACE;;AAEA;EACE;;AAKJ;EACE;EACA;;AAEA;EACE;;AAIF;EACE;EACA;;AAIF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;;AASR;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;EACE;;AAKE;AAAA;AAAA;EACE;;AAMN;AAAA;EACE","file":"semantic-forms.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../styles/globals.scss","../styles/inputs.scss","../styles/labels.scss","../styles/colspan.scss","../styles/tabs.scss","../styles/lowFlow.scss","../semanticForms.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EA9BF;AAAA;AAAA;IA+BI;;;AA/BJ;AAAA;AAAA;EAkCE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;EACE;EACA;EACA;;AAIF;EA7DF;AAAA;AAAA;IA8DI;;;AAIF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAYE;EACA;EACA;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;;AA4CJ;EAGM;IA1CJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA;;EAEA;IA2BI;MA1BF;;;EA0BE;IAvBJ;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACE;;;AAgBA;EAnDF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EAoCE;IAnCA;;;AAmCA;EAhCF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAsBJ;AAAA;EAzDE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EA0CF;AAAA;IAzCI;;;AAyCJ;AAAA;EAtCE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;;ACpIF;AAAA;EAEE;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAUJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAIA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIF;EAnCF;IAoCI;IACA;IACA;IACA;;;AAGF;EA1CF;IA2CI;;;AAIJ;AAAA;AAAA;EAGE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;AAAA;AAAA;EACE;EACA;;AAMF;AAAA;AAAA;EACE;;AAIF;AAAA;AAAA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;EACA;;AAIE;AAAA;AAAA;AAAA;AAAA;EACE;;AAKJ;AAAA;AAAA;EACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;EACE;EACA;;AAGF;AAAA;AAAA;EACE;EACA;;AAEA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;;AAKN;EACE;EAEA;;AAGA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;;AAMR;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAKJ;EACE;EACA;EACA;EACA;EAEA;EACA;EACA,OAnNc;EAoNd,QApNc;EAqNd;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAEA;EACE;;AAKJ;EACE;;AAIF;AAAA;AAAA;AAAA;EAIE;;AAIF;AAAA;EAEE;;AAIF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;AAAA;AAAA;AAAA;EACE;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;;AAIJ;EACE;;AAEA;EAEE;;AAKJ;EACE;EACA;;AAMA;AAAA;AAAA;AAAA;AAAA;EAEE;;AAEA;AAAA;AAAA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;AAAA;AAAA;EACE;EACA;;AAIJ;AAAA;AAAA;EACE;;AAEA;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;;AAMN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAYE;EACA;EACA;EACA;;AAIF;EACE;IACE;;EAEA;IACE;IACA;IACA;IACA;IACA;IACA;;EAIJ;IACE;;;;AClXJ;AAAA;EAKE;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;EACE;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAOF;EACE;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;;AAOF;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AASF;AAAA;AAAA;AAAA;AAAA;EAEE;EACA;EACA;;AAKJ;EACE;;AAOA;AAAA;AAAA;AAAA;AAAA;EAEE;;AAIJ;EAEE;;AAGF;AAAA;EAEE;;AAMF;EACE;EACA;EACA;EACA;EACA;EACA;EACA,aAjIa;EAkIb;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;AAQJ;EACE;;AAGF;EAEE;;AAEA;EACE;;AAMF;EACE;;AAMN;EACE;EACA;EACA;EACA;;AAGF;AAAA;AAAA;EAGE;;AAGF;AAAA;EAEE;;AAGA;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;EACA;;AAKA;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAMN;EACE;EACA;EAEA;EACA;EACA;EACA;EAEA;EACA;;AAEA;EACE;;AAMF;EACE;;AAKF;EACE;;AAMN;EACE;EACA;;AAEA;EACE;;AAEA;EAEE;EACA;EACA;;AAON;EACE;EACA;;;AC7SJ;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAIF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAMF;AAAA;EACE;;AAIJ;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAGF;AAAA;EAEE;;AAKA;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAMF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;AAAA;AAAA;EAEE;;;AAMN;AAAA;EAEE;;AAGA;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;IAEE;;;AAKJ;EACE;AAAA;AAAA;AAAA;AAAA;IAIE;;EAEA;AAAA;AAAA;AAAA;AAAA;IACE;;EAGF;AAAA;AAAA;AAAA;AAAA;IACE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAME;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAEE;;EAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAEE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAQE;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAGE;;EAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAGE;;;AAMN;EACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAUE;;EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAIE;;EAGF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IAIE;;;;AC1SN;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EAGA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;;AAKJ;EACE;EACA;EACA;;AAGA;EACE;;;ACjER;AAAA;EAEE;;AAEA;AAAA;EACE;EACA;;AAMF;AAAA;EACE;;AAEA;AAAA;EACE;;AAIA;AAAA;EACE;EACA;EACA;;AAKJ;AAAA;EACE;;AAGF;AAAA;EACE;;AAGA;AAAA;EACE;EACA;EACA;;AAKN;AAAA;EACE;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;EACA;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;AAAA;EACE;;AAEA;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAKA;AAAA;EACE;EACA;;AASF;AAAA;AAAA;EACE;;AAKN;AAAA;AAAA;AAAA;EAEE;;AAGF;AAAA;EACE;EACA;;AAGA;AAAA;AAAA;EAEE;;AAGE;AAAA;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAKJ;AAAA;AAAA;EACE;EACA;;AAKJ;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAIF;AAAA;EACE;EACA;EACA;EACA;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;ACvJJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAGA;AAAA;AAAA;AAAA;AAAA;EAGE;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EAnBF;IAoBI;;EAEA;IACE;IACA;IACA;IACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;;AAEA;EAEE;;AAGF;EAEE;EACA;EACA;EACA;EACA;EAEA;EAEA;EACA;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA;EACA;;AAGF;EACE;IACE;;;AAKF;EACE;;AAIJ;EACE;EACA;;AAKN;AAAA;EAEE;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAEA;EAEE;EACA;EACA;;AAOJ;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;;AAGA;EAEE;EACA;EACA;EACA;EACA;;AAGA;EACE;;AAIF;EACE;;AAIF;EACE;EACA;EACA;EACA;;AAIJ;EACE;;AAKA;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAKJ;EACE;EACA;EACA;;AAKJ;EACE;;AAEA;EACE;;AAKJ;EACE;EACA;;AAEA;EACE;;AAIF;EACE;EACA;;AAIF;AAAA;AAAA;EAGE;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;;AAGF;AAAA;EAEE;EACA;;AASR;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;EACA;;AAIJ;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAIJ;AAAA;EAEE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;AAAA;EACE;;AAGF;AAAA;EACE;EACA;;AAGF;AAAA;EACE;;AAGF;AAAA;EACE;;AAGF;AAAA;AAAA;EACE;EACA;EACA;;AAGF;AAAA;AAAA;EACE;;AAKE;AAAA;AAAA;EACE;;AAMN;AAAA;EACE","file":"semantic-forms.css"}
@@ -1,78 +1,62 @@
1
1
  (function(root,factory){if(typeof exports==="object"&&typeof module==="object")module.exports=factory();else if(typeof define==="function"&&define.amd)define("semanticForms",[],factory);else if(typeof exports==="object")exports["semanticForms"]=factory();else root["semanticForms"]=factory()})(this,()=>/******/(()=>{// webpackBootstrap
2
2
  /******/var __webpack_modules__={
3
- /***/90:
4
- /***/(module,__unused_webpack_exports,__webpack_require__)=>{const{createKeyboardShortcut,shortcutListener}=__webpack_require__(497);const{enhanceInput,handleUndoRedo}=__webpack_require__(866);const semanticForms=()=>{
5
- // do some feature detection so none of the JS executes if the browser is too old
6
- if(typeof document.getElementsByClassName!=="function"||typeof document.querySelector!=="function"||!document.body.classList||!window.MutationObserver){console.warn("semantic-forms was loaded into an unsupported browser and will not execute.");return}
7
- // custom keyboard shortcut listener
8
- const keyboardShortcuts=[];document.addEventListener("keydown",e=>shortcutListener(e,keyboardShortcuts));
9
- // progressively enhance form elements that have the semanticForms class
10
- const forms=document.querySelectorAll("form.semanticForms:not(.semanticFormsActive), table.semanticForms:not(.semanticFormsActive)");for(const form of forms){form.classList.add("semanticFormsActive");if(form.classList.contains("lowFlow"))continue;
11
- // update each input in the semantic form
12
- const inputs=Array.from(form.querySelectorAll("input, textarea, select"));for(const input of inputs){enhanceInput(input,form);
13
- // handle keyboard shortcuts
14
- if(input.getAttribute("data-focus-key")!==null){const shortcut=createKeyboardShortcut(input,keyboardShortcuts);keyboardShortcuts.push(shortcut)}}}
15
- // prevents multiple listeners
16
- document.removeEventListener("keydown",handleUndoRedo);document.addEventListener("keydown",handleUndoRedo);
17
- // monitor changes to the DOM and enhance new semanticForms forms that get added
18
- if(!window.semanticFormsObserver){window.semanticFormsObserver=new window.MutationObserver(mutations=>{let stop=false;for(const mutation of mutations){for(const node of mutation.addedNodes)if(node.nodeName==="FORM"||node?.querySelector?.("form")){semanticForms();stop=true}if(stop)break}});window.semanticFormsObserver.observe(document.body,{attributes:false,childList:true,characterData:false,subtree:true})}semanticForms.reinitialize=form=>{form.classList.remove("semanticFormsActive");semanticForms()}};module.exports=semanticForms
3
+ /***/584(module){
4
+ // uses the navigator to best determine the client's operating system
5
+ // returns one of `mac`, `windows`, or `linux`
6
+ const getOS=()=>{const userAgent=window.navigator.userAgent;const platform=window.navigator.platform;let os=null;if(platform.includes("Win"))os="windows";else if(platform.includes("Mac")||/iPhone|iPad|iPod/.test(userAgent))os="mac";else if(platform.includes("Linux")||/Android/.test(userAgent))os="linux";return os};
7
+ // places an element immediately after another element
8
+
9
+ // newNode: the element being placed after the reference node
10
+ // referenceNode: the element the new node is placed after
11
+ const insertAfter=(newNode,referenceNode)=>{if(referenceNode.nextSibling)referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling);else referenceNode.parentNode.appendChild(newNode)};
12
+ // works out how far a font's visible text sits from the middle of its own line box
13
+
14
+ // browsers place a line of text by the font's ascent and descent, which are rarely symmetrical, so the letters themselves end up slightly above or below the middle of the box holding them. that is invisible at the half pixel it usually amounts to, until a display without a high pixel density rounds it up to a whole one. the shift is the same for every element using the font, so it is measured once per font and reused
15
+
16
+ // returns the number of pixels the text sits below the middle of its box, negative when it sits above
17
+ const inkOffsets=new Map;const getInkOffset=(fontStyle,fontWeight,fontSize,fontFamily)=>{const key=`${fontStyle} ${fontWeight} ${fontSize} ${fontFamily}`;if(inkOffsets.has(key))return inkOffsets.get(key);
18
+ // the ascent is where the baseline falls in a line box, which an inline-block aligned to the baseline reports directly
19
+ const probe=document.createElement("div");probe.style.cssText=`position:absolute;left:-9999px;top:0;white-space:nowrap;visibility:hidden;line-height:normal;padding:0;border:0;margin:0;font-style:${fontStyle};font-weight:${fontWeight};font-size:${fontSize};font-family:${fontFamily}`;const marker=document.createElement("span");marker.style.cssText="display:inline-block;width:0;height:0;vertical-align:baseline";probe.append("Hxn",marker);document.body.append(probe);const lineBox=probe.getBoundingClientRect();const ascent=marker.getBoundingClientRect().top-lineBox.top;const descent=lineBox.height-ascent;probe.remove();
20
+ // the cap height is where the letters actually start, which only the drawn pixels can say. drawing it large keeps the answer accurate to a fraction of a pixel
21
+ const scale=8;const size=parseFloat(fontSize);const canvas=document.createElement("canvas");canvas.width=Math.ceil(size*scale*4);canvas.height=Math.ceil(size*scale*3);const context=canvas.getContext("2d",{willReadFrequently:true});context.fillStyle="#fff";context.fillRect(0,0,canvas.width,canvas.height);context.fillStyle="#000";context.font=`${fontStyle} ${fontWeight} ${size*scale}px ${fontFamily}`;context.textBaseline="alphabetic";const baseline=Math.round(size*scale*2);context.fillText("Hxn",10,baseline);const pixels=context.getImageData(0,0,canvas.width,canvas.height).data;let inkTop=null;for(let y=0;y<canvas.height&&inkTop===null;y++)for(let x=0;x<canvas.width;x++)if(pixels[(y*canvas.width+x)*4]<128){inkTop=y;break}if(inkTop===null){const none={offset:0,fieldOffset:0};inkOffsets.set(key,none);return none}const capHeight=(baseline-inkTop)/scale;
22
+ // rounded to whole device pixels, because browsers put a line of text on the pixel grid rather than at the fraction of one asked for. a correction finer than that either does nothing or moves the letters a whole pixel, depending on which side of the halfway mark the sum lands
23
+
24
+ // two roundings come out of this, because a measurement landing exactly halfway can go either way and the browser does not send every kind of text the same way. our own labels follow the ordinary rounding; the text a field draws inside itself, and the text on a button, follow the one that rounds a half away from zero. they differ only for a measurement of exactly minus a half, and agree everywhere else
25
+ const ratio=window.devicePixelRatio||1;const exact=((ascent-descent)/2-capHeight/2)*ratio;const offset=Math.round(exact)/ratio;const fieldOffset=Math.sign(exact)*Math.round(Math.abs(exact))/ratio;const pair={offset,fieldOffset};inkOffsets.set(key,pair);return pair};
26
+ // puts the measured offset on the form as a custom property, for the stylesheet to subtract when it centers the float label on its field
27
+ const applyInkOffset=(form,label)=>{if(!label.isConnected)return;const style=window.getComputedStyle(label);const{offset,fieldOffset}=getInkOffset(style.fontStyle,style.fontWeight,style.fontSize,style.fontFamily);form.style.setProperty("--semanticFormsTextInkOffset",`${offset}px`);form.style.setProperty("--semanticFormsFieldTextInkOffset",`${fieldOffset}px`)};
28
+ // a web font that is still downloading when a form is enhanced is measured in whichever font the page falls back to, and the letters move once the real one arrives. the forms measured so far are remembered so they can be measured again at that point, which the browser reports once for the page rather than once per font
29
+ const measured=new Map;let awaitingFonts=false;const setInkOffset=(form,label)=>{measured.set(form,label);applyInkOffset(form,label);if(awaitingFonts||!document.fonts)return;awaitingFonts=true;document.fonts.ready.then(()=>{
30
+ // the cache is keyed by what the font is called, which does not change when the file behind it finally loads
31
+ inkOffsets.clear();for(const[form,label]of measured)applyInkOffset(form,label);measured.clear()})};module.exports={getOS,insertAfter,setInkOffset}
19
32
  /***/},
20
- /***/497:
21
- /***/(module,__unused_webpack_exports,__webpack_require__)=>{const{getOS,insertAfter}=__webpack_require__(584);const specialCharMap={Minus:"-",Equal:"=",BracketLeft:"[",BracketRight:"]",Backslash:"\\",Semicolon:";",Quote:"'",Comma:",",Period:".",Slash:"/",Backquote:"`"};const shiftSpecialCharMap={1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")",Minus:"_",Equal:"+",BracketLeft:"{",BracketRight:"}",Backslash:"|",Semicolon:":",Quote:'"',Comma:"<",Period:">",Slash:"?",Backquote:"~"};
22
- // handles keyboard shortcut events
23
- const shortcutListener=(e,shortcuts)=>{
24
- // search for matching shortcut from cached shortcut configs
25
- const shortcut=shortcuts.find(shortcut=>{let matchesKey=false;if(e.altKey&&!e.shiftKey)
26
- // mac adjusts the key value if altKey is pressed
27
- matchesKey="Key"+shortcut.key.toUpperCase()===e.code||"Digit"+shortcut.key.toUpperCase()===e.code||shortcut.key===e.key||specialCharMap[e.code]===shortcut.key;else if(e.shiftKey){
28
- // check shift special character map
29
- const code=e.code.replace(/Key|Digit/,"");matchesKey=(shiftSpecialCharMap[code]||shiftSpecialCharMap[e.key])&&(shiftSpecialCharMap[code]===shortcut.key||shiftSpecialCharMap[e.key]===shortcut.key)}else matchesKey=shortcut.key.toUpperCase()===e.key.toUpperCase();if(!matchesKey)return false;let matchesModifier;if(shortcut.modifier){if(shortcut.modifier===shortcut.defaultModifier)matchesModifier=shortcut.os==="windows"||shortcut.os==="linux"?e.ctrlKey:e.metaKey;if(shortcut.modifier==="meta")matchesModifier=e.metaKey;if(shortcut.modifier==="alt")matchesModifier=e.altKey;if(shortcut.modifier==="ctrl")matchesModifier=e.ctrlKey}return matchesModifier});if(shortcut){e.preventDefault();shortcut.input.focus()}};const createKeyboardShortcut=(input,shortcuts)=>{const os=getOS();
30
- // this is the custom keyword for meta on linux/mac, ctrl on windows
31
- const defaultModifier="metactrl";
32
- // get focus key value
33
- let focusKey=input.getAttribute("data-focus-key");if(focusKey.length>1){console.error(`Provided focus key "${focusKey}" is more than one character. Using first character only.`);focusKey=focusKey.toString()[0]}
34
- // get focus modifier value
35
- let modifierSymbol;let modifierKey=defaultModifier;const modifierAttr={default:input.getAttribute("data-focus-modifier")||defaultModifier,linux:input.getAttribute("data-focus-modifier-linux"),mac:input.getAttribute("data-focus-modifier-mac"),windows:input.getAttribute("data-focus-modifier-win")};if(os&&modifierAttr[os])
36
- // a specific modifier key has been set by the user
37
- modifierKey=modifierAttr[os];else modifierKey=modifierAttr.default;
38
- // validate passed in modifier
39
- const recognizedModifiers=["ctrl","alt","opt","meta","cmd",defaultModifier];if(!recognizedModifiers.includes(modifierKey)){console.error(`Received an unrecognized modifier, "${modifierKey}," defaulting to "${defaultModifier}."`,input);modifierKey=defaultModifier}
40
- // retrieve modifier symbol
41
- if(["alt","opt"].includes(modifierKey))modifierSymbol=os==="mac"?"⌥":"⎇";else if(["meta","win","cmd"].includes(modifierKey)||modifierKey===defaultModifier&&os==="mac")if(os==="mac")modifierSymbol="⌘";else if(os==="linux")modifierSymbol="◆";else modifierSymbol="⊞";else if(modifierKey==="ctrl"||modifierKey===defaultModifier&&(os==="windows"||os==="linux"))if(os==="mac")modifierSymbol="⌃";else modifierSymbol="Ctrl";
42
- // add the shortcut to the cached array, if not a duplicate
43
- if(shortcuts.some(shortcut=>shortcut.key===focusKey&&shortcut.modifier===modifierKey))console.error(`Duplicate keyboard shortcut "${modifierKey} + ${focusKey}" detected. Only the first input will be focusable using this keyboard shortcut.`,input);
44
- // set the shortcut indicator/title
45
- if(input.nodeName==="TEXTAREA"||input.type==="text"||input.type==="number"){
46
- // create focus indicator for valid inputs
47
- const indicator=document.createElement("span");indicator.classList.add("focus-key");indicator.innerHTML=`<kbd>${modifierSymbol} ${focusKey.toUpperCase()}</kbd>`;const label=input.nextSibling;insertAfter(indicator,label)}else
48
- // update the input title
49
- if(input.getAttribute("title"))input.setAttribute("title",input.getAttribute("title")+` (${modifierSymbol} + ${focusKey})`);else input.setAttribute("title",`Focus with ${modifierSymbol} + ${focusKey}`);return{key:focusKey,modifier:modifierKey,input,os,defaultModifier}};module.exports={shortcutListener,createKeyboardShortcut}
50
- /***/},
51
- /***/584:
52
- /***/module=>{
53
- /**
54
- * Uses the navigator to best determine the clients operating system.
55
- * @returns Operating system string (`mac`, `windows`, `linux`)
56
- */
57
- const getOS=()=>{const userAgent=window.navigator.userAgent;const platform=window.navigator.platform;let os=null;if(platform.includes("Win"))os="windows";else if(platform.includes("Mac")||/iPhone|iPad|iPod/.test(userAgent))os="mac";else if(platform.includes("Linux")||/Android/.test(userAgent))os="linux";return os}
58
- /**
59
- * Places an element immediately after another element
60
- * @param {Object} newNode element being placed after the reference node
61
- * @param {*} referenceNode element to be used as reference for new node
62
- */;const insertAfter=(newNode,referenceNode)=>{if(referenceNode.nextSibling)referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling);else referenceNode.parentNode.appendChild(newNode)};module.exports={getOS,insertAfter}
63
- /***/},
64
- /***/866:
65
- /***/(module,__unused_webpack_exports,__webpack_require__)=>{const{insertAfter}=__webpack_require__(584);const icons={passwordShow:'<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m1 12s4-8 11-8 11 8 11 8"/><path d="m1 12s4 8 11 8 11-8 11-8"/><circle cx="12" cy="12" r="3"/></g></svg>',passwordHide:'<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m2 2 20 20"/><path d="m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335"/><path d="m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192"/></g></svg>',helpIcon:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" version="1.1" style="overflow:visible;"><rect width="16" height="16" fill="none"/><path fill="currentColor" d="M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z"/></svg>'};const lookups={nodeName:["TEXTAREA","SELECT"],inputType:["checkbox","color","date","datetime-local","email","file","image","month","number","password","radio","range","search","tel","text","time","url","week"]};let lastFocusedInput;let lastClearFieldPressed;const enhanceInput=(input,form)=>{
33
+ /***/866(module,__unused_webpack_exports,__webpack_require__){const{insertAfter}=__webpack_require__(584);const icons={passwordShow:'<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m1 12s4-8 11-8 11 8 11 8"/><path d="m1 12s4 8 11 8 11-8 11-8"/><circle cx="12" cy="12" r="3"/></g></svg>',passwordHide:'<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m2 2 20 20"/><path d="m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335"/><path d="m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192"/></g></svg>',helpIcon:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" version="1.1" style="overflow:visible;"><rect width="16" height="16" fill="none"/><path fill="currentColor" d="M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z"/></svg>'};const lookups={nodeName:["TEXTAREA","SELECT"],inputType:["checkbox","color","date","datetime-local","email","file","image","month","number","password","radio","range","search","tel","text","time","url","week"]};let lastFocusedInput;let lastClearFieldPressed;
34
+ // browsers that implement the switch attribute expose it on the input prototype, render the control as a switch and report the switch role themselves, so nothing below is needed there
35
+ const nativeSwitchSupport="switch"in window.HTMLInputElement.prototype;
36
+ // lets a polyfilled switch be toggled by dragging its thumb, which is what the native control does. a pointer that never travels far enough is left alone so it still lands as a click.
37
+ const enableSwitchDragging=input=>{input.addEventListener("pointerdown",event=>{if(input.disabled)return;const startX=event.clientX;const rightToLeft=window.getComputedStyle(input).direction==="rtl";
38
+ // half the track is the distance the thumb travels between the two positions
39
+ const travel=input.clientWidth/2||1;const wasChecked=input.checked;let dragging=false;input.setPointerCapture(event.pointerId);const drag=moveEvent=>{const distance=rightToLeft?startX-moveEvent.clientX:moveEvent.clientX-startX;if(!dragging&&Math.abs(distance)<=5)return;// still within a click
40
+ dragging=true;moveEvent.preventDefault();// don't select or scroll while dragging
41
+ input.checked=(wasChecked?1:0)+distance/travel>.5};const drop=upEvent=>{input.releasePointerCapture(upEvent.pointerId);input.removeEventListener("pointermove",drag);input.removeEventListener("pointerup",drop);input.removeEventListener("pointercancel",drop);if(!dragging)return;
42
+ // the click that follows the drag would otherwise put the switch back where it started
43
+ input.addEventListener("click",clickEvent=>clickEvent.preventDefault(),{once:true,capture:true});if(input.checked!==wasChecked){input.dispatchEvent(new Event("input",{bubbles:true}));input.dispatchEvent(new Event("change",{bubbles:true}))}};input.addEventListener("pointermove",drag);input.addEventListener("pointerup",drop);input.addEventListener("pointercancel",drop)})};const enhanceInput=(input,form)=>{
66
44
  // ignore input if it has previously been formatted
67
45
  if(input.classList.contains("semanticform")||!input.id)return;const type=input.getAttribute("type");if(!lookups.nodeName.includes(input.nodeName)&&!lookups.inputType.includes(type))return;
68
46
  // recursively find <dl> element
69
- let dl=input.parentNode;while(dl&&dl.nodeName!=="DL")dl=dl.parentNode;if(!dl)return;if(!dl.classList.contains("floatLabelForm"))dl.classList.add("floatLabelForm");const label=input.parentNode.parentNode.id&&(type==="checkbox"||type==="radio")?document.querySelector("label[data-for="+input.parentNode.parentNode.id.replace(/\./g,"\\.")+"]"):document.querySelector("label[for="+input.id.replace(/\./g,"\\.")+"]");if(!label)console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) without a properly associated label. Make sure there is a label for it and the label has a matching "for" attribute.`);input.classList.add("semanticform");const isWrapped=input.closest("dd").parentElement.nodeName==="DIV";
47
+ let dl=input.parentNode;while(dl&&dl.nodeName!=="DL")dl=dl.parentNode;if(!dl)return;if(!dl.classList.contains("floatLabelForm"))dl.classList.add("floatLabelForm");
48
+ // the label is looked up in the input's own tree rather than the document, so that a form inside a shadow root finds its labels instead of coming up empty
49
+ const tree=input.getRootNode();const label=input.parentNode.parentNode.id&&(type==="checkbox"||type==="radio")?tree.querySelector("label[data-for="+input.parentNode.parentNode.id.replace(/\./g,"\\.")+"]"):tree.querySelector("label[for="+input.id.replace(/\./g,"\\.")+"]");if(!label){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) without a properly associated label. Make sure there is a label for it and the label has a matching "for" attribute.`);return}input.classList.add("semanticform");
50
+ // an input outside a <dd> is reported by the checks further down, so tolerate it here
51
+ const isWrapped=input.closest("dd")?.parentElement.nodeName==="DIV";
70
52
  // #region create labels
71
53
  const newLabel=document.createElement("label");newLabel.className="floatLabelFormAnimatedLabel";if(type==="checkbox"||type==="radio"){const div=isWrapped?input.closest("dd").parentElement:document.createElement("div");const dt=label.closest("dt");const dd=input.closest("dd");if(!dt||!dd){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that is not inside a <dd> element.`);return}if(dd.firstChild.nodeName!=="LABEL"){if(type==="checkbox"&&input.parentNode.nodeName==="DD"){newLabel.setAttribute("for",input.id);input.parentNode.classList.add("singleCheckbox");newLabel.className="";label.setAttribute("hidden","hidden");insertAfter(newLabel,input)}if(type==="radio"&&input.parentNode.nodeName==="DD"){newLabel.setAttribute("for",input.id);input.parentNode.classList.add("singleRadio");newLabel.className="";label.setAttribute("hidden","hidden");insertAfter(newLabel,input)}newLabel.innerHTML=label.innerHTML;if(label.hasAttribute("title")&&label.getAttribute("data-show-help-icon")!==null&&!label.querySelector("span.help")){const text=label.getAttribute("title");label.innerHTML+=` <span title="${text}" class="help">${icons.helpIcon}</span>`;newLabel.innerHTML+=` <span title="${text}" class="help">${icons.helpIcon}</span>`}if(dd.querySelector(":required")&&label.getAttribute("data-no-asterisk")===null&&!label.querySelector("span.required")){const text=label.getAttribute("data-asterisk-text")||"This field is required.";label.innerHTML+=` <span title="${text}" class="required">*</span>`;newLabel.innerHTML+=` <span title="${text}" class="required">*</span>`}if(!dd.querySelector("label"))dd.append(newLabel)}
72
54
  // if the user did not wrap the input in a div, do it for them
73
- if(!isWrapped){div.append(dt,dd);
55
+ if(!isWrapped){
56
+ // the wrapper goes where the <dt> was, so the field keeps its place in the markup. a div the author wrote is already in the right place and is deliberately left where it is: moving it would push the field past anything the enhancer does not touch, such as a <dd> holding only a button
57
+ dt.before(div);div.append(dt,dd);
74
58
  // determine visibility of newly created <div>
75
- if(dt.style.display==="none"&&dd.style.display==="none")div.style.display="none"}dl.append(div)}else{newLabel.setAttribute("for",input.id);newLabel.innerHTML=label.innerHTML;if(input.hasAttribute("title")&&label.getAttribute("data-show-help-icon")!==null&&!label.querySelector("span.help")){const text=input.getAttribute("title");newLabel.innerHTML+=` <span title="${text}" class="help">${icons.helpIcon}</span>`}if(input.hasAttribute("required")&&label.getAttribute("data-no-asterisk")===null&&!label.querySelector("span.required")){const text=label.getAttribute("data-asterisk-text")||"This field is required.";newLabel.innerHTML+=` <span title="${text}" class="required">*</span>`}label.setAttribute("hidden","hidden");insertAfter(newLabel,input)}
59
+ if(dt.style.display==="none"&&dd.style.display==="none")div.style.display="none"}}else{newLabel.setAttribute("for",input.id);newLabel.innerHTML=label.innerHTML;if(input.hasAttribute("title")&&label.getAttribute("data-show-help-icon")!==null&&!label.querySelector("span.help")){const text=input.getAttribute("title");newLabel.innerHTML+=` <span title="${text}" class="help">${icons.helpIcon}</span>`}if(input.hasAttribute("required")&&label.getAttribute("data-no-asterisk")===null&&!label.querySelector("span.required")){const text=label.getAttribute("data-asterisk-text")||"This field is required.";newLabel.innerHTML+=` <span title="${text}" class="required">*</span>`}label.setAttribute("hidden","hidden");insertAfter(newLabel,input)}
76
60
  // #endregion
77
61
  // #region standard inputs
78
62
  // check for auto-grow attribute on textareas
@@ -81,27 +65,30 @@ if(input.getAttribute("data-auto-grow")!==null){
81
65
  if(input.nodeName==="INPUT"&&input.type==="text"){const newInput=document.createElement("textarea");newInput.id=input.id;newInput.class=input.class;newInput.innerText=input.value;newInput.setAttribute("data-auto-grow","");input.replaceWith(newInput);input=newInput}if(input.nodeName==="TEXTAREA")
82
66
  // when pressing enter while this input is focused, we want to submit
83
67
  input.addEventListener("keypress",e=>{if(e.key!=="Enter"||e.key==="Enter"&&e.shiftKey)return;e.preventDefault();form.requestSubmit()})}if(type!=="checkbox"&&type!=="radio"){if(!input.getAttribute("placeholder"))input.setAttribute("placeholder"," ");const div=isWrapped?input.closest("dd").parentElement:document.createElement("div");const dt=label.closest("dt");const dd=input.closest("dd");if(!dt||!dd){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that does not have a corresponding ${!dt?"<dt>":"<dd>"} element.`);return}
84
- // input clear button
85
- if(input.nodeName!=="SELECT"&&type!=="range"){const clearBtn=document.createElement("button");clearBtn.type="button";clearBtn.title=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.ariaLabel=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.tabIndex=-1;clearBtn.innerHTML='<svg viewBox="0 0 16 16" width="18" height="18"><path d="M 1 1 L 15 15 M 1 15 L 15 1" fill="none" stroke-width="2" stroke="currentColor" />';clearBtn.classList.add("clear");clearBtn.id=`semanticFormsClearButton_${input.id}`;clearBtn.addEventListener("click",()=>{input.previousValue=input.value;input.value="";input.focus();lastClearFieldPressed=input.id;
68
+ // input clear button. a field the user cannot edit does not get one, since the button would empty it anyway. a field that only becomes uneditable later is handled in css
69
+ if(input.nodeName!=="SELECT"&&type!=="range"&&!input.readOnly&&!input.disabled){const clearBtn=document.createElement("button");clearBtn.type="button";clearBtn.title=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.ariaLabel=input.getAttribute("data-clear-field-text")||"Clear field";clearBtn.tabIndex=-1;clearBtn.innerHTML='<svg viewBox="0 0 16 16" width="18" height="18"><path d="M 1 1 L 15 15 M 1 15 L 15 1" fill="none" stroke-width="2" stroke="currentColor" />';clearBtn.classList.add("clear");clearBtn.id=`semanticFormsClearButton_${input.id}`;clearBtn.addEventListener("click",()=>{input.previousValue=input.value;input.value="";input.focus();lastClearFieldPressed=input.id;
86
70
  // used for any other updates required by various inputs
87
71
  input.dispatchEvent(new Event("input",{bubbles:true}))});insertAfter(clearBtn,dd.querySelector("label"))}input.addEventListener("focus",event=>{if(event.target.nodeName==="INPUT")lastFocusedInput=event.target});
88
- // check for colspan- utility class on dd, and move to div
89
- if(/colspan-/.test(dd.className)){const match=dd.className.match(/colspan-([0-9]|full)/)[0];dd.classList.remove(match);div.classList.add(match)}
72
+ // the colspan- and col- utility classes are documented as going on the dd, but they size and place the grid item, which is the div wrapping it, so move any of them across
73
+ for(const utility of dd.className.match(/colspan-(?:[0-9]|full)|col-[0-9]/g)||[]){dd.classList.remove(utility);div.classList.add(utility)}
90
74
  // check for max-content attribute
91
75
  // this may be removed once fully supported in Firefox and Safari: https://caniuse.com/wf-field-sizing
92
76
  if(input.getAttribute("data-max-content")!==null)if(!("fieldSizing"in document.createElement("input").style)){const adjustWidth=()=>{const value=input.value!==""?input.value:input.placeholder;const width=value.length*8+40;input.style.width=width+"px";input.style.maxWidth="100%"};adjustWidth();input.addEventListener("input",adjustWidth)}
93
77
  // if the user did not wrap the input in a div, do it for them
94
- if(!isWrapped){div.append(dt,dd);
78
+ if(!isWrapped){
79
+ // as above, the wrapper takes the <dt>'s position rather than being appended to the end
80
+ dt.before(div);div.append(dt,dd);
95
81
  // determine visibility of newly created <div>
96
- if(dt.style.display==="none"&&dd.style.display==="none")div.style.display="none"}dl.append(div)}
82
+ if(dt.style.display==="none"&&dd.style.display==="none")div.style.display="none"}}
97
83
  // #endregion
98
84
  // handle file input clear btn, cannot be handled with CSS
99
85
  if(type==="file"){const clearBtn=input.parentElement.querySelector(".clear");input.addEventListener("input",event=>{clearBtn.style.display=event.target.files.length?"flex":"none"});clearBtn.addEventListener("click",()=>{clearBtn.style.display="none"})}
100
- // handle range inputs with a class to display the value
101
- // TODO: should this be a data attribute instead?
102
- if(type==="range"&&input.classList.contains("displayValue")){const label=input.parentNode.parentNode.querySelector("dd label");label.innerHTML+=`<span class="seperator">: </span><output>${input.value}</output>`;input.addEventListener("input",event=>{const output=event.target.parentNode.parentNode.querySelector("output");output.innerHTML=event.target.value})}
86
+ // handle range inputs set to display the value. every other per-field flag in the library is a data attribute, so that is the documented way to ask for this, but the original `displayValue` class is still honored
87
+ if(type==="range"&&(input.getAttribute("data-display-value")!==null||input.classList.contains("displayValue"))){const label=input.parentNode.parentNode.querySelector("dd label");label.innerHTML+=`<span class="seperator">: </span><output>${input.value}</output>`;input.addEventListener("input",event=>{const output=event.target.parentNode.parentNode.querySelector("output");output.innerHTML=event.target.value})}
103
88
  // show password button
104
89
  if(type==="password"&&input.getAttribute("data-no-reveal")===null){const showBtn=document.createElement("button");showBtn.type="button";showBtn.title=input.getAttribute("data-show-password-text")||"Show password";showBtn.ariaLabel=input.getAttribute("data-show-password-text")||"Show password";showBtn.tabIndex=-1;showBtn.innerHTML=icons.passwordShow;showBtn.classList.add("show");showBtn.id=`semanticFormsShowButton_${input.id}`;const dd=input.closest("dd");if(!dd){console.error(`semantic-forms: Found an input (${input.id||input.getAttribute("name")}) that is not inside a <dd> element.`);return}showBtn.addEventListener("click",()=>{if(input.type==="password"){showBtn.innerHTML=icons.passwordHide;showBtn.title=input.getAttribute("data-hide-password-text")||"Hide password";showBtn.ariaLabel=input.getAttribute("data-hide-password-text")||"Hide password";input.type="text"}else{showBtn.innerHTML=icons.passwordShow;showBtn.title=input.getAttribute("data-show-password-text")||"Show password";showBtn.ariaLabel=input.getAttribute("data-show-password-text")||"Show password";input.type="password"}input.focus()});insertAfter(showBtn,dd.querySelector("label"))}
90
+ // a checkbox with the switch attribute is a switch; the stylesheet draws one in every browser, and where the attribute is not implemented natively the role and dragging are supplied here
91
+ if(type==="checkbox"&&input.hasAttribute("switch")&&!nativeSwitchSupport){input.setAttribute("role","switch");enableSwitchDragging(input)}
105
92
  // add listener to shift clear button when scrollbar present
106
93
  if(input.nodeName==="TEXTAREA"){if(input.getAttribute("data-disable-autosize")===null){
107
94
  // add auto-sizing
@@ -134,24 +121,110 @@ const shiftClearBtn=()=>{const clearBtn=input.parentElement?.querySelector("butt
134
121
  // handle undo/redo
135
122
  if((event.ctrlKey||event.metaKey)&&event.key==="z"&&!event.shiftKey){
136
123
  // undo clearing a field
137
- if(lastFocusedInput)if(lastFocusedInput?.parentNode?.querySelector("button.clear").id===`semanticFormsClearButton_${lastClearFieldPressed}`||lastFocusedInput?.parentNode?.querySelector("button.clear").name===`semanticFormsClearButton_${lastClearFieldPressed}`)if(lastFocusedInput.previousValue){lastFocusedInput.redoValue=lastFocusedInput.value;lastFocusedInput.value=lastFocusedInput.previousValue}}else if(event.ctrlKey&&event.key==="y"||event.metaKey&&event.shiftKey&&event.key==="z")
124
+ if(lastFocusedInput)if(lastFocusedInput?.parentNode?.querySelector("button.clear")?.id===`semanticFormsClearButton_${lastClearFieldPressed}`||lastFocusedInput?.parentNode?.querySelector("button.clear")?.name===`semanticFormsClearButton_${lastClearFieldPressed}`)if(lastFocusedInput.previousValue){
125
+ // the browser undoes the field's own edit history on this key too, which would apply on top of the value restored here, so the native behavior is suppressed
126
+ event.preventDefault();lastFocusedInput.redoValue=lastFocusedInput.value;lastFocusedInput.value=lastFocusedInput.previousValue}}else if(event.ctrlKey&&event.key==="y"||event.metaKey&&event.shiftKey&&event.key==="z")
138
127
  // redo clearing a field
139
- if(lastFocusedInput)if(lastFocusedInput?.parentNode?.querySelector("button.clear").id===`semanticFormsClearButton_${lastClearFieldPressed}`||lastFocusedInput?.parentNode?.querySelector("button.clear").name===`semanticFormsClearButton_${lastClearFieldPressed}`)if(lastFocusedInput.redoValue){lastFocusedInput.previousValue=lastFocusedInput.value;lastFocusedInput.value=lastFocusedInput.redoValue}};module.exports={enhanceInput,handleUndoRedo}
128
+ if(lastFocusedInput)if(lastFocusedInput?.parentNode?.querySelector("button.clear")?.id===`semanticFormsClearButton_${lastClearFieldPressed}`||lastFocusedInput?.parentNode?.querySelector("button.clear")?.name===`semanticFormsClearButton_${lastClearFieldPressed}`)if(lastFocusedInput.redoValue){
129
+ // as above, the browser's own redo would otherwise apply on top of this
130
+ event.preventDefault();lastFocusedInput.previousValue=lastFocusedInput.value;lastFocusedInput.value=lastFocusedInput.redoValue}};module.exports={enhanceInput,handleUndoRedo}
131
+ /***/},
132
+ /***/497(module,__unused_webpack_exports,__webpack_require__){const{getOS,insertAfter}=__webpack_require__(584);const specialCharMap={Minus:"-",Equal:"=",BracketLeft:"[",BracketRight:"]",Backslash:"\\",Semicolon:";",Quote:"'",Comma:",",Period:".",Slash:"/",Backquote:"`"};const shiftSpecialCharMap={1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")",Minus:"_",Equal:"+",BracketLeft:"{",BracketRight:"}",Backslash:"|",Semicolon:":",Quote:'"',Comma:"<",Period:">",Slash:"?",Backquote:"~"};
133
+ // handles keyboard shortcut events
134
+ const shortcutListener=(e,shortcuts)=>{
135
+ // search for matching shortcut from cached shortcut configs
136
+ const shortcut=shortcuts.find(shortcut=>{let matchesKey=false;if(e.altKey&&!e.shiftKey)
137
+ // mac adjusts the key value if altKey is pressed
138
+ matchesKey="Key"+shortcut.key.toUpperCase()===e.code||"Digit"+shortcut.key.toUpperCase()===e.code||shortcut.key===e.key||specialCharMap[e.code]===shortcut.key;else if(e.shiftKey){
139
+ // check shift special character map
140
+ const code=e.code.replace(/Key|Digit/,"");matchesKey=(shiftSpecialCharMap[code]||shiftSpecialCharMap[e.key])&&(shiftSpecialCharMap[code]===shortcut.key||shiftSpecialCharMap[e.key]===shortcut.key)}else matchesKey=shortcut.key.toUpperCase()===e.key.toUpperCase();if(!matchesKey)return false;let matchesModifier;if(shortcut.modifier){if(shortcut.modifier===shortcut.defaultModifier)matchesModifier=shortcut.os==="windows"||shortcut.os==="linux"?e.ctrlKey:e.metaKey;if(shortcut.modifier==="meta")matchesModifier=e.metaKey;if(shortcut.modifier==="alt")matchesModifier=e.altKey;if(shortcut.modifier==="ctrl")matchesModifier=e.ctrlKey}return matchesModifier});if(shortcut){e.preventDefault();shortcut.input.focus()}};const createKeyboardShortcut=(input,shortcuts)=>{const os=getOS();
141
+ // this is the custom keyword for meta on linux/mac, ctrl on windows
142
+ const defaultModifier="metactrl";
143
+ // get focus key value
144
+ let focusKey=input.getAttribute("data-focus-key");if(focusKey.length>1){console.error(`Provided focus key "${focusKey}" is more than one character. Using first character only.`);focusKey=focusKey.toString()[0]}
145
+ // get focus modifier value
146
+ let modifierSymbol;let modifierKey=defaultModifier;const modifierAttr={default:input.getAttribute("data-focus-modifier")||defaultModifier,linux:input.getAttribute("data-focus-modifier-linux"),mac:input.getAttribute("data-focus-modifier-mac"),windows:input.getAttribute("data-focus-modifier-win")};if(os&&modifierAttr[os])
147
+ // a specific modifier key has been set by the user
148
+ modifierKey=modifierAttr[os];else modifierKey=modifierAttr.default;
149
+ // validate passed in modifier
150
+ const recognizedModifiers=["ctrl","alt","opt","meta","cmd",defaultModifier];if(!recognizedModifiers.includes(modifierKey)){console.error(`Received an unrecognized modifier, "${modifierKey}," defaulting to "${defaultModifier}."`,input);modifierKey=defaultModifier}
151
+ // retrieve modifier symbol
152
+ if(["alt","opt"].includes(modifierKey))modifierSymbol=os==="mac"?"⌥":"⎇";else if(["meta","win","cmd"].includes(modifierKey)||modifierKey===defaultModifier&&os==="mac")if(os==="mac")modifierSymbol="⌘";else if(os==="linux")modifierSymbol="◆";else modifierSymbol="⊞";else if(modifierKey==="ctrl"||modifierKey===defaultModifier&&(os==="windows"||os==="linux"))if(os==="mac")modifierSymbol="⌃";else modifierSymbol="Ctrl";
153
+ // add the shortcut to the cached array, if not a duplicate
154
+ if(shortcuts.some(shortcut=>shortcut.key===focusKey&&shortcut.modifier===modifierKey))console.error(`Duplicate keyboard shortcut "${modifierKey} + ${focusKey}" detected. Only the first input will be focusable using this keyboard shortcut.`,input);
155
+ // set the shortcut indicator/title
156
+ if(input.nodeName==="TEXTAREA"||input.type==="text"||input.type==="number"){
157
+ // create focus indicator for valid inputs
158
+ const indicator=document.createElement("span");indicator.classList.add("focus-key");indicator.innerHTML=`<kbd>${modifierSymbol} ${focusKey.toUpperCase()}</kbd>`;const label=input.nextSibling;insertAfter(indicator,label)}else
159
+ // update the input title
160
+ if(input.getAttribute("title"))input.setAttribute("title",input.getAttribute("title")+` (${modifierSymbol} + ${focusKey})`);else input.setAttribute("title",`Focus with ${modifierSymbol} + ${focusKey}`);return{key:focusKey,modifier:modifierKey,input,os,defaultModifier}};module.exports={shortcutListener,createKeyboardShortcut}
161
+ /***/},
162
+ /***/61(module){let tabGroupCount=0;
163
+ // turns a group of fieldsets into a set of tabs
164
+
165
+ // the markup it enhances is an element with the `tabs` class holding one `<fieldset>` per tab, each titled by its `<legend>`. left alone that is a stack of labelled field groups, which is a perfectly usable form, so a browser without JavaScript still gets everything
166
+
167
+ // form: form element to search for tab groups
168
+ const enhanceTabs=form=>{for(const group of form.querySelectorAll(".tabs:not(.semanticFormsTabsActive)")){const panels=Array.from(group.children).filter(child=>child.nodeName==="FIELDSET");
169
+ // one fieldset is not a set of tabs, and no fieldsets means the class is on the wrong element
170
+ if(panels.length<2){if(panels.length===0)console.error("semantic-forms: Found a .tabs element with no <fieldset> children. Each tab needs to be a <fieldset> with a <legend> naming it.",group);continue}group.classList.add("semanticFormsTabsActive");const groupId=++tabGroupCount;const tabList=document.createElement("div");const tabs=[];tabList.classList.add("tabList");tabList.setAttribute("role","tablist");
171
+ // shows one panel and marks its tab as the selected one
172
+ const selectTab=(index,moveFocus)=>{for(const[i,panel]of panels.entries())panel.hidden=i!==index;for(const[i,tab]of tabs.entries()){const selected=i===index;tab.setAttribute("aria-selected",selected?"true":"false");
173
+ // only the selected tab is in the tab order; the arrow keys reach the others
174
+ tab.tabIndex=selected?0:-1}if(moveFocus)tabs[index].focus()};for(const[index,panel]of panels.entries()){const legend=panel.querySelector("legend");const tab=document.createElement("button");tab.type="button";tab.setAttribute("role","tab");tab.id=`semanticFormsTab_${groupId}_${index}`;tab.textContent=legend?legend.textContent:`Tab ${index+1}`;if(!panel.id)panel.id=`semanticFormsTabPanel_${groupId}_${index}`;panel.setAttribute("role","tabpanel");panel.setAttribute("aria-labelledby",tab.id);tab.setAttribute("aria-controls",panel.id);
175
+ // the tab now names the panel, so the legend would be read out twice
176
+ if(legend)legend.hidden=true;tab.addEventListener("click",()=>selectTab(index));tabs.push(tab);tabList.append(tab)}
177
+ // the arrow keys move between tabs, which is what a tablist is expected to do
178
+ tabList.addEventListener("keydown",event=>{const current=tabs.indexOf(document.activeElement);if(current===-1)return;const keys={ArrowRight:(current+1)%tabs.length,ArrowLeft:(current-1+tabs.length)%tabs.length,Home:0,End:tabs.length-1};if(!(event.key in keys))return;event.preventDefault();selectTab(keys[event.key],true)});group.prepend(tabList);selectTab(0)}};module.exports={enhanceTabs}
179
+ /***/},
180
+ /***/90(module,__unused_webpack_exports,__webpack_require__){const{createKeyboardShortcut,shortcutListener}=__webpack_require__(497);const{enhanceInput,handleUndoRedo}=__webpack_require__(866);const{enhanceTabs}=__webpack_require__(61);const{setInkOffset}=__webpack_require__(584);
181
+ // one observer per tree that has been handed to semanticForms, so that a shadow root gets its own without replacing the document's
182
+ const observers=new WeakMap;
183
+ // progressively enhances every semanticForms form in a tree
184
+
185
+ // root: document or shadow root to search; defaults to the main document
186
+ const semanticForms=(root=document)=>{
187
+ // do some feature detection so none of the JS executes if the browser is too old
188
+ if(typeof document.getElementsByClassName!=="function"||typeof document.querySelector!=="function"||!document.body.classList||!window.MutationObserver){console.warn("semantic-forms was loaded into an unsupported browser and will not execute.");return}
189
+ // custom keyboard shortcut listener
190
+ const keyboardShortcuts=[];document.addEventListener("keydown",e=>shortcutListener(e,keyboardShortcuts));
191
+ // progressively enhance form elements that have the semanticForms class
192
+ const forms=root.querySelectorAll("form.semanticForms:not(.semanticFormsActive), table.semanticForms:not(.semanticFormsActive)");for(const form of forms){form.classList.add("semanticFormsActive");if(form.classList.contains("lowFlow"))continue;
193
+ // how far this font's letters sit from the middle of their own line box, which the stylesheet subtracts wherever it centers text. it is measured per form rather than per field, so that a form holding nothing but buttons is corrected too
194
+ setInkOffset(form,form);
195
+ // update each input in the semantic form
196
+ const inputs=Array.from(form.querySelectorAll("input, textarea, select"));for(const input of inputs){enhanceInput(input,form);
197
+ // handle keyboard shortcuts
198
+ if(input.getAttribute("data-focus-key")!==null){const shortcut=createKeyboardShortcut(input,keyboardShortcuts);keyboardShortcuts.push(shortcut)}}
199
+ // done after the inputs so that anything sizing itself measures while it is still on screen
200
+ enhanceTabs(form)}
201
+ // prevents multiple listeners
202
+ document.removeEventListener("keydown",handleUndoRedo);document.addEventListener("keydown",handleUndoRedo);
203
+ // monitor changes to this tree and enhance new semanticForms forms that get added to it
204
+ if(!observers.has(root)){const observer=new window.MutationObserver(mutations=>{let stop=false;for(const mutation of mutations){for(const node of mutation.addedNodes)if(node.nodeName==="FORM"||node?.querySelector?.("form")){semanticForms(root);stop=true}if(stop)break}});
205
+ // a shadow root is observed directly; the document is observed through its body
206
+ observer.observe(root===document?document.body:root,{attributes:false,childList:true,characterData:false,subtree:true});observers.set(root,observer);
207
+ // long standing name for the document's observer, kept for anything already using it
208
+ if(root===document)window.semanticFormsObserver=observer}semanticForms.reinitialize=form=>{
209
+ // with no form given this just rescans for forms that are not active yet
210
+ if(!form)return semanticForms(root);form.classList.remove("semanticFormsActive");
211
+ // the form knows which tree it belongs to, so a form in a shadow root reinitializes there
212
+ semanticForms(form.getRootNode())}};module.exports=semanticForms
140
213
  /***/}
141
214
  /******/};
142
215
  /************************************************************************/
143
216
  /******/ // The module cache
144
- /******/var __webpack_module_cache__={};
217
+ /******/const __webpack_module_cache__={};
145
218
  /******/
146
219
  /******/ // The require function
147
220
  /******/function __webpack_require__(moduleId){
148
221
  /******/ // Check if module is in cache
149
- /******/var cachedModule=__webpack_module_cache__[moduleId];
222
+ /******/const cachedModule=__webpack_module_cache__[moduleId];
150
223
  /******/if(cachedModule!==void 0)
151
224
  /******/return cachedModule.exports;
152
225
  /******/
153
226
  /******/ // Create a new module (and put it into the cache)
154
- /******/var module=__webpack_module_cache__[moduleId]={
227
+ /******/const module=__webpack_module_cache__[moduleId]={
155
228
  /******/ // no module.id needed
156
229
  /******/ // no module.loaded needed
157
230
  /******/exports:{}
@@ -169,7 +242,7 @@ if(lastFocusedInput)if(lastFocusedInput?.parentNode?.querySelector("button.clear
169
242
  /******/ // startup
170
243
  /******/ // Load entry module and return exports
171
244
  /******/ // This entry module is referenced by other modules so it can't be inlined
172
- /******/var __webpack_exports__=__webpack_require__(90);
245
+ /******/let __webpack_exports__=__webpack_require__(90);
173
246
  /******/
174
247
  /******/return __webpack_exports__;
175
248
  /******/})());