├── .gitignore ├── CODEOWNERS ├── custom-elements-manifest.config.js ├── src ├── index.ts ├── auto-check-element-define.ts └── auto-check-element.ts ├── tsconfig.json ├── .github └── workflows │ ├── nodejs.yml │ └── publish.yml ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .eslintrc.json ├── LICENSE ├── web-test-runner.config.js ├── package.json ├── examples └── index.html ├── README.md ├── custom-elements.json └── test └── auto-check.js /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @github/primer-reviewers 2 | -------------------------------------------------------------------------------- /custom-elements-manifest.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | packagejson: true, 3 | globs: ['src/*-element.ts'], 4 | plugins: [], 5 | } 6 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import {AutoCheckElement} from './auto-check-element.js' 2 | 3 | export {AutoCheckElement} 4 | export default AutoCheckElement 5 | export * from './auto-check-element-define.js' 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2020", 4 | "target": "es2017", 5 | "strict": true, 6 | "moduleResolution": "node", 7 | "declaration": true, 8 | "outDir": "dist", 9 | "lib": ["dom", "dom.iterable", "es2020"], 10 | "removeComments": true 11 | }, 12 | "files": ["src/index.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: push 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | permissions: 8 | contents: read 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Use Node.js 18.x 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: 18.x 15 | - name: npm install, build, and test 16 | run: | 17 | npm install 18 | npm run build 19 | npm test 20 | env: 21 | CI: true 22 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | publish-npm: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: read 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 18 17 | registry-url: https://registry.npmjs.org/ 18 | cache: npm 19 | - run: npm ci 20 | - run: npm test 21 | - run: npm version ${TAG_NAME} --git-tag-version=false 22 | env: 23 | TAG_NAME: ${{ github.event.release.tag_name }} 24 | - run: npm whoami; npm --ignore-scripts publish 25 | env: 26 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 27 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/javascript-node/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Node.js version (use -bullseye variants on local arm64/Apple Silicon): 16, 14, 12, 16-bullseye, 14-bullseye, 12-bullseye, 16-buster, 14-buster, 12-buster 4 | ARG VARIANT="16" 5 | FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT} 6 | 7 | # [Optional] Uncomment this section to install additional OS packages. 8 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 9 | # && apt-get -y install --no-install-recommends 10 | 11 | # [Optional] Uncomment if you want to install an additional version of node using nvm 12 | # ARG EXTRA_NODE_VERSION=10 13 | # RUN su node -c "source/usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}" 14 | 15 | # [Optional] Uncomment if you want to install more global node modules 16 | # RUN su node -c "npm install -g " 17 | -------------------------------------------------------------------------------- /src/auto-check-element-define.ts: -------------------------------------------------------------------------------- 1 | import {AutoCheckElement} from './auto-check-element.js' 2 | 3 | const root = (typeof globalThis !== 'undefined' ? globalThis : window) as typeof window 4 | try { 5 | root.AutoCheckElement = AutoCheckElement.define() 6 | } catch (e: unknown) { 7 | if ( 8 | !(root.DOMException && e instanceof DOMException && e.name === 'NotSupportedError') && 9 | !(e instanceof ReferenceError) 10 | ) { 11 | throw e 12 | } 13 | } 14 | 15 | type JSXBase = JSX.IntrinsicElements extends {span: unknown} 16 | ? JSX.IntrinsicElements 17 | : Record> 18 | declare global { 19 | interface Window { 20 | AutoCheckElement: typeof AutoCheckElement 21 | } 22 | interface HTMLElementTagNameMap { 23 | 'auto-check': AutoCheckElement 24 | } 25 | namespace JSX { 26 | interface IntrinsicElements { 27 | ['auto-check']: JSXBase['span'] & Partial> 28 | } 29 | } 30 | } 31 | 32 | export default AutoCheckElement 33 | export * from './auto-check-element.js' 34 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "plugin:github/browser", 5 | "plugin:github/recommended", 6 | "plugin:github/typescript", 7 | "plugin:custom-elements/recommended" 8 | ], 9 | "rules": { 10 | "custom-elements/tag-name-matches-class": [ 11 | "error", 12 | { 13 | "suffix": "Element" 14 | } 15 | ], 16 | "custom-elements/define-tag-after-class-definition": "off", 17 | "custom-elements/no-method-prefixed-with-on": "off", 18 | "custom-elements/expose-class-on-global": "off", 19 | "import/extensions": ["error", "always"], 20 | "import/no-unresolved": "off" 21 | }, 22 | "overrides": [ 23 | { 24 | "files": "src/*-define.ts", 25 | "rules": { 26 | "@typescript-eslint/no-namespace": "off" 27 | } 28 | }, 29 | { 30 | "files": "test/**/*.js", 31 | "rules": { 32 | "github/unescaped-html-literal": "off", 33 | "github/no-inner-html": "off", 34 | "i18n-text/no-en": "off" 35 | }, 36 | "env": { 37 | "mocha": true 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 GitHub, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /web-test-runner.config.js: -------------------------------------------------------------------------------- 1 | import {esbuildPlugin} from '@web/dev-server-esbuild' 2 | import {playwrightLauncher} from '@web/test-runner-playwright' 3 | const browser = product => 4 | playwrightLauncher({ 5 | product, 6 | }) 7 | 8 | export default { 9 | files: ['test/*'], 10 | nodeResolve: true, 11 | plugins: [esbuildPlugin({ts: true, target: 'es2020'})], 12 | browsers: [browser('chromium')], 13 | testFramework: { 14 | config: { 15 | timeout: 500, 16 | }, 17 | }, 18 | 19 | middleware: [ 20 | async ({request, response}, next) => { 21 | const {method, path} = request 22 | if (method === 'POST' || method === 'GET') { 23 | if (path.startsWith('/fail')) { 24 | response.status = 422 25 | // eslint-disable-next-line i18n-text/no-en 26 | response.body = 'This is an error' 27 | } else if (path.startsWith('/success')) { 28 | response.status = 200 29 | // eslint-disable-next-line i18n-text/no-en 30 | response.body = 'This is a warning' 31 | } 32 | } 33 | await next() 34 | }, 35 | ], 36 | } 37 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/javascript-node 3 | { 4 | "name": "Node.js", 5 | "build": { 6 | "dockerfile": "Dockerfile", 7 | // Update 'VARIANT' to pick a Node version: 16, 14, 12. 8 | // Append -bullseye or -buster to pin to an OS version. 9 | // Use -bullseye variants on local arm64/Apple Silicon. 10 | "args": { "VARIANT": "16" } 11 | }, 12 | 13 | // Set *default* container specific settings.json values on container create. 14 | "settings": {}, 15 | 16 | // Add the IDs of extensions you want installed when the container is created. 17 | "extensions": [ 18 | "dbaeumer.vscode-eslint" 19 | ], 20 | 21 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 22 | // "forwardPorts": [], 23 | 24 | // Use 'postCreateCommand' to run commands after the container is created. 25 | // "postCreateCommand": "yarn install", 26 | 27 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 28 | "remoteUser": "node", 29 | "features": { 30 | "git": "latest" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@github/auto-check-element", 3 | "version": "5.2.0", 4 | "description": "An input element that validates its value with a server endpoint.", 5 | "repository": "github/auto-check-element", 6 | "files": [ 7 | "dist" 8 | ], 9 | "main": "dist/bundle.js", 10 | "module": "dist/index.js", 11 | "type": "module", 12 | "types": "dist/index.d.ts", 13 | "exports": { 14 | ".": "./dist/index.js", 15 | "./define": "./dist/index.js", 16 | "./auto-check": "./dist/auto-check-element.js", 17 | "./auto-check/define": "./dist/auto-check-element-define.js" 18 | }, 19 | "scripts": { 20 | "clean": "rm -rf dist/", 21 | "lint": "eslint . --ext .js,.ts && tsc --noEmit", 22 | "lint:fix": "npm run lint -- --fix", 23 | "prebuild": "npm run clean && npm run lint && mkdir dist", 24 | "bundle": "esbuild --bundle dist/index.js --keep-names --outfile=dist/bundle.js --format=esm", 25 | "build": "tsc && npm run bundle && npm run manifest", 26 | "prepublishOnly": "npm run build", 27 | "pretest": "npm run build && npx playwright install --with-deps", 28 | "test": "web-test-runner", 29 | "postpublish": "npm publish --ignore-scripts --@github:registry='https://npm.pkg.github.com'", 30 | "manifest": "custom-elements-manifest analyze" 31 | }, 32 | "keywords": [ 33 | "custom element", 34 | "web component", 35 | "auto-check", 36 | "input" 37 | ], 38 | "license": "MIT", 39 | "prettier": "@github/prettier-config", 40 | "devDependencies": { 41 | "@custom-elements-manifest/analyzer": "^0.8.0", 42 | "@github/prettier-config": "^0.0.6", 43 | "@open-wc/testing": "^3.1.8", 44 | "@web/dev-server-esbuild": "^0.3.6", 45 | "@web/test-runner": "^0.19.0", 46 | "@web/test-runner-playwright": "^0.11.1", 47 | "esbuild": "^0.25.0", 48 | "eslint": "^8.38.0", 49 | "eslint-plugin-custom-elements": "^0.0.8", 50 | "eslint-plugin-github": "^4.7.0", 51 | "typescript": "^5.0.4" 52 | }, 53 | "eslintIgnore": [ 54 | "dist/" 55 | ], 56 | "dependencies": { 57 | "@github/mini-throttle": "^2.1.0" 58 | }, 59 | "customElements": "custom-elements.json" 60 | } 61 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <auto-check> element 5 | 10 | 11 | 12 |
13 |

auto-check-element

14 |

Simple form

15 | 16 |
17 |

All fields marked with * are required

18 | 19 | 20 | 21 | 22 |

23 |
24 | 25 |
26 | 27 |

Form that has custom validity messages

28 |

Input 422 for an error response.

29 | 30 |
31 |

All fields marked with * are required

32 | 33 | 34 | 35 | 36 |

37 |
38 | 39 |
40 |
41 | 42 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # <auto-check> element 2 | 3 | An input element that validates its value against a server endpoint. 4 | 5 | ## Installation 6 | 7 | ``` 8 | $ npm install --save @github/auto-check-element 9 | ``` 10 | 11 | ## Usage 12 | 13 | ### Script 14 | 15 | Import as a modules: 16 | 17 | ```js 18 | import '@github/auto-check-element' 19 | ``` 20 | 21 | With a script tag: 22 | 23 | ```html 24 |