Compare commits
381 commits
Author | SHA1 | Date | |
---|---|---|---|
5dbea2825a | |||
312971acea | |||
a7ed4d880e | |||
ba27dbb533 | |||
9c6de739c7 | |||
2730d7aad4 | |||
5d17dd8531 | |||
d1f39c6cda | |||
bbdacdfe3b | |||
92eabcbd4a | |||
2a8107f379 | |||
ea45c47d43 | |||
d130beb4e9 | |||
6056cce4e9 | |||
ce590e3785 | |||
30e6dbadda | |||
4da6239a67 | |||
9ac71c4717 | |||
835ea12ac9 | |||
1b67baec25 | |||
624dd797a4 | |||
cbbdbda95b | |||
d796e90955 | |||
06d16cd857 | |||
d26b753f6b | |||
72da548a64 | |||
490e341db5 | |||
76780ccc34 | |||
beb07ebc2c | |||
20d3f5cd55 | |||
f63201d929 | |||
08d4f1fee7 | |||
09eeca0db0 | |||
e2aab31bc0 | |||
c01144ab23 | |||
86694c138e | |||
7c360b44b3 | |||
2099c3dc2e | |||
d25c065210 | |||
eb22895f00 | |||
ac8d27facf | |||
06d4435c82 | |||
bb76a572c0 | |||
6df44b1044 | |||
29097d5457 | |||
c21b998eaa | |||
96e4ac53d9 | |||
770342b7e8 | |||
eef836a037 | |||
8ab8157607 | |||
75caa0b1f3 | |||
3d42067bbd | |||
ce3d1111d8 | |||
7758226d64 | |||
25a7ed0318 | |||
23f0b7cb9d | |||
303d12504c | |||
3b4d7543e5 | |||
781c729e13 | |||
9605f367f9 | |||
1b4d3553ef | |||
f12c62c4b8 | |||
c7976b7acd | |||
4df199e0b9 | |||
0903934848 | |||
64b5df6874 | |||
824eca6f81 | |||
9c9aded8b2 | |||
7e200664c4 | |||
04571e36d3 | |||
11208fe62d | |||
b9acfa773d | |||
6e4903e852 | |||
a8862e78be | |||
bf94386cc5 | |||
0b6973b322 | |||
66c6864267 | |||
391c3e39cb | |||
3d402d4560 | |||
545a442f5c | |||
c989be1491 | |||
3633c4ac0f | |||
859f6262eb | |||
6b16e93977 | |||
7f727480e8 | |||
82b94228f9 | |||
b92823b70c | |||
22f9be0d93 | |||
2222f767a9 | |||
f0ec43fa20 | |||
c4f3a81d41 | |||
fb379408c1 | |||
c26596e9ec | |||
9835eb756a | |||
70397fd89a | |||
59ea75ef14 | |||
8647f36fbe | |||
046afbb614 | |||
de5307ce4d | |||
05a41c5c7d | |||
9e656397cd | |||
20579bad35 | |||
977221650a | |||
e09a342ac8 | |||
e64eface11 | |||
de6c46cdd0 | |||
a1ec9d0de6 | |||
3d921621b7 | |||
46deb9abe5 | |||
6b6fb17bca | |||
b4a6371cc8 | |||
60adc56bbf | |||
ebbea8c3b0 | |||
41f81d22ed | |||
cbaf43232c | |||
825efc6fd0 | |||
68313da412 | |||
3ed027229d | |||
44b4326a52 | |||
b3b7b3f14f | |||
3d099d85fc | |||
9676cff128 | |||
47aba515fb | |||
62e849d1b4 | |||
d116f95c54 | |||
6215ca5e59 | |||
67266a3aae | |||
85f0b5f9be | |||
592c326442 | |||
214b6e80df | |||
9f2661023d | |||
d2516e7de3 | |||
0e8e42e015 | |||
e7b4afd472 | |||
952b3fc146 | |||
760f39dbf3 | |||
573c840de4 | |||
44da784f29 | |||
6be462c80b | |||
e67b8a3e4c | |||
933ea6093f | |||
84b952e115 | |||
f745be449d | |||
8775bacdd9 | |||
fb2310cb56 | |||
68322d9528 | |||
d04031e02f | |||
7dcc155b8f | |||
b5b593a62f | |||
81c44ba8f2 | |||
f30b976424 | |||
ab22347d7b | |||
e6882f3e4b | |||
452c8fa666 | |||
a0fe05f926 | |||
939a73b762 | |||
68f6b8e398 | |||
dddba5b35b | |||
5afe8b5a7f | |||
9e11db8181 | |||
00e53f76ee | |||
5051bf1b10 | |||
034191c78a | |||
c03fcf5d03 | |||
eb17194ff3 | |||
0e44a916e3 | |||
88f63faa0b | |||
172366d6fa | |||
e3cc6eaf1b | |||
1f5192b4ad | |||
2e004015d5 | |||
b080bcda7d | |||
2a03d9be12 | |||
2b8acc5f37 | |||
9504cfcec5 | |||
1c751472b2 | |||
b48395ce36 | |||
a2485392a5 | |||
50fae125ed | |||
264a0cb486 | |||
92d5e49fb6 | |||
64407174e3 | |||
dbd15d7823 | |||
99f945bc03 | |||
312569a734 | |||
15d54c7d34 | |||
ef2c70fb7a | |||
69582349bb | |||
bef6743c3b | |||
472e0dff39 | |||
7887c05249 | |||
9bb0c628b2 | |||
a35c8b9009 | |||
1dbab0f29e | |||
e83f40956b | |||
dc7cf42e90 | |||
4c6acb5de2 | |||
7e38f83b9e | |||
71e64e0f52 | |||
4b9dd1efe3 | |||
4acd6d6ca8 | |||
6848970fd9 | |||
00bf028904 | |||
1285602b2f | |||
8782564ddf | |||
4de6e677d1 | |||
2fca709814 | |||
ffc32df462 | |||
f597bc9aff | |||
bc8a044ab1 | |||
31ef5bb065 | |||
7de0887e7d | |||
4e8842d013 | |||
b8074733c9 | |||
98206e899d | |||
659c3545fb | |||
97f91c240c | |||
7022c238fd | |||
bbeb556a48 | |||
bb0736e8fc | |||
b8f5bd1680 | |||
6c1e02fa82 | |||
f872caf1f8 | |||
585859f4cd | |||
e7d775e2ae | |||
5cf226f166 | |||
37db45e651 | |||
57807e88f6 | |||
589578f420 | |||
39b6eed395 | |||
061219cb00 | |||
62ccd923ff | |||
43e670d02d | |||
0829899284 | |||
7540d39f95 | |||
67382a3f31 | |||
899e4b16bb | |||
63e5b51683 | |||
3c05016920 | |||
0580a0433f | |||
fee575d6d9 | |||
b08a5412f9 | |||
f32995367b | |||
201b3c8ada | |||
9c021408fa | |||
aceb838988 | |||
03a45094b7 | |||
92680c0dc0 | |||
da87fa07cf | |||
2247eff08a | |||
5018e4a7d4 | |||
cc32284e8a | |||
b1005061ff | |||
6486bbbd6d | |||
f9f63e7aba | |||
5c17250e20 | |||
fc9bca2ece | |||
2fa92520ef | |||
bbbc31594c | |||
56845e3897 | |||
9bebf2e99e | |||
4d1c3cd2ae | |||
e8b96b0a6e | |||
879c97f64c | |||
5d4d3be1b5 | |||
a99547c2f4 | |||
a846534ffb | |||
efaf8f8aae | |||
c424ae2f3b | |||
22e1884ad4 | |||
0cf05f4eff | |||
31f9d33327 | |||
8540d5aabd | |||
55b356ec69 | |||
ba09fb00e6 | |||
23e5e7674f | |||
7091daa0d1 | |||
71a3131d3c | |||
caed692440 | |||
c36f76460c | |||
5c9dfdf2db | |||
2f873167f6 | |||
437651411f | |||
6c3bad777d | |||
d02cdffcdb | |||
dc9e7eb44d | |||
5c30a1f0de | |||
48b74a91bc | |||
9c001487ba | |||
826384b9d5 | |||
16e16a181c | |||
490a2bb37b | |||
35d8b6f603 | |||
24d6aea68f | |||
c3e46e55aa | |||
bded79386f | |||
367fee6885 | |||
3182c7f2c2 | |||
28f36bf6f5 | |||
3431d03ef0 | |||
cd4454201b | |||
496db95153 | |||
307881a068 | |||
f3c0abef95 | |||
90a92656be | |||
cd165deb3c | |||
6f2bf5770b | |||
feb2a15edc | |||
2292b5282f | |||
d657b17568 | |||
5fe6e18077 | |||
bd674b5bdf | |||
8d11eae895 | |||
c9d86fd826 | |||
0010afa109 | |||
8d1aa239ac | |||
6192ebd5db | |||
b0f3b28ef4 | |||
798b49d565 | |||
139a756ef9 | |||
11e9719bbb | |||
4d87fa6532 | |||
7e4347b183 | |||
bd44abb629 | |||
293eed2091 | |||
3e0246f2f2 | |||
ff08408c84 | |||
2288d47672 | |||
728b570e57 | |||
58a3d66cd3 | |||
d14f1c503f | |||
88a2bc1b7c | |||
5587ec6063 | |||
9a14daedc3 | |||
e060ceaad4 | |||
f6c77fbac0 | |||
7920f20c98 | |||
608358a9f8 | |||
8e6daa64f0 | |||
a45bcdaf49 | |||
ea9e322931 | |||
d5437413a4 | |||
dad2b345cd | |||
4fdf7b8d1d | |||
de71fb7ef4 | |||
013058dd7f | |||
315b2f8f36 | |||
a06988406a | |||
498b7fe70a | |||
0439728374 | |||
2c434feb43 | |||
e39cb73a70 | |||
62bfde18bc | |||
8149db8436 | |||
15082ccd03 | |||
54c026ec61 | |||
4193422cf6 | |||
620bfeae0d | |||
462d8b764c | |||
17e02df269 | |||
e37b051b5a | |||
69ee88ae88 | |||
544763017e | |||
92cfd989ff | |||
b224a96e08 | |||
e07e14bd8f | |||
1f06a32b30 | |||
0f7cbfb6bf | |||
57f16c23ee | |||
2f96c239ff | |||
5b68505b1a | |||
e53ebdda42 | |||
447f53a078 | |||
af4dd13ffe | |||
81b2e23d0d | |||
71662e0e4b | |||
83bc319801 | |||
3ce59432bc | |||
7d3c8daf07 | |||
3319529b98 | |||
60d52a2d3b |
16
.babelrc
|
@ -1,3 +1,17 @@
|
||||||
{
|
{
|
||||||
"presets": ["env", "stage-2"]
|
"presets": [["@babel/preset-env", { "loose": true }]],
|
||||||
|
"env": {
|
||||||
|
"test": {
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"node": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1
.browserslistrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
> 1%
|
4
.codecov.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
coverage:
|
||||||
|
parsers:
|
||||||
|
javascript:
|
||||||
|
enable_partials: yes
|
|
@ -1 +1,3 @@
|
||||||
node_modules/
|
node_modules/
|
||||||
|
types/
|
||||||
|
public/
|
37
.eslintrc
|
@ -1,37 +0,0 @@
|
||||||
{
|
|
||||||
"parser": "babel-eslint",
|
|
||||||
"extends": [
|
|
||||||
"airbnb",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"es6": true,
|
|
||||||
"browser": true,
|
|
||||||
"node": true,
|
|
||||||
"mocha": true
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"describe": true,
|
|
||||||
"it": true,
|
|
||||||
"before": true,
|
|
||||||
"after": true,
|
|
||||||
"beforeEach": true,
|
|
||||||
"afterEach": true
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"import/no-extraneous-dependencies": ["error", {
|
|
||||||
"devDependencies": true
|
|
||||||
}],
|
|
||||||
"no-console": ["warn", { "allow": ["warn", "error"] }],
|
|
||||||
"no-plusplus": "off",
|
|
||||||
"no-unused-expressions": "off",
|
|
||||||
"no-underscore-dangle": "off",
|
|
||||||
"prettier/prettier": ["error", {
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "all"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
123
.eslintrc.json
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
{
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"plugins": ["@typescript-eslint", "prettier", "sort-class-members"],
|
||||||
|
"extends": [
|
||||||
|
"airbnb-base",
|
||||||
|
"airbnb-typescript",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
"plugin:compat/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"browser": true,
|
||||||
|
"mocha": true,
|
||||||
|
"cypress/globals": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json",
|
||||||
|
"ecmaVersion": 2020
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"import/prefer-default-export": "off",
|
||||||
|
"import/no-extraneous-dependencies": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"devDependencies": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-console": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"allow": ["warn", "error"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-plusplus": "off",
|
||||||
|
"no-unused-expressions": "off",
|
||||||
|
"no-underscore-dangle": "off",
|
||||||
|
"consistent-return": "off",
|
||||||
|
"import/no-useless-path-segments": "warn",
|
||||||
|
"prefer-destructuring": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"array": false,
|
||||||
|
"object": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"curly": ["error", "all"],
|
||||||
|
"newline-before-return": "error",
|
||||||
|
"sort-class-members/sort-class-members": [
|
||||||
|
2,
|
||||||
|
{
|
||||||
|
"order": [
|
||||||
|
"[static-properties]",
|
||||||
|
"[static-methods]",
|
||||||
|
"[properties]",
|
||||||
|
"[conventional-private-properties]",
|
||||||
|
"constructor",
|
||||||
|
"[methods]",
|
||||||
|
"[conventional-private-methods]"
|
||||||
|
],
|
||||||
|
"accessorPairPositioning": "getThenSet"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lines-between-class-members": "off",
|
||||||
|
"@typescript-eslint/no-namespace": "off",
|
||||||
|
"react/jsx-filename-extension": [0]
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.test.ts"],
|
||||||
|
"env": {
|
||||||
|
"mocha": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"no-restricted-syntax": "off",
|
||||||
|
"compat/compat": "off",
|
||||||
|
"no-new": "off",
|
||||||
|
"@typescript-eslint/no-empty-function": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
|
"@typescript-eslint/no-unused-expressions": "off",
|
||||||
|
"@typescript-eslint/naming-convention": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"selector": "default",
|
||||||
|
"format": ["camelCase", "PascalCase", "UPPER_CASE"],
|
||||||
|
"leadingUnderscore": "allow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["cypress/**"],
|
||||||
|
"plugins": ["cypress"],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": "warn"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"cypress/globals": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"polyfills": [
|
||||||
|
"Array.from",
|
||||||
|
"Array.prototype.find",
|
||||||
|
"Array.prototype.includes",
|
||||||
|
"Symbol",
|
||||||
|
"Symbol.iterator",
|
||||||
|
"DOMTokenList",
|
||||||
|
"Object.assign",
|
||||||
|
"CustomEvent",
|
||||||
|
"Element.prototype.classList",
|
||||||
|
"Element.prototype.closest",
|
||||||
|
"Element.prototype.dataset"
|
||||||
|
],
|
||||||
|
"import/resolver": {
|
||||||
|
"node": {
|
||||||
|
"extensions": [".js", ".ts"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
.gitattributes
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
## GITATTRIBUTES FOR WEB PROJECTS
|
||||||
|
#
|
||||||
|
# These settings are for any web project.
|
||||||
|
#
|
||||||
|
# Details per file setting:
|
||||||
|
# text These files should be normalized (i.e. convert CRLF to LF).
|
||||||
|
# binary These files are binary and should be left untouched.
|
||||||
|
#
|
||||||
|
# Note that binary is a macro for -text -diff.
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Auto detect
|
||||||
|
## Handle line endings automatically for files detected as
|
||||||
|
## text and leave all files detected as binary untouched.
|
||||||
|
## This will handle all files NOT defined below.
|
||||||
|
* text eol=lf
|
||||||
|
|
||||||
|
# Source code
|
||||||
|
*.css text eol=lf
|
||||||
|
*.html text diff=html eol=lf
|
||||||
|
*.js text eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
*.scss text diff=css eol=lf
|
||||||
|
*.ts text eol=lf
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
*.md text eol=lf
|
||||||
|
*.txt text eol=lf
|
||||||
|
AUTHORS text eol=lf
|
||||||
|
CHANGELOG text eol=lf
|
||||||
|
CHANGES text eol=lf
|
||||||
|
CONTRIBUTING text eol=lf
|
||||||
|
COPYING text eol=lf
|
||||||
|
copyright text eol=lf
|
||||||
|
*COPYRIGHT* text eol=lf
|
||||||
|
INSTALL text eol=lf
|
||||||
|
license text eol=lf
|
||||||
|
LICENSE text eol=lf
|
||||||
|
NEWS text eol=lf
|
||||||
|
readme text eol=lf
|
||||||
|
*README* text eol=lf
|
||||||
|
TODO text eol=lf
|
||||||
|
|
||||||
|
# Linters
|
||||||
|
.eslintrc text eol=lf
|
||||||
|
.stylelintrc text eol=lf
|
||||||
|
|
||||||
|
# Configs
|
||||||
|
.babelrc text eol=lf
|
||||||
|
.browserslistrc text eol=lf
|
||||||
|
.editorconfig text eol=lf
|
||||||
|
.env text eol=lf
|
||||||
|
.gitattributes text eol=lf
|
||||||
|
.gitconfig text eol=lf
|
||||||
|
package-lock.json text -diff eol=lf
|
||||||
|
*.npmignore text eol=lf
|
||||||
|
*.yaml text eol=lf
|
||||||
|
*.yml text eol=lf
|
||||||
|
browserslist text eol=lf
|
||||||
|
|
||||||
|
# Graphics
|
||||||
|
# SVG treated as an asset (binary) by default.
|
||||||
|
*.svg text eol=lf
|
||||||
|
*.png binary
|
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: feature request
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
28
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--- Describe your changes in detail -->
|
||||||
|
<!--- Why is this change required? What problem does it solve? -->
|
||||||
|
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||||
|
|
||||||
|
## Screenshots (if appropriate)
|
||||||
|
|
||||||
|
## Types of changes
|
||||||
|
|
||||||
|
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
||||||
|
|
||||||
|
- [ ] Chore (tooling change or documentation change)
|
||||||
|
- [ ] Refactor (non-breaking change which maintains existing functionality)
|
||||||
|
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||||
|
- [ ] New feature (non-breaking change which adds functionality)
|
||||||
|
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||||
|
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||||
|
|
||||||
|
- [ ] My code follows the code style of this project.
|
||||||
|
- [ ] I have added new tests for the bug I fixed/the new feature I added.
|
||||||
|
- [ ] I have modified existing tests for the bug I fixed/the new feature I added.
|
||||||
|
- [ ] My change requires a change to the documentation.
|
||||||
|
- [ ] I have updated the documentation accordingly.
|
BIN
.github/actions-scripts/__snapshots__/chrome-win32.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
.github/actions-scripts/__snapshots__/edge-win32.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
.github/actions-scripts/__snapshots__/firefox-darwin.png
vendored
Executable file
After Width: | Height: | Size: 47 KiB |
BIN
.github/actions-scripts/__snapshots__/firefox-win32.png
vendored
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
.github/actions-scripts/__snapshots__/ie-win32.png
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
.github/actions-scripts/__snapshots__/puppeteer-darwin.png
vendored
Executable file
After Width: | Height: | Size: 297 KiB |
BIN
.github/actions-scripts/__snapshots__/safari-darwin.png
vendored
Normal file
After Width: | Height: | Size: 284 KiB |
14
.github/actions-scripts/polyfills-sync.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
const { readFileSync } = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const readme = readFileSync(path.resolve(__dirname, '../../README.md'), 'utf8');
|
||||||
|
|
||||||
|
const polyfillsFromDocs = /^```polyfills\s*\n([^`]+)\n^```/m
|
||||||
|
.exec(readme)[1]
|
||||||
|
.split('\n')
|
||||||
|
.map(v => v.trim())
|
||||||
|
.sort();
|
||||||
|
// @ts-ignore
|
||||||
|
const polyfillsFromSettings = require('../../.eslintrc.json').settings.polyfills.sort();
|
||||||
|
assert.deepStrictEqual(polyfillsFromDocs, polyfillsFromSettings);
|
92
.github/actions-scripts/puppeteer.js
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
const { readFileSync, writeFileSync, mkdirSync } = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { once } = require('events');
|
||||||
|
|
||||||
|
const puppeteer = require('puppeteer');
|
||||||
|
const pixelmatch = require('pixelmatch');
|
||||||
|
const { PNG } = require('pngjs');
|
||||||
|
|
||||||
|
const server = require('../../server');
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
const browser = await puppeteer.launch();
|
||||||
|
const page = await browser.newPage();
|
||||||
|
const artifactsPath = 'screenshot';
|
||||||
|
const snapshotName = `puppeteer-${process.platform}.png`;
|
||||||
|
let error;
|
||||||
|
let pixelDifference;
|
||||||
|
let diff;
|
||||||
|
|
||||||
|
if (!server.listening) await once(server, 'listening');
|
||||||
|
|
||||||
|
try {
|
||||||
|
page.on('console', msg => {
|
||||||
|
if (msg.type() === 'error') throw new Error(msg.text());
|
||||||
|
});
|
||||||
|
page.on('pageerror', err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.goto(`http://127.0.0.1:${server.address().port}`, {
|
||||||
|
waitUntil: 'networkidle2',
|
||||||
|
});
|
||||||
|
await page.setViewport({ width: 640, height: 1000 });
|
||||||
|
await page.waitForTimeout(500); // Wait for resize to complete
|
||||||
|
await page.click('label[for="choices-single-custom-templates"]');
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
await page.keyboard.press('ArrowDown');
|
||||||
|
|
||||||
|
mkdirSync(artifactsPath, { recursive: true });
|
||||||
|
const imageBuffer = await page.screenshot({
|
||||||
|
path: path.join(artifactsPath, snapshotName),
|
||||||
|
fullPage: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// compare with snapshot
|
||||||
|
const screenshot = PNG.sync.read(imageBuffer);
|
||||||
|
const snapshot = PNG.sync.read(
|
||||||
|
readFileSync(path.resolve(__dirname, `./__snapshots__/${snapshotName}`)),
|
||||||
|
);
|
||||||
|
const { width, height } = screenshot;
|
||||||
|
diff = new PNG({ width, height });
|
||||||
|
pixelDifference = pixelmatch(
|
||||||
|
screenshot.data,
|
||||||
|
snapshot.data,
|
||||||
|
diff.data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
{
|
||||||
|
threshold: 0.6,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
error = err;
|
||||||
|
} finally {
|
||||||
|
if (diff) {
|
||||||
|
writeFileSync(path.join(artifactsPath, 'diff-' + snapshotName), PNG.sync.write(diff));
|
||||||
|
}
|
||||||
|
await Promise.all([
|
||||||
|
browser.close(),
|
||||||
|
new Promise(resolve => server.close(resolve)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelDifference > 200) {
|
||||||
|
console.error(
|
||||||
|
`Snapshot is different from screenshot by ${pixelDifference} pixels`,
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (error) process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('unhandledRejection', err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
process.once('uncaughtException', err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
setImmediate(test);
|
155
.github/actions-scripts/selenium.js
vendored
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
const path = require('path');
|
||||||
|
const { readFileSync, writeFileSync, mkdirSync } = require('fs');
|
||||||
|
const { once } = require('events');
|
||||||
|
|
||||||
|
const pixelmatch = require('pixelmatch');
|
||||||
|
const { PNG } = require('pngjs');
|
||||||
|
const {
|
||||||
|
Builder,
|
||||||
|
By,
|
||||||
|
Key,
|
||||||
|
until,
|
||||||
|
Capabilities,
|
||||||
|
logging,
|
||||||
|
} = require('selenium-webdriver');
|
||||||
|
|
||||||
|
const server = require('../../server');
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
let pixelDifference;
|
||||||
|
let error;
|
||||||
|
|
||||||
|
let capabilities;
|
||||||
|
switch (process.env.BROWSER) {
|
||||||
|
case 'ie':
|
||||||
|
capabilities = Capabilities.ie();
|
||||||
|
capabilities.set('ignoreProtectedModeSettings', true);
|
||||||
|
capabilities.set('ignoreZoomSetting', true);
|
||||||
|
capabilities.set('ie.options', {
|
||||||
|
enableFullPageScreenshot: true,
|
||||||
|
ensureCleanSession: true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'edge':
|
||||||
|
capabilities = Capabilities.edge();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'safari':
|
||||||
|
capabilities = Capabilities.safari();
|
||||||
|
capabilities.set('safari.options', { technologyPreview: false });
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'firefox': {
|
||||||
|
capabilities = Capabilities.firefox().setLoggingPrefs({ browser: 'ALL' });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'chrome': {
|
||||||
|
capabilities = Capabilities.chrome().setLoggingPrefs({ browser: 'ALL' });
|
||||||
|
capabilities.set('chromeOptions', {
|
||||||
|
args: ['--headless', '--no-sandbox', '--disable-gpu'],
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let driver = await new Builder().withCapabilities(capabilities).build();
|
||||||
|
|
||||||
|
if (!server.listening) await once(server, 'listening');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await driver.get(`http://127.0.0.1:${server.address().port}`);
|
||||||
|
|
||||||
|
// wait for last choice to init
|
||||||
|
await driver.wait(
|
||||||
|
until.elementLocated(By.css('#reset-multiple ~ .choices__list')),
|
||||||
|
10000,
|
||||||
|
'waiting for all Choices instances to init',
|
||||||
|
);
|
||||||
|
|
||||||
|
// Resize window
|
||||||
|
await driver
|
||||||
|
.manage()
|
||||||
|
.window()
|
||||||
|
.maximize();
|
||||||
|
await driver
|
||||||
|
.manage()
|
||||||
|
.window()
|
||||||
|
// magic numbers here to make sure all demo page are fit inside
|
||||||
|
.setRect({ x: 0, y: 0, width: 630, height: 4000 });
|
||||||
|
|
||||||
|
// and click on press space on it, so it should open choices
|
||||||
|
await driver
|
||||||
|
.findElement(By.css('#reset-multiple ~ .choices__list button'))
|
||||||
|
.sendKeys(Key.SPACE);
|
||||||
|
await driver.sleep(1000);
|
||||||
|
|
||||||
|
// take screenshot
|
||||||
|
const image = await driver.takeScreenshot();
|
||||||
|
const imageBuffer = Buffer.from(image, 'base64');
|
||||||
|
|
||||||
|
const snapshotName = `${process.env.BROWSER}-${process.platform}.png`;
|
||||||
|
const artifactsPath = 'screenshot';
|
||||||
|
mkdirSync(artifactsPath, { recursive: true });
|
||||||
|
|
||||||
|
writeFileSync(path.join(artifactsPath, snapshotName), imageBuffer);
|
||||||
|
|
||||||
|
// compare with snapshot
|
||||||
|
const screenshot = PNG.sync.read(imageBuffer);
|
||||||
|
const snapshot = PNG.sync.read(
|
||||||
|
readFileSync(path.resolve(__dirname, `./__snapshots__/${snapshotName}`)),
|
||||||
|
);
|
||||||
|
const { width, height } = screenshot;
|
||||||
|
const diff = new PNG({ width, height });
|
||||||
|
pixelDifference = pixelmatch(
|
||||||
|
screenshot.data,
|
||||||
|
snapshot.data,
|
||||||
|
diff.data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
{
|
||||||
|
threshold: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
writeFileSync(path.join(artifactsPath, 'diff.png'), PNG.sync.write(diff));
|
||||||
|
|
||||||
|
// getting console logs
|
||||||
|
// ensure no errors in console (only supported in Chrome currently)
|
||||||
|
if (process.env.BROWSER === 'chrome') {
|
||||||
|
const entries = await driver
|
||||||
|
.manage()
|
||||||
|
.logs()
|
||||||
|
.get(logging.Type.BROWSER);
|
||||||
|
if (
|
||||||
|
Array.isArray(entries) &&
|
||||||
|
entries.some(entry => entry.level.name_ === 'SEVERE')
|
||||||
|
)
|
||||||
|
throw new Error(JSON.stringify(entries));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
error = err;
|
||||||
|
} finally {
|
||||||
|
await Promise.all([
|
||||||
|
driver.quit(),
|
||||||
|
new Promise(resolve => server.close(resolve)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
if (pixelDifference > 200) {
|
||||||
|
console.error(
|
||||||
|
`Snapshot is different from screenshot by ${pixelDifference} pixels`,
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (error) process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.on('unhandledRejection', err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
process.once('uncaughtException', err => {
|
||||||
|
console.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
setImmediate(test);
|
29
.github/release-drafter.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name-template: 'Draft (next release)'
|
||||||
|
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||||
|
sort-direction: descending
|
||||||
|
exclude-labels:
|
||||||
|
- 'skip-changelog'
|
||||||
|
- 'release'
|
||||||
|
categories:
|
||||||
|
- title: '🚨 Breaking changes'
|
||||||
|
labels:
|
||||||
|
- 'breaking change'
|
||||||
|
- title: '🚀 Features'
|
||||||
|
labels:
|
||||||
|
- 'feature'
|
||||||
|
- 'enhancement'
|
||||||
|
- title: '🐛 Bug Fixes'
|
||||||
|
labels:
|
||||||
|
- 'bugfix'
|
||||||
|
- title: '🔧 Maintenance'
|
||||||
|
labels:
|
||||||
|
- 'chore'
|
||||||
|
- 'housekeeping'
|
||||||
|
- 'refactor'
|
||||||
|
- 'documentation'
|
||||||
|
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||||
|
template: |
|
||||||
|
# Changes
|
||||||
|
$CHANGES
|
||||||
|
# Contributors
|
||||||
|
$CONTRIBUTORS
|
131
.github/workflows/browsers.yml
vendored
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
name: Browsers
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- '.browserslistrc'
|
||||||
|
- '.babelrc'
|
||||||
|
- 'webpack.config.*'
|
||||||
|
- 'public/index.html'
|
||||||
|
- '.github/actions-scripts/__snapshots__/**'
|
||||||
|
- '.github/workflows/browsers.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
selenium:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, macos-latest]
|
||||||
|
browser: [edge, firefox, safari, chrome]
|
||||||
|
exclude:
|
||||||
|
- os: windows-latest
|
||||||
|
browser: safari
|
||||||
|
- os: macos-latest
|
||||||
|
browser: edge
|
||||||
|
- os: macos-latest
|
||||||
|
browser: chrome
|
||||||
|
# Safari workaround is not working in Catalina
|
||||||
|
- browser: safari
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: Dump GitHub context
|
||||||
|
env:
|
||||||
|
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||||
|
run: echo "$GITHUB_CONTEXT"
|
||||||
|
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.OS }}-build-${{ matrix.browser }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.OS }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.OS }}-build-
|
||||||
|
${{ runner.OS }}-
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
|
# install drivers
|
||||||
|
- name: Enable Safari Driver
|
||||||
|
run: |
|
||||||
|
# Workaround for `sudo safardriver --enable` not working:
|
||||||
|
# https://github.com/web-platform-tests/wpt/issues/19845
|
||||||
|
# https://github.com/web-platform-tests/wpt/blob/master/tools/ci/azure/install_safari.yml
|
||||||
|
mkdir -p ~/Library/WebDriver/
|
||||||
|
curl https://raw.githubusercontent.com/web-platform-tests/wpt/master/tools/ci/azure/com.apple.Safari.plist -o ~/Library/WebDriver/com.apple.Safari.plist
|
||||||
|
defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1
|
||||||
|
# sudo safaridriver --enable
|
||||||
|
if: matrix.browser == 'safari'
|
||||||
|
|
||||||
|
- run: |
|
||||||
|
brew install --cask firefox
|
||||||
|
brew install geckodriver
|
||||||
|
if: matrix.browser == 'firefox' && matrix.os == 'macos-latest'
|
||||||
|
|
||||||
|
- run: echo "$env:GeckoWebDriver" >> $GITHUB_PATH
|
||||||
|
if: matrix.browser == 'firefox' && matrix.os == 'windows-latest'
|
||||||
|
|
||||||
|
- run: echo "$env:EdgeWebDriver" >> $GITHUB_PATH
|
||||||
|
if: matrix.browser == 'edge' && matrix.os == 'windows-latest'
|
||||||
|
|
||||||
|
- run: echo "$env:ChromeWebDriver" >> $GITHUB_PATH
|
||||||
|
if: matrix.browser == 'chrome' && matrix.os == 'windows-latest'
|
||||||
|
|
||||||
|
- run: npm i --no-optional --no-audit selenium-webdriver pixelmatch pngjs
|
||||||
|
- run: node .github/actions-scripts/selenium.js
|
||||||
|
env:
|
||||||
|
BROWSER: ${{ matrix.browser }}
|
||||||
|
PORT: 0
|
||||||
|
NODE_ENV: production # prevent watching
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: screenshot-${{ matrix.browser }}-${{ matrix.os }}
|
||||||
|
path: screenshot
|
||||||
|
|
||||||
|
puppeteer:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.OS }}-build-puppeteer
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.OS }}-build-puppeteer
|
||||||
|
- run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
- run: npm i --no-optional --no-audit puppeteer pixelmatch pngjs
|
||||||
|
- run: node .github/actions-scripts/puppeteer.js
|
||||||
|
env:
|
||||||
|
PORT: 0
|
||||||
|
NODE_ENV: production # prevent watching
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: screenshot-puppeteer-darwin
|
||||||
|
path: screenshot
|
60
.github/workflows/build-and-test.yml
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
name: Build and test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Build and run all tests
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
npx bundlesize
|
||||||
|
npm run test:unit:coverage
|
||||||
|
npm run test:e2e
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
CI_REPO_NAME: ${{ github.event.repository.name }}
|
||||||
|
CI_REPO_OWNER: ${{ github.event.organization.login }}
|
||||||
|
CI_COMMIT_SHA: ${{ github.sha }}
|
||||||
|
GIT_COMMIT: ${{ github.sha }}
|
||||||
|
CI_BRANCH: ${{ github.head_ref }}
|
||||||
|
BUNDLESIZE_GITHUB_TOKEN: ${{secrets.BUNDLESIZE_GITHUB_TOKEN}}
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
##
|
||||||
|
## Disabling for now. There does not appear to be a secure way to do this
|
||||||
|
## with protected branches. See discussion:
|
||||||
|
## https://github.community/t/how-to-push-to-protected-branches-in-a-github-action/16101
|
||||||
|
##
|
||||||
|
# - name: Commit built files
|
||||||
|
# run: |
|
||||||
|
# git config --local user.email "action@github.com"
|
||||||
|
# git config --local user.name "GitHub Action"
|
||||||
|
# git commit -m "Update build files 🏗" -a || echo "No changes to commit" && exit 0
|
||||||
|
# - name: Push changes
|
||||||
|
# uses: ad-m/github-push-action@master
|
||||||
|
# with:
|
||||||
|
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
run: bash <(curl -s https://codecov.io/bash)
|
||||||
|
-f ./coverage/lcov.info
|
||||||
|
-B ${{ github.head_ref }}
|
||||||
|
-C ${{ github.sha }}
|
||||||
|
-Z || echo 'Codecov upload failed'
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
GITLAB_CI: true # pretend we are GitLab CI, while Codecov adding support for Github Actions
|
||||||
|
CODECOV_ENV: github-action
|
||||||
|
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
|
42
.github/workflows/bundlesize.yml
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
name: Bundle size checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/scripts/**'
|
||||||
|
- 'src/styles/**'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- '.browserslistrc'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
measure:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Install dependencies and build
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
|
# we don't need to build here, as even minized assets expected to be commited
|
||||||
|
|
||||||
|
- run: npx bundlesize
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
BUNDLESIZE_GITHUB_TOKEN: ${{secrets.BUNDLESIZE_GITHUB_TOKEN}}
|
||||||
|
CI_REPO_NAME: ${{ github.event.repository.name }}
|
||||||
|
CI_REPO_OWNER: ${{ github.event.organization.login }}
|
||||||
|
CI_COMMIT_SHA: ${{ github.event.after }}
|
||||||
|
GIT_COMMIT: ${{ github.event.after }}
|
||||||
|
CI_BRANCH: ${{ github.head_ref }}
|
||||||
|
FORCE_COLOR: 2
|
32
.github/workflows/deploy-pages.yml
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
name: Deploy Pages
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy-gh-pages:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
registry-url: https://registry.npmjs.org/
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
rm -rf public/test
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
- name: Deploy
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PUBLISH_BRANCH: gh-pages
|
||||||
|
PUBLISH_DIR: ./public
|
24
.github/workflows/deployment.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
name: Publish to npm
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-npm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
registry-url: https://registry.npmjs.org/
|
||||||
|
- run: npm ci
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
- run: npm publish
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
71
.github/workflows/e2e-tests.yml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: End-to-end tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- 'package-lock.json'
|
||||||
|
- '.browserslistrc'
|
||||||
|
- '.babelrc'
|
||||||
|
- 'webpack.config.*'
|
||||||
|
- 'public/test/**'
|
||||||
|
- 'cypress/**'
|
||||||
|
- '.github/workflows/e2e-tests.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-e2e:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
TERM: xterm-256color
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18.x
|
||||||
|
|
||||||
|
- name: Cache node modules
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.OS }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.OS }}-build-
|
||||||
|
${{ runner.OS }}-
|
||||||
|
|
||||||
|
- name: Get Cypress info
|
||||||
|
id: cypress-info
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=version::$(jq -r .devDependencies.cypress ./package.json)
|
||||||
|
echo ::set-output name=cache::$(npx cypress cache path)
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
- name: Cache Cypress cache
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ${{ steps.cypress-info.outputs.cache }}
|
||||||
|
key: ${{ runner.OS }}-cypress-${{ steps.cypress-info.outputs.version }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.OS }}-cypress-${{ steps.cypress-info.outputs.version }}
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
env:
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
|
- name: run Cypress (with or without recording)
|
||||||
|
# if we have ran out of free Cypress recordings, run Cypress with recording switched off
|
||||||
|
run: npm exec -- run-p --race start cypress:ci || npm exec -- run-p --race start cypress:run
|
||||||
|
env:
|
||||||
|
NODE_ENV: production # prevent watching
|
||||||
|
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
||||||
|
DEBUG: commit-info,cypress:server:record
|
||||||
|
# https://docs.cypress.io/guides/guides/continuous-integration.html#Environment-variables
|
||||||
|
COMMIT_INFO_BRANCH: ${{ github.head_ref }}
|
||||||
|
COMMIT_INFO_AUTHOR: ${{ github.event.sender.login }}
|
||||||
|
COMMIT_INFO_SHA: ${{ github.event.after }}
|
41
.github/workflows/lint.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
name: Code linting
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/scripts/**'
|
||||||
|
- 'src/styles/**'
|
||||||
|
- package-lock.json
|
||||||
|
- '.browserslistrc'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
|
- name: run eslint
|
||||||
|
run: npm run lint:js
|
||||||
|
|
||||||
|
## Can't use same eslint config for TypeScript and JavaScript
|
||||||
|
## TypeScript rules cause rule definition not found errors
|
||||||
|
## Can be re-enabled if this is resolved: https://github.com/eslint/eslint/issues/14851
|
||||||
|
# - name: Lint JS bundle
|
||||||
|
# run: |
|
||||||
|
# npm run js:build
|
||||||
|
# npx eslint --no-ignore ./public/assets/scripts/*.js
|
||||||
|
|
||||||
|
- name: run stylelint
|
||||||
|
run: npm run lint:scss
|
23
.github/workflows/polyfills-sync.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
name: Polyfills documentation
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'README.md'
|
||||||
|
- '.browserslistrc'
|
||||||
|
- '.eslintrc.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sync:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Check Polyfills documentation and settings sync
|
||||||
|
run: node .github/actions-scripts/polyfills-sync.js
|
14
.github/workflows/release-drafter.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
name: Release drafter
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-draft-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: release-drafter/release-drafter@v5
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
42
.github/workflows/unit-tests.yml
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
name: Unit tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'src/scripts/**'
|
||||||
|
- package-lock.json
|
||||||
|
- '.browserslistrc'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-unit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm install --no-optional --no-audit --ignore-scripts
|
||||||
|
env:
|
||||||
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
|
- run: npm run test:unit:coverage
|
||||||
|
env:
|
||||||
|
FORCE_COLOR: 2
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
run: bash <(curl -s https://codecov.io/bash)
|
||||||
|
-f ./coverage/lcov.info
|
||||||
|
-B ${{ github.head_ref }}
|
||||||
|
-C ${{ github.sha }}
|
||||||
|
-Z || echo 'Codecov upload failed'
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
GITLAB_CI: true # pretend we are GitLab CI, while Codecov adding support for Github Actions
|
||||||
|
CODECOV_ENV: github-action
|
||||||
|
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
|
3
.gitignore
vendored
|
@ -1,10 +1,7 @@
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.gitignore
|
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
|
||||||
package-lock.json
|
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
tests/reports
|
tests/reports
|
||||||
|
|
6
.huskyrc
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"skipCI": true,
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
}
|
8
.mocharc.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require:
|
||||||
|
- 'ts-node/register'
|
||||||
|
- './config/jsdom.js'
|
||||||
|
exit: true
|
||||||
|
spec: src/**/**/*.test.ts
|
||||||
|
extension:
|
||||||
|
- ts
|
||||||
|
- js
|
20
.prettierrc.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"endOfLine": "lf",
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.svg"],
|
||||||
|
"options": {
|
||||||
|
"parser": "html",
|
||||||
|
"htmlWhitespaceSensitivity": "ignore"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["public/*.html"],
|
||||||
|
"options": {
|
||||||
|
"trailingComma": "es5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
.stylelintrc.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"extends": "stylelint-config-standard-scss",
|
||||||
|
"rules": {
|
||||||
|
"declaration-block-no-redundant-longhand-properties": null
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
language: node_js
|
|
||||||
node_js:
|
|
||||||
- "8"
|
|
||||||
before_install:
|
|
||||||
- '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28'
|
|
||||||
- npm install -g npm@latest
|
|
||||||
install:
|
|
||||||
- npm install
|
|
||||||
script: npm run test
|
|
17
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
// we enforce ESLint rules, so, recommend extension
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
// we use prettier, so, recommend extension
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
// we are on GitHub, so, recommend extension
|
||||||
|
"github.vscode-pull-request-github",
|
||||||
|
// needed for our configured debug configuration with Chrome
|
||||||
|
"msjsdiag.debugger-for-chrome"
|
||||||
|
// Mocha recommended - https://mochajs.org/#mocha-sidebar-vs-code,
|
||||||
|
// but it's buggy
|
||||||
|
// "maty.vscode-mocha-sidebar"
|
||||||
|
]
|
||||||
|
}
|
70
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Chrome",
|
||||||
|
"preLaunchTask": "buildAndWatch",
|
||||||
|
"url": "http://localhost:3001",
|
||||||
|
"webRoot": "${workspaceFolder}",
|
||||||
|
"sourceMapPathOverrides": {
|
||||||
|
"webpack://Choices/*": "${workspaceFolder}/*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Mocha Current File",
|
||||||
|
"program": "${workspaceFolder}/node_modules/mocha/bin/mocha",
|
||||||
|
"args": ["-u", "bdd", "--timeout", "999999", "--colors", "${file}"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"internalConsoleOptions": "neverOpen",
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Mocha All",
|
||||||
|
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
||||||
|
"args": ["-u", "bdd", "--timeout", "999999", "--colors"],
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Cypress Current File",
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/cypress",
|
||||||
|
"windows": {
|
||||||
|
"runtimeExecutable": "${workspaceFolder}\\node_modules\\.bin\\cypress.cmd"
|
||||||
|
},
|
||||||
|
"runtimeArgs": [
|
||||||
|
"run",
|
||||||
|
"--headed",
|
||||||
|
"--no-exit",
|
||||||
|
"--browser=electron",
|
||||||
|
"--port",
|
||||||
|
"9898",
|
||||||
|
"--spec"
|
||||||
|
],
|
||||||
|
"protocol": "legacy",
|
||||||
|
"port": 9898,
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"preLaunchTask": "buildAndWatch",
|
||||||
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
|
"timeout": 999999999999999,
|
||||||
|
"autoAttachChildProcesses": false,
|
||||||
|
"env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
// "DEBUG": "cypress:*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
72
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
"eslint.enable": true,
|
||||||
|
// prevent watch task failures on lint errors
|
||||||
|
"eslint.autoFixOnSave": true,
|
||||||
|
// switch off default VSCode formatting rules
|
||||||
|
"javascript.format.enable": false,
|
||||||
|
// Javascript prettier runs via ESLint
|
||||||
|
"prettier.disableLanguages": ["javascript"],
|
||||||
|
"[json]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[html]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[scss]": {
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.formatOnSave": false
|
||||||
|
},
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"public/assets": true,
|
||||||
|
"**/coverage": true
|
||||||
|
},
|
||||||
|
// Mocha Sidebar settings
|
||||||
|
"mocha.env": {
|
||||||
|
"NODE_ENV": "test"
|
||||||
|
},
|
||||||
|
"mocha.files.glob": "src/scripts/**/*.test.js",
|
||||||
|
"mocha.requires": ["@babel/register", "./config/jsdom.js"],
|
||||||
|
// for Windows collaborators
|
||||||
|
"files.eol": "\n",
|
||||||
|
"files.encoding": "utf8",
|
||||||
|
// associations for some files this project is using
|
||||||
|
"files.associations": {
|
||||||
|
".browserslistrc": "gitignore",
|
||||||
|
".huskyrc": "jsonc",
|
||||||
|
".npmrc": "ini"
|
||||||
|
},
|
||||||
|
// We use NPM as package manager
|
||||||
|
"npm.packageManager": "npm",
|
||||||
|
"npm.autoDetect": "on",
|
||||||
|
"npm.fetchOnlinePackageInfo": true,
|
||||||
|
"eslint.packageManager": "npm",
|
||||||
|
"json.schemas": [
|
||||||
|
// Cypress related settings - https://docs.cypress.io/guides/tooling/intelligent-code-completion.html#Features-1
|
||||||
|
{
|
||||||
|
"fileMatch": ["cypress.json"],
|
||||||
|
"url": "https://on.cypress.io/cypress.schema.json"
|
||||||
|
},
|
||||||
|
// Husky config file
|
||||||
|
{
|
||||||
|
"fileMatch": [".huskyrc"],
|
||||||
|
"url": "http://json.schemastore.org/huskyrc"
|
||||||
|
},
|
||||||
|
// Prettier config
|
||||||
|
{
|
||||||
|
"fileMatch": [".prettierrc.json"],
|
||||||
|
"url": "http://json.schemastore.org/prettierrc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"stylelint.validate": [
|
||||||
|
"css",
|
||||||
|
"less",
|
||||||
|
"postcss",
|
||||||
|
"scss"
|
||||||
|
]
|
||||||
|
}
|
87
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
{
|
||||||
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
|
// for the documentation about the tasks.json format
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"label": "buildAndWatch",
|
||||||
|
"script": "js:watch",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"isBackground": true,
|
||||||
|
"presentation": {
|
||||||
|
"echo": true,
|
||||||
|
"reveal": "always",
|
||||||
|
"focus": false,
|
||||||
|
"panel": "dedicated",
|
||||||
|
"showReuseMessage": true,
|
||||||
|
"clear": false
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$eslint-stylish",
|
||||||
|
{
|
||||||
|
"owner": "webpack",
|
||||||
|
"fileLocation": "absolute",
|
||||||
|
"pattern": [
|
||||||
|
{
|
||||||
|
"regexp": "^Module build failed \\(from (\\.+)\\)",
|
||||||
|
"file": 1,
|
||||||
|
"line": 2,
|
||||||
|
"column": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"regexp": "\\s*TS\\d+:\\s*(.*)",
|
||||||
|
"message": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"severity": "error",
|
||||||
|
"source": "webpack",
|
||||||
|
"background": {
|
||||||
|
"activeOnStart": true,
|
||||||
|
"beginsPattern": "^Listening at",
|
||||||
|
"endsPattern": "Compiled successfully\\."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "css:build",
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": ["$node-sass"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "lint",
|
||||||
|
"problemMatcher": ["$eslint-stylish"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "build",
|
||||||
|
"group": "build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "test",
|
||||||
|
"group": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "test:e2e",
|
||||||
|
"group": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "test:unit",
|
||||||
|
"group": "test"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "cypress:open",
|
||||||
|
"isBackground": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,11 +1,12 @@
|
||||||
# Contributions
|
# Contributions
|
||||||
In lieu of a formal styleguide, take care to maintain the existing coding style ensuring there are no linting errors. Add unit tests for any new or changed functionality. Lint and test your code using the npm scripts below:
|
In lieu of a formal styleguide, take care to maintain the existing coding style ensuring there are no linting errors. Add unit tests for any new or changed functionality. Lint and test your code using the npm scripts below:
|
||||||
|
|
||||||
### NPM tasks
|
### NPM tasks
|
||||||
| Task | Usage |
|
| Task | Usage |
|
||||||
| -------------------- | ------------------------------------------------------------ |
|
| -------------------- | ------------------------------------------------------------ |
|
||||||
| `npm run start` | Fire up local server for development |
|
| `npm run start` | Fire up local server for development |
|
||||||
| `npm run test` | Run sequence of tests once |
|
| `npm run test:unit` | Run sequence of unit tests once |
|
||||||
|
| `npm run test:e2e` | Run sequence of integration tests once |
|
||||||
| `npm run test:watch` | Fire up test server and re-test on file change |
|
| `npm run test:watch` | Fire up test server and re-test on file change |
|
||||||
| `npm run js:build` | Compile Choices to an uglified JavaScript file |
|
| `npm run js:build` | Compile Choices to an uglified JavaScript file |
|
||||||
| `npm run css:watch` | Watch SCSS files for changes. On a change, run build process |
|
| `npm run css:watch` | Watch SCSS files for changes. On a change, run build process |
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
|
||||||
const { JSDOM } = require('jsdom');
|
const { JSDOM } = require('jsdom');
|
||||||
|
|
||||||
const jsdom = new JSDOM('<!doctype html><html><body></body></html>');
|
const jsdom = new JSDOM(
|
||||||
|
'<!doctype html><html><head><meta charset="utf-8"></head><body></body></html>',
|
||||||
|
{
|
||||||
|
pretendToBeVisual: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
const { window } = jsdom;
|
const { window } = jsdom;
|
||||||
|
|
||||||
function copyProps(src, target) {
|
function copyProps(src, target) {
|
||||||
|
@ -20,26 +27,6 @@ function ignoreExtensions(extensions = [], returnValue = {}) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockRAF(global) {
|
|
||||||
let callbacksQueue = [];
|
|
||||||
|
|
||||||
global.setInterval(() => {
|
|
||||||
for (let i = 0; i < callbacksQueue.length; i++) {
|
|
||||||
if (callbacksQueue[i] !== false) {
|
|
||||||
callbacksQueue[i].call(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
callbacksQueue = [];
|
|
||||||
}, 1000 / 60);
|
|
||||||
|
|
||||||
global.requestAnimationFrame = callback => callbacksQueue.push(callback) - 1;
|
|
||||||
|
|
||||||
global.cancelAnimationFrame = id => {
|
|
||||||
callbacksQueue[id] = false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
global.window = window;
|
global.window = window;
|
||||||
global.document = window.document;
|
global.document = window.document;
|
||||||
global.navigator = {
|
global.navigator = {
|
||||||
|
@ -48,12 +35,16 @@ global.navigator = {
|
||||||
global.CustomEvent = window.CustomEvent;
|
global.CustomEvent = window.CustomEvent;
|
||||||
global.Element = window.Element;
|
global.Element = window.Element;
|
||||||
global.HTMLElement = window.HTMLElement;
|
global.HTMLElement = window.HTMLElement;
|
||||||
|
global.Option = window.Option;
|
||||||
global.HTMLOptionElement = window.HTMLOptionElement;
|
global.HTMLOptionElement = window.HTMLOptionElement;
|
||||||
global.HTMLOptGroupElement = window.HTMLOptGroupElement;
|
global.HTMLOptGroupElement = window.HTMLOptGroupElement;
|
||||||
|
global.HTMLSelectElement = window.HTMLSelectElement;
|
||||||
|
global.HTMLInputElement = window.HTMLInputElement;
|
||||||
global.DocumentFragment = window.DocumentFragment;
|
global.DocumentFragment = window.DocumentFragment;
|
||||||
|
global.requestAnimationFrame = window.requestAnimationFrame;
|
||||||
|
window.matchMedia = () => true;
|
||||||
|
|
||||||
copyProps(window, global);
|
copyProps(window, global);
|
||||||
mockRAF(global);
|
|
||||||
|
|
||||||
ignoreExtensions(['.scss', '.css']);
|
ignoreExtensions(['.scss', '.css']);
|
||||||
ignoreExtensions(['.jpg', '.png', '.svg'], '');
|
ignoreExtensions(['.jpg', '.png', '.svg'], '');
|
15
cypress.config.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { defineConfig } from 'cypress'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
video: false,
|
||||||
|
projectId: 'n7g5qp',
|
||||||
|
e2e: {
|
||||||
|
// We've imported your old cypress plugins here.
|
||||||
|
// You may want to clean this up later by importing these.
|
||||||
|
setupNodeEvents(on, config) {
|
||||||
|
return require('./cypress/plugins/index.js')(on, config)
|
||||||
|
},
|
||||||
|
baseUrl: 'http://localhost:3001/test',
|
||||||
|
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||||
|
},
|
||||||
|
})
|
1011
cypress/e2e/select-multiple.spec.ts
Normal file
1149
cypress/e2e/select-one.spec.ts
Normal file
431
cypress/e2e/text.spec.ts
Normal file
|
@ -0,0 +1,431 @@
|
||||||
|
describe('Choices - text element', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit('/text', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('scenarios', () => {
|
||||||
|
const textInput = 'testing';
|
||||||
|
|
||||||
|
describe('basic', () => {
|
||||||
|
describe('adding items', () => {
|
||||||
|
it('allows me to input items', () => {
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput)
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($el) => {
|
||||||
|
expect($el).to.contain(textInput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates the value of the original input', () => {
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput)
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__input[hidden]')
|
||||||
|
.should('have.value', textInput);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inputting data', () => {
|
||||||
|
it('shows a dropdown prompt', () => {
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible')
|
||||||
|
.should(($dropdown) => {
|
||||||
|
const dropdownText = $dropdown.text().trim();
|
||||||
|
expect(dropdownText).to.equal(
|
||||||
|
`Press Enter to add "${textInput}"`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('editing items', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
for (let index = 0; index < 3; index++) {
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput)
|
||||||
|
.type('{enter}');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on back space', () => {
|
||||||
|
it('allows me to change my entry', () => {
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{backspace}')
|
||||||
|
.type('-edited')
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.data('value')).to.equal(`${textInput}-edited`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on cmd+a', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{cmd}a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('highlights all items', () => {
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.each(($choice) => {
|
||||||
|
expect($choice.hasClass('is-highlighted')).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on backspace', () => {
|
||||||
|
it('clears all inputted values', () => {
|
||||||
|
// two backspaces are needed as Cypress has an issue where
|
||||||
|
// it will also insert an 'a' character into the text input
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{backspace}{backspace}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=edit-items]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.should('have.length', 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove button', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(`${textInput}`)
|
||||||
|
.type('{enter}');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on click', () => {
|
||||||
|
it('removes respective choice', () => {
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__list--multiple')
|
||||||
|
.children()
|
||||||
|
.should(($items) => {
|
||||||
|
expect($items.length).to.equal(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.find('.choices__button')
|
||||||
|
.focus()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.should(($items) => {
|
||||||
|
expect($items.length).to.equal(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates the value of the original input', () => {
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.find('.choices__button')
|
||||||
|
.focus()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=remove-button]')
|
||||||
|
.find('.choices__input[hidden]')
|
||||||
|
.then(($input) => {
|
||||||
|
expect($input.val()).to.not.contain(textInput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('unique values only', () => {
|
||||||
|
describe('unique values', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=unique-values]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(`${textInput}`)
|
||||||
|
.type('{enter}')
|
||||||
|
.type(`${textInput}`)
|
||||||
|
.type('{enter}');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('only allows me to input unique values', () => {
|
||||||
|
cy.get('[data-test-hook=unique-values]')
|
||||||
|
.find('.choices__list--multiple')
|
||||||
|
.first()
|
||||||
|
.children()
|
||||||
|
.should(($items) => {
|
||||||
|
expect($items.length).to.equal(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inputting a non-unique value', () => {
|
||||||
|
it('displays dropdown prompt', () => {
|
||||||
|
cy.get('[data-test-hook=unique-values]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible')
|
||||||
|
.should(($dropdown) => {
|
||||||
|
const dropdownText = $dropdown.text().trim();
|
||||||
|
expect(dropdownText).to.equal(
|
||||||
|
'Only unique values can be added',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('input limit', () => {
|
||||||
|
const inputLimit = 5;
|
||||||
|
beforeEach(() => {
|
||||||
|
for (let index = 0; index < inputLimit + 1; index++) {
|
||||||
|
cy.get('[data-test-hook=input-limit]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(`${textInput} + ${index}`)
|
||||||
|
.type('{enter}');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not let me input more than 5 choices', () => {
|
||||||
|
cy.get('[data-test-hook=input-limit]')
|
||||||
|
.find('.choices__list--multiple')
|
||||||
|
.first()
|
||||||
|
.children()
|
||||||
|
.should(($items) => {
|
||||||
|
expect($items.length).to.equal(inputLimit);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('reaching input limit', () => {
|
||||||
|
it('displays dropdown prompt', () => {
|
||||||
|
cy.get('[data-test-hook=input-limit]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible')
|
||||||
|
.should(($dropdown) => {
|
||||||
|
const dropdownText = $dropdown.text().trim();
|
||||||
|
expect(dropdownText).to.equal(
|
||||||
|
`Only ${inputLimit} values can be added`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('add item filter', () => {
|
||||||
|
describe('inputting a value that satisfies the filter', () => {
|
||||||
|
const input = 'joe@bloggs.com';
|
||||||
|
|
||||||
|
it('allows me to add choice', () => {
|
||||||
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(input)
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('inputting a value that does not satisfy the regex', () => {
|
||||||
|
it('displays dropdown prompt', () => {
|
||||||
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(`this is not an email address`)
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible')
|
||||||
|
.should(($dropdown) => {
|
||||||
|
const dropdownText = $dropdown.text().trim();
|
||||||
|
expect(dropdownText).to.equal(
|
||||||
|
'Only values matching specific conditions can be added',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('prepend/append', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput)
|
||||||
|
.type('{enter}');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('prepends and appends value to inputted value', () => {
|
||||||
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays just the inputted value to the user', () => {
|
||||||
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text()).to.not.contain(`before-${textInput}-after`);
|
||||||
|
expect($choice.text()).to.contain(textInput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('adding items disabled', () => {
|
||||||
|
it('does not allow me to input data', () => {
|
||||||
|
cy.get('[data-test-hook=adding-items-disabled]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('disabled via attribute', () => {
|
||||||
|
it('does not allow me to input data', () => {
|
||||||
|
cy.get('[data-test-hook=disabled-via-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pre-populated choices', () => {
|
||||||
|
it('pre-populates choices', () => {
|
||||||
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.should(($choices) => {
|
||||||
|
expect($choices.length).to.equal(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Josh Johnson');
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Joe Bloggs');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('placeholder', () => {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
placeholder: true,
|
||||||
|
placeholderValue: 'I am a placeholder',
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
describe('when no value has been inputted', () => {
|
||||||
|
it('displays a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('have.attr', 'placeholder', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('allow html', () => {
|
||||||
|
describe('is undefined', () => {
|
||||||
|
it('logs a deprecation warning', () => {
|
||||||
|
cy.get('@consoleWarn').should(
|
||||||
|
'be.calledOnceWithExactly',
|
||||||
|
'Deprecation warning: allowHTML will default to false in a future release. To render HTML in Choices, you will need to set it to true. Setting allowHTML will suppress this message.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Mason Rogers');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Mason Rogers');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Mason Rogers</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('within form', () => {
|
||||||
|
describe('inputting item', () => {
|
||||||
|
describe('on enter key', () => {
|
||||||
|
it('does not submit form', () => {
|
||||||
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
|
$form.submit(() => {
|
||||||
|
// this will fail the test if the form submits
|
||||||
|
throw new Error('Form submitted');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=within-form]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(textInput)
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=within-form]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.last()
|
||||||
|
.should(($el) => {
|
||||||
|
expect($el).to.contain(textInput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
5
cypress/fixtures/example.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Using fixtures to represent data",
|
||||||
|
"email": "hello@cypress.io",
|
||||||
|
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||||
|
}
|
17
cypress/plugins/index.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example plugins/index.js can be used to load plugins
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off loading
|
||||||
|
// the plugins file with the 'pluginsFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/plugins-guide
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// This function is called when a project is opened or re-opened (e.g. due to
|
||||||
|
// the project's config changing)
|
||||||
|
|
||||||
|
module.exports = (on, config) => {
|
||||||
|
// `on` is used to hook into various events Cypress emits
|
||||||
|
// `config` is the resolved Cypress config
|
||||||
|
};
|
25
cypress/support/commands.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.js shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
20
cypress/support/e2e.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands';
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
17
jsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"checkJs": true,
|
||||||
|
"target": "es2020",
|
||||||
|
"lib": ["esnext", "dom"],
|
||||||
|
"types": ["cypress"],
|
||||||
|
"strict": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
/* Additional Checks */
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"strictNullChecks": false
|
||||||
|
}
|
||||||
|
}
|
14
lint-staged.config.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
'*.js': ['eslint --fix --quiet -f visualstudio', 'git add'],
|
||||||
|
'*.{ts,scss,yaml,yml,md,html,json,babelrc,eslintrc}': [
|
||||||
|
'prettier --write',
|
||||||
|
'git add',
|
||||||
|
],
|
||||||
|
'src/icons/*.svg': [
|
||||||
|
'prettier --write --parser=html --html-whitespace-sensitivity=ignore',
|
||||||
|
'git add',
|
||||||
|
],
|
||||||
|
'.codecov.yml': () =>
|
||||||
|
'curl -f --silent --data-binary @.codecov.yml https://codecov.io/validate',
|
||||||
|
'src/scripts/**/*.js': () => 'npm run test:unit',
|
||||||
|
};
|
23844
package-lock.json
generated
Normal file
160
package.json
|
@ -1,25 +1,33 @@
|
||||||
{
|
{
|
||||||
"name": "choices.js",
|
"name": "choices.js",
|
||||||
"version": "4.0.0",
|
"version": "10.2.0",
|
||||||
"description": "A vanilla JS customisable text input/select box plugin",
|
"description": "A vanilla JS customisable text input/select box plugin",
|
||||||
"main": "./public/assets/scripts/choices.min.js",
|
"main": "./public/assets/scripts/choices.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./public/types/src/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "NODE_ENV=development node server.js",
|
"start": "run-p js:watch css:watch",
|
||||||
"build": "npm run js:build && npm run css:build",
|
"build": "run-p js:build css:build",
|
||||||
"lint": "eslint assets/**/*.js",
|
"lint": "run-p lint:js lint:scss",
|
||||||
"coverage": "nyc npm run test",
|
"lint:js": "eslint src/scripts/**/*.ts",
|
||||||
"test": "mocha --require ./config/test.js --compilers js:babel-core/register \"./src/**/**/**/**/*.test.js\"",
|
"lint:scss": "stylelint src/**/*.scss",
|
||||||
"test:watch": "npm run test -- --watch --inspect=5556",
|
"bundlesize": "bundlesize",
|
||||||
|
"cypress:run": "cypress run --browser chrome",
|
||||||
|
"cypress:open": "cypress open",
|
||||||
|
"cypress:ci": "cypress run --browser chrome --record --group $GITHUB_REF --ci-build-id $GITHUB_SHA",
|
||||||
|
"test": "run-s test:unit test:e2e",
|
||||||
|
"test:unit": "cross-env TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha",
|
||||||
|
"test:unit:watch": "npm run test:unit -- --watch --inspect=5556",
|
||||||
|
"test:unit:coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text --reporter=text-summary mocha",
|
||||||
|
"test:e2e": "run-p --race start cypress:run",
|
||||||
|
"js:watch": "cross-env NODE_ENV=development node server.js",
|
||||||
|
"js:build": "webpack --config webpack.config.prod.js",
|
||||||
"css:watch": "nodemon -e scss -x \"npm run css:build\"",
|
"css:watch": "nodemon -e scss -x \"npm run css:build\"",
|
||||||
"css:build": "npm run css:sass -s && npm run css:prefix -s && npm run css:min -s",
|
"css:build": "run-s css:sass css:prefix css:min",
|
||||||
"css:sass": "node-sass --output-style expanded --include-path scss src/styles/base.scss public/assets/styles/base.css && node-sass --output-style expanded --include-path scss src/styles/choices.scss public/assets/styles/choices.css",
|
"css:sass": "sass -I scss src/styles/base.scss public/assets/styles/base.css && sass -I scss src/styles/choices.scss public/assets/styles/choices.css",
|
||||||
"css:prefix": "postcss --use autoprefixer -b 'last 2 versions' public/assets/styles/*.css -d public/assets/styles",
|
"css:prefix": "postcss public/assets/styles/*.css --use autoprefixer --no-map --env prod --dir public/assets/styles",
|
||||||
"css:min": "csso public/assets/styles/base.css public/assets/styles/base.min.css && csso public/assets/styles/choices.css public/assets/styles/choices.min.css",
|
"css:min": "csso public/assets/styles/base.css --output public/assets/styles/base.min.css && csso public/assets/styles/choices.css --output public/assets/styles/choices.min.css",
|
||||||
"js:build": "concurrently --prefix-colors yellow,green \"webpack --env.minimize --config webpack.config.prod.js\" \"webpack --config webpack.config.prod.js\"",
|
"deploy": "git subtree push --prefix public origin gh-pages",
|
||||||
"version": "node version.js --current $npm_package_version --new $npm_config_newVersion",
|
"prepublishOnly": "npm run build"
|
||||||
"postversion": "npm run js:build",
|
|
||||||
"prepush": "npm run lint && npm run test"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -27,6 +35,14 @@
|
||||||
},
|
},
|
||||||
"author": "Josh Johnson",
|
"author": "Josh Johnson",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"files": [
|
||||||
|
"public/assets/scripts",
|
||||||
|
"public/assets/styles",
|
||||||
|
"public/types",
|
||||||
|
"src",
|
||||||
|
"!src/**/*.test.js",
|
||||||
|
"types"
|
||||||
|
],
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/jshjohnson/Choices/issues"
|
"url": "https://github.com/jshjohnson/Choices/issues"
|
||||||
},
|
},
|
||||||
|
@ -40,55 +56,69 @@
|
||||||
"js"
|
"js"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^6.3.3",
|
"@babel/core": "^7.20.5",
|
||||||
"babel-core": "^6.26.0",
|
"@babel/preset-env": "^7.20.2",
|
||||||
"babel-eslint": "^7.2.3",
|
"@babel/register": "^7.18.9",
|
||||||
"babel-loader": "^7.1.2",
|
"@types/chai": "^4.3.4",
|
||||||
"babel-preset-env": "^1.6.1",
|
"@types/mocha": "^10.0.1",
|
||||||
"babel-preset-stage-2": "^6.24.1",
|
"@types/sinon": "^10.0.13",
|
||||||
"chai": "^4.1.0",
|
"@types/sinon-chai": "^3.2.9",
|
||||||
"concurrently": "^3.1.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
"csso": "^1.8.2",
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
"eslint": "^3.19.0",
|
"autoprefixer": "^10.4.13",
|
||||||
"eslint-config-airbnb": "^15.1.0",
|
"babel-loader": "^9.1.0",
|
||||||
"eslint-config-prettier": "^2.9.0",
|
"bundlesize": "^0.18.1",
|
||||||
"eslint-loader": "^1.5.0",
|
"chai": "^4.3.7",
|
||||||
"eslint-plugin-import": "^2.7.0",
|
"cross-env": "^7.0.3",
|
||||||
"eslint-plugin-jsx-a11y": "^5.1.1",
|
"csso-cli": "^4.0.1",
|
||||||
"eslint-plugin-prettier": "^2.6.0",
|
"cypress": "11.2.0",
|
||||||
"eslint-plugin-react": "^7.2.1",
|
"eslint": "^8.28.0",
|
||||||
"express": "^4.16.3",
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
"husky": "^0.14.3",
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"jsdom": "^11.5.1",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"mocha": "^3.4.2",
|
"eslint-plugin-compat": "4.0.2",
|
||||||
"node-sass": "^3.4.2",
|
"eslint-plugin-cypress": "^2.12.1",
|
||||||
"nodemon": "^1.9.1",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"nyc": "^11.0.3",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"postcss-cli": "^2.5.1",
|
"eslint-plugin-sort-class-members": "^1.15.2",
|
||||||
"prettier": "^1.13.0",
|
"eslint-webpack-plugin": "^3.2.0",
|
||||||
"sinon": "^2.4.0",
|
"express": "^4.18.2",
|
||||||
"webpack": "^3.8.1",
|
"husky": "^8.0.2",
|
||||||
"webpack-dev-middleware": "^2.0.0",
|
"jsdom": "^20.0.3",
|
||||||
"webpack-hot-middleware": "^2.22.2",
|
"lint-staged": "^13.0.4",
|
||||||
"whatwg-fetch": "^1.0.0",
|
"mocha": "^10.1.0",
|
||||||
"wrapper-webpack-plugin": "^0.1.7"
|
"nodemon": "^2.0.20",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"nyc": "^15.1.0",
|
||||||
|
"postcss": "^8.4.19",
|
||||||
|
"postcss-cli": "^10.0.0",
|
||||||
|
"prettier": "^2.8.0",
|
||||||
|
"sass": "^1.56.1",
|
||||||
|
"sinon": "^15.0.0",
|
||||||
|
"sinon-chai": "^3.7.0",
|
||||||
|
"stylelint": "^14.15.0",
|
||||||
|
"stylelint-config-standard": "^29.0.0",
|
||||||
|
"stylelint-config-standard-scss": "^6.1.0",
|
||||||
|
"ts-loader": "^9.4.1",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"typescript": "^4.9.3",
|
||||||
|
"webpack": "^5.75.0",
|
||||||
|
"webpack-cli": "^5.0.0",
|
||||||
|
"webpack-dev-middleware": "^6.0.1",
|
||||||
|
"webpack-hot-middleware": "^2.25.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"classnames": "^2.2.5",
|
"deepmerge": "^4.2.2",
|
||||||
"core-js": "^2.5.6",
|
"fuse.js": "^6.6.2",
|
||||||
"custom-event-polyfill": "^0.3.0",
|
"redux": "^4.2.0"
|
||||||
"deepmerge": "^2.2.1",
|
|
||||||
"fuse.js": "^3.1.0",
|
|
||||||
"opn": "^5.1.0",
|
|
||||||
"redux": "^3.3.1"
|
|
||||||
},
|
},
|
||||||
"npmName": "choices.js",
|
"npmName": "choices.js",
|
||||||
"npmFileMap": [
|
"npmFileMap": [
|
||||||
{
|
{
|
||||||
"basePath": "src",
|
|
||||||
"files": [
|
"files": [
|
||||||
"public/scripts/*",
|
"public/assets/scripts/*",
|
||||||
"public/styles/*",
|
"public/assets/styles/*",
|
||||||
|
"public/types/*",
|
||||||
"src/icons/*"
|
"src/icons/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -100,5 +130,15 @@
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"src/scripts/**/**/*.test.js"
|
"src/scripts/**/**/*.test.js"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"bundlesize": [
|
||||||
|
{
|
||||||
|
"path": "public/assets/scripts/choices.min.js",
|
||||||
|
"maxSize": "25 kB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "public/assets/styles/choices.min.css",
|
||||||
|
"maxSize": "2.5 kB"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<browserconfig>
|
<browserconfig>
|
||||||
<msapplication>
|
<msapplication>
|
||||||
<tile>
|
<tile>
|
||||||
<square150x150logo src="/assets/images/mstile-150x150.png"/>
|
<square150x150logo src="/assets/images/mstile-150x150.png"/>
|
||||||
<TileColor>#ffffff</TileColor>
|
<TileColor>#ffffff</TileColor>
|
||||||
</tile>
|
</tile>
|
||||||
</msapplication>
|
</msapplication>
|
||||||
</browserconfig>
|
</browserconfig>
|
||||||
|
|
27
public/assets/scripts/.eslintrc.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// get polyfill settings from top level config
|
||||||
|
// @ts-ignore
|
||||||
|
const { settings } = require('../../../.eslintrc.json');
|
||||||
|
|
||||||
|
// Adding non-polyfilable Symbol-related functions as they are most probably
|
||||||
|
// behind the flag
|
||||||
|
|
||||||
|
settings.polyfills.push(
|
||||||
|
'Symbol.toStringTag',
|
||||||
|
'Symbol.for',
|
||||||
|
'Object.getOwnPropertySymbols',
|
||||||
|
'Object.getOwnPropertyDescriptors',
|
||||||
|
'Promise', // Promise is gate checked
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = /** @type {import('eslint').Linter.Config} */ ({
|
||||||
|
root: true,
|
||||||
|
extends: ['plugin:compat/recommended'],
|
||||||
|
parserOptions: {
|
||||||
|
// ensure that it's compatible with ES5 browsers, so, no `const`, etc
|
||||||
|
ecmaVersion: 5,
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
},
|
||||||
|
settings,
|
||||||
|
});
|
4
public/assets/scripts/choices.min.js
vendored
1
public/assets/scripts/choices.min.js.LICENSE.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/*! choices.js v10.2.0 | © 2022 Josh Johnson | https://github.com/jshjohnson/Choices#readme */
|
|
@ -1,14 +1,14 @@
|
||||||
/*=============================================
|
/* =============================================
|
||||||
= Generic styling =
|
= Generic styling =
|
||||||
=============================================*/
|
============================================= */
|
||||||
* {
|
* {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
*,
|
*,
|
||||||
*:before,
|
*::before,
|
||||||
*:after {
|
*::after {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ body {
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
color: #FFFFFF;
|
color: #fff;
|
||||||
background-color: #333;
|
background-color: #333;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ label {
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
|
@ -64,7 +65,7 @@ h6 {
|
||||||
a,
|
a,
|
||||||
a:visited,
|
a:visited,
|
||||||
a:focus {
|
a:focus {
|
||||||
color: #FFFFFF;
|
color: #fff;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +79,7 @@ a:focus {
|
||||||
border-radius: 2.5px;
|
border-radius: 2.5px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
appearance: none;
|
||||||
appearance: none;
|
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,13 +113,16 @@ h6,
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label + p {
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: block;
|
display: block;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: 40em;
|
max-width: 40em;
|
||||||
padding: 48px;
|
padding: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 620px) {
|
@media (max-width: 620px) {
|
||||||
.container {
|
.container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -127,11 +130,10 @@ h6,
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
background-color: #FFFFFF;
|
background-color: #fff;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section a,
|
.section a,
|
||||||
.section a:visited,
|
.section a:visited,
|
||||||
.section a:focus {
|
.section a:focus {
|
||||||
|
@ -143,7 +145,7 @@ h6,
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo__img {
|
.logo-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -156,6 +158,10 @@ h6,
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.push-bottom {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.zero-bottom {
|
.zero-bottom {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -168,8 +174,8 @@ h6,
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-hidden {
|
[data-test-hook] {
|
||||||
display: none;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===== End of Section comment block ======*/
|
/* ===== End of Section comment block ====== */
|
||||||
|
|
1
public/assets/styles/base.css.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"sourceRoot":"","sources":["../../../src/styles/base.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAYA;EACE;EACA;;;AAGF;AAAA;AAAA;EAGE;;;AAGF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME;EACA;EACA;EACA;;;AAGF;AAAA;AAAA;EAGE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,eAtFiB;;;AAyFnB;AAAA;EAEE,WA1FoB;;;AA6FtB;AAAA;EAEE,WA9FoB;;;AAiGtB;AAAA;EAEE,WAlGoB;;;AAqGtB;AAAA;EAEE,WAtGoB;;;AAyGtB;AAAA;EAEE,WA1GoB;;;AA6GtB;AAAA;EAEE,WA9GoB;;;AAiHtB;EACE;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EANF;IAOI;;;;AAIJ;EACE;EACA,SAxIiB;EAyIjB;;AAEA;AAAA;AAAA;EAGE;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE,eArKiB;;;AAwKnB;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE,eArLiB;;;AAwLnB","file":"base.css"}
|
2
public/assets/styles/base.min.css
vendored
|
@ -1 +1 @@
|
||||||
*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,:after,:before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label{margin-bottom:8px;font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;-webkit-appearance:none;-moz-appearance:none;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#00bcd4}.logo{display:block;margin-bottom:12px}.logo__img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}.is-hidden{display:none}
|
*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}*,::after,::before{box-sizing:border-box}body,html{position:relative;margin:0;width:100%;height:100%}body{font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;font-size:16px;line-height:1.4;color:#fff;background-color:#333;overflow-x:hidden}hr,label{display:block}label,p{margin-bottom:8px}label{font-size:14px;font-weight:500;cursor:pointer}p{margin-top:0}hr{margin:30px 0;border:0;border-bottom:1px solid #eaeaea;height:1px}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:12px;font-weight:400;line-height:1.2}a,a:focus,a:visited{color:#fff;text-decoration:none;font-weight:600}.form-control{display:block;width:100%;background-color:#f9f9f9;padding:12px;border:1px solid #ddd;border-radius:2.5px;font-size:14px;-webkit-appearance:none;appearance:none;margin-bottom:24px}.h1,h1{font-size:32px}.h2,h2{font-size:24px}.h3,h3{font-size:20px}.h4,h4{font-size:18px}.h5,h5{font-size:16px}.h6,h6{font-size:14px}label+p{margin-top:-4px}.container{display:block;margin:auto;max-width:40em;padding:48px}@media (max-width:620px){.container{padding:0}}.section{background-color:#fff;padding:24px;color:#333}.section a,.section a:focus,.section a:visited{color:#00bcd4}.logo{display:block;margin-bottom:12px}.logo-img{width:100%;height:auto;display:inline-block;max-width:100%;vertical-align:top;padding:6px 0}.visible-ie{display:none}.push-bottom{margin-bottom:24px}.zero-bottom{margin-bottom:0}.zero-top{margin-top:0}.text-center{text-align:center}[data-test-hook]{margin-bottom:24px}
|
|
@ -1,53 +1,51 @@
|
||||||
/*===============================
|
/* ===============================
|
||||||
= Choices =
|
= Choices =
|
||||||
===============================*/
|
=============================== */
|
||||||
.choices {
|
.choices {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices:focus {
|
.choices:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices:last-child {
|
.choices:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
.choices.is-open {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
.choices.is-disabled .choices__inner,
|
.choices.is-disabled .choices__inner,
|
||||||
.choices.is-disabled .choices__input {
|
.choices.is-disabled .choices__input {
|
||||||
background-color: #EAEAEA;
|
background-color: #eaeaea;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices.is-disabled .choices__item {
|
.choices.is-disabled .choices__item {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
.choices [hidden] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.choices[data-type*="select-one"] {
|
.choices[data-type*=select-one] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__inner {
|
||||||
.choices[data-type*="select-one"] .choices__inner {
|
|
||||||
padding-bottom: 7.5px;
|
padding-bottom: 7.5px;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__input {
|
||||||
.choices[data-type*="select-one"] .choices__input {
|
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-bottom: 1px solid #DDDDDD;
|
border-bottom: 1px solid #ddd;
|
||||||
background-color: #FFFFFF;
|
background-color: #fff;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__button {
|
||||||
.choices[data-type*="select-one"] .choices__button {
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
|
||||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMDAwIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-size: 8px;
|
background-size: 8px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -58,23 +56,23 @@
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
border-radius: 10em;
|
border-radius: 10em;
|
||||||
opacity: .5;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__button:hover, .choices[data-type*=select-one] .choices__button:focus {
|
||||||
.choices[data-type*="select-one"] .choices__button:hover, .choices[data-type*="select-one"] .choices__button:focus {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__button:focus {
|
||||||
.choices[data-type*="select-one"] .choices__button:focus {
|
box-shadow: 0 0 0 2px #00bcd4;
|
||||||
box-shadow: 0px 0px 0px 2px #00BCD4;
|
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one] .choices__item[data-value=""] .choices__button {
|
||||||
.choices[data-type*="select-one"]:after {
|
display: none;
|
||||||
|
}
|
||||||
|
.choices[data-type*=select-one]::after {
|
||||||
content: "";
|
content: "";
|
||||||
height: 0;
|
height: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-color: #333333 transparent transparent transparent;
|
border-color: #333 transparent transparent transparent;
|
||||||
border-width: 5px;
|
border-width: 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 11.5px;
|
right: 11.5px;
|
||||||
|
@ -82,31 +80,27 @@
|
||||||
margin-top: -2.5px;
|
margin-top: -2.5px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one].is-open::after {
|
||||||
.choices[data-type*="select-one"].is-open:after {
|
border-color: transparent transparent #333 transparent;
|
||||||
border-color: transparent transparent #333333 transparent;
|
|
||||||
margin-top: -7.5px;
|
margin-top: -7.5px;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one][dir=rtl]::after {
|
||||||
.choices[data-type*="select-one"][dir="rtl"]:after {
|
|
||||||
left: 11.5px;
|
left: 11.5px;
|
||||||
right: auto;
|
right: auto;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-one][dir=rtl] .choices__button {
|
||||||
.choices[data-type*="select-one"][dir="rtl"] .choices__button {
|
|
||||||
right: auto;
|
right: auto;
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-left: 25px;
|
margin-left: 25px;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices[data-type*="select-multiple"] .choices__inner,
|
.choices[data-type*=select-multiple] .choices__inner,
|
||||||
.choices[data-type*="text"] .choices__inner {
|
.choices[data-type*=text] .choices__inner {
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-multiple] .choices__button,
|
||||||
.choices[data-type*="select-multiple"] .choices__button,
|
.choices[data-type*=text] .choices__button {
|
||||||
.choices[data-type*="text"] .choices__button {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
@ -115,17 +109,16 @@
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
border-left: 1px solid #008fa1;
|
border-left: 1px solid #008fa1;
|
||||||
background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==);
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjEiIHZpZXdCb3g9IjAgMCAyMSAyMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjRkZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yLjU5Mi4wNDRsMTguMzY0IDE4LjM2NC0yLjU0OCAyLjU0OEwuMDQ0IDIuNTkyeiIvPjxwYXRoIGQ9Ik0wIDE4LjM2NEwxOC4zNjQgMGwyLjU0OCAyLjU0OEwyLjU0OCAyMC45MTJ6Ii8+PC9nPjwvc3ZnPg==");
|
||||||
background-size: 8px;
|
background-size: 8px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
opacity: .75;
|
opacity: 0.75;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
.choices[data-type*=select-multiple] .choices__button:hover, .choices[data-type*=select-multiple] .choices__button:focus,
|
||||||
.choices[data-type*="select-multiple"] .choices__button:hover, .choices[data-type*="select-multiple"] .choices__button:focus,
|
.choices[data-type*=text] .choices__button:hover,
|
||||||
.choices[data-type*="text"] .choices__button:hover,
|
.choices[data-type*=text] .choices__button:focus {
|
||||||
.choices[data-type*="text"] .choices__button:focus {
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,22 +128,18 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
padding: 7.5px 7.5px 3.75px;
|
padding: 7.5px 7.5px 3.75px;
|
||||||
border: 1px solid #DDDDDD;
|
border: 1px solid #ddd;
|
||||||
border-radius: 2.5px;
|
border-radius: 2.5px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
.is-focused .choices__inner, .is-open .choices__inner {
|
||||||
.is-focused .choices__inner,
|
|
||||||
.is-open .choices__inner {
|
|
||||||
border-color: #b7b7b7;
|
border-color: #b7b7b7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-open .choices__inner {
|
.is-open .choices__inner {
|
||||||
border-radius: 2.5px 2.5px 0 0;
|
border-radius: 2.5px 2.5px 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-flipped.is-open .choices__inner {
|
.is-flipped.is-open .choices__inner {
|
||||||
border-radius: 0 0 2.5px 2.5px;
|
border-radius: 0 0 2.5px 2.5px;
|
||||||
}
|
}
|
||||||
|
@ -160,18 +149,15 @@
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--single {
|
.choices__list--single {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 4px 16px 4px 4px;
|
padding: 4px 16px 4px 4px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .choices__list--single {
|
||||||
[dir="rtl"] .choices__list--single {
|
|
||||||
padding-right: 4px;
|
padding-right: 4px;
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--single .choices__item {
|
.choices__list--single .choices__item {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +165,6 @@
|
||||||
.choices__list--multiple {
|
.choices__list--multiple {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--multiple .choices__item {
|
.choices__list--multiple .choices__item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
@ -189,85 +174,76 @@
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-right: 3.75px;
|
margin-right: 3.75px;
|
||||||
margin-bottom: 3.75px;
|
margin-bottom: 3.75px;
|
||||||
background-color: #00BCD4;
|
background-color: #00bcd4;
|
||||||
border: 1px solid #00a5bb;
|
border: 1px solid #00a5bb;
|
||||||
color: #FFFFFF;
|
color: #fff;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--multiple .choices__item[data-deletable] {
|
.choices__list--multiple .choices__item[data-deletable] {
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .choices__list--multiple .choices__item {
|
||||||
[dir="rtl"] .choices__list--multiple .choices__item {
|
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: 3.75px;
|
margin-left: 3.75px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--multiple .choices__item.is-highlighted {
|
.choices__list--multiple .choices__item.is-highlighted {
|
||||||
background-color: #00a5bb;
|
background-color: #00a5bb;
|
||||||
border: 1px solid #008fa1;
|
border: 1px solid #008fa1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-disabled .choices__list--multiple .choices__item {
|
.is-disabled .choices__list--multiple .choices__item {
|
||||||
background-color: #aaaaaa;
|
background-color: #aaaaaa;
|
||||||
border: 1px solid #919191;
|
border: 1px solid #919191;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__list--dropdown {
|
.choices__list--dropdown, .choices__list[aria-expanded] {
|
||||||
display: none;
|
visibility: hidden;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: #FFFFFF;
|
background-color: #fff;
|
||||||
border: 1px solid #DDDDDD;
|
border: 1px solid #ddd;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
border-bottom-left-radius: 2.5px;
|
border-bottom-left-radius: 2.5px;
|
||||||
border-bottom-right-radius: 2.5px;
|
border-bottom-right-radius: 2.5px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
will-change: visibility;
|
||||||
}
|
}
|
||||||
|
.is-active.choices__list--dropdown, .is-active.choices__list[aria-expanded] {
|
||||||
.choices__list--dropdown.is-active {
|
visibility: visible;
|
||||||
display: block;
|
|
||||||
}
|
}
|
||||||
|
.is-open .choices__list--dropdown, .is-open .choices__list[aria-expanded] {
|
||||||
.is-open .choices__list--dropdown {
|
|
||||||
border-color: #b7b7b7;
|
border-color: #b7b7b7;
|
||||||
}
|
}
|
||||||
|
.is-flipped .choices__list--dropdown, .is-flipped .choices__list[aria-expanded] {
|
||||||
.is-flipped .choices__list--dropdown {
|
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
border-radius: .25rem .25rem 0 0;
|
border-radius: 0.25rem 0.25rem 0 0;
|
||||||
}
|
}
|
||||||
|
.choices__list--dropdown .choices__list, .choices__list[aria-expanded] .choices__list {
|
||||||
.choices__list--dropdown .choices__list {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
will-change: scroll-position;
|
will-change: scroll-position;
|
||||||
}
|
}
|
||||||
|
.choices__list--dropdown .choices__item, .choices__list[aria-expanded] .choices__item {
|
||||||
.choices__list--dropdown .choices__item {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
[dir=rtl] .choices__list--dropdown .choices__item, [dir=rtl] .choices__list[aria-expanded] .choices__item {
|
||||||
[dir="rtl"] .choices__list--dropdown .choices__item {
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
.choices__list--dropdown .choices__item--selectable {
|
.choices__list--dropdown .choices__item--selectable, .choices__list[aria-expanded] .choices__item--selectable {
|
||||||
padding-right: 100px;
|
padding-right: 100px;
|
||||||
}
|
}
|
||||||
.choices__list--dropdown .choices__item--selectable:after {
|
.choices__list--dropdown .choices__item--selectable::after, .choices__list[aria-expanded] .choices__item--selectable::after {
|
||||||
content: attr(data-select-text);
|
content: attr(data-select-text);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -276,23 +252,21 @@
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
[dir="rtl"] .choices__list--dropdown .choices__item--selectable {
|
[dir=rtl] .choices__list--dropdown .choices__item--selectable, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-left: 100px;
|
padding-left: 100px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
[dir="rtl"] .choices__list--dropdown .choices__item--selectable:after {
|
[dir=rtl] .choices__list--dropdown .choices__item--selectable::after, [dir=rtl] .choices__list[aria-expanded] .choices__item--selectable::after {
|
||||||
right: auto;
|
right: auto;
|
||||||
left: 10px;
|
left: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.choices__list--dropdown .choices__item--selectable.is-highlighted, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted {
|
||||||
.choices__list--dropdown .choices__item--selectable.is-highlighted {
|
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
}
|
}
|
||||||
|
.choices__list--dropdown .choices__item--selectable.is-highlighted::after, .choices__list[aria-expanded] .choices__item--selectable.is-highlighted::after {
|
||||||
.choices__list--dropdown .choices__item--selectable.is-highlighted:after {
|
opacity: 0.5;
|
||||||
opacity: .5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__item {
|
.choices__item {
|
||||||
|
@ -306,10 +280,8 @@
|
||||||
.choices__item--disabled {
|
.choices__item--disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
opacity: .5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__heading {
|
.choices__heading {
|
||||||
|
@ -323,15 +295,13 @@
|
||||||
.choices__button {
|
.choices__button {
|
||||||
text-indent: -9999px;
|
text-indent: -9999px;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
appearance: none;
|
||||||
appearance: none;
|
|
||||||
border: 0;
|
border: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__button:focus {
|
.choices__button:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
@ -347,24 +317,24 @@
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 4px 0 4px 2px;
|
padding: 4px 0 4px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__input:focus {
|
.choices__input:focus {
|
||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
.choices__input::-webkit-search-decoration, .choices__input::-webkit-search-cancel-button, .choices__input::-webkit-search-results-button, .choices__input::-webkit-search-results-decoration {
|
||||||
[dir="rtl"] .choices__input {
|
display: none;
|
||||||
|
}
|
||||||
|
.choices__input::-ms-clear, .choices__input::-ms-reveal {
|
||||||
|
display: none;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
[dir=rtl] .choices__input {
|
||||||
padding-right: 2px;
|
padding-right: 2px;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__placeholder {
|
.choices__placeholder {
|
||||||
opacity: .5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.choices__input.is-hidden,
|
/* ===== End of Choices ====== */
|
||||||
.choices[data-type*="select-one"] .choices__input.is-hidden,
|
|
||||||
.choices[data-type*="select-multiple"] .choices__input.is-hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*===== End of Choices ======*/
|
|
||||||
|
|
1
public/assets/styles/choices.css.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"sourceRoot":"","sources":["../../../src/styles/choices.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AA2BA;EACE;EACA;EACA,eApBkB;EAqBlB,WAxBqB;;AA0BrB;EACE;;AAGF;EACE;;AAGF;EACE;;AAIA;AAAA;EAEE,kBAlCsB;EAmCtB;EACA;;AAEF;EACE;;AAIJ;EACE;;;AAIJ;EACE;;AACA;EACE;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEF;EACE,kBApDyB;EAqDzB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;EACA;;AAIA;EACE;EACA;;AAEF;EACE;EACA;EACA;EACA;;;AAOJ;AAAA;EACE;;AAEF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA,aA5HoB;EA6HpB;EACA;EACA,kBA9HiB;EA+HjB,iBAjIuB;EAkIvB,OAlIuB;EAmIvB;EACA;EACA;;AAEA;AAAA;AAAA;EAEE;;;AAKN;EACE;EACA;EACA;EACA,kBA1JiB;EA2JjB;EACA;EACA,eA/JsB;EAgKtB,WAnKqB;EAoKrB;EACA;;AAEA;EAEE;;AAGF;EACE;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;;AAOF;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;;;AAIJ;EACE;;AACA;EACE;EACA;EACA,eA9MyB;EA+MzB;EACA,WAnNmB;EAoNnB;EACA;EACA;EACA,kBA9MoB;EA+MpB;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;;AAKN;EACE;EACA,SApOgB;EAqOhB;EACA;EACA,kBAjP0B;EAkP1B;EACA;EACA;EACA,2BAzPsB;EA0PtB,4BA1PsB;EA2PtB;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA,WA3RmB;;AA6RnB;EACE;;AAIF;EADF;IAEI;;EAEA;IACE;IACA,WAtSe;IAuSf;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;;EAEA;IACE;IACA;;;AAKN;EACE;;AAEA;EACE;;;AAUR;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA,WAxVqB;EAyVrB;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA,kBA3WiB;EA4WjB,WAjXqB;EAkXrB;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EAIE;;AAGF;EAEE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;;;AAGF","file":"choices.css"}
|
2
public/assets/styles/choices.min.css
vendored
1407
public/index.html
1
public/robots.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Disallow: /test/*
|
628
public/test/select-multiple/index.html
Normal file
|
@ -0,0 +1,628 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,user-scalable=no"
|
||||||
|
/>
|
||||||
|
<title>Choices</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
itemprop="description"
|
||||||
|
content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-32x32.png"
|
||||||
|
sizes="32x32"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-16x16.png"
|
||||||
|
sizes="16x16"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="mask-icon"
|
||||||
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
|
color="#00bcd4"
|
||||||
|
/>
|
||||||
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
|
<meta
|
||||||
|
name="msapplication-config"
|
||||||
|
content="../../assets/images/browserconfig.xml"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
|
<!-- Ignore these -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
|
<!-- End ignore these -->
|
||||||
|
|
||||||
|
<!-- Choices includes -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
|
<!-- End Choices includes -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="section">
|
||||||
|
<h2>Select multiple inputs</h2>
|
||||||
|
<div data-test-hook="basic">
|
||||||
|
<label for="choices-basic">Basic</label>
|
||||||
|
<button class="disable push-bottom">Disable</button>
|
||||||
|
<button class="enable push-bottom">Enable</button>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-basic"
|
||||||
|
id="choices-basic"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Find me">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="remove-button">
|
||||||
|
<label for="choices-remove-button">Remove button</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remove-button"
|
||||||
|
id="choices-remove-button"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-choice">
|
||||||
|
<label for="choices-disabled-choice">Disabled choice</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-choice"
|
||||||
|
id="choices-disabled-choice"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4" disabled>Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="add-items-disabled">
|
||||||
|
<label for="choices-add-items-disabled">Add items disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-add-items-disabled"
|
||||||
|
id="choices-add-items-disabled"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-via-attr">
|
||||||
|
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-via-attr"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
multiple
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="selection-limit">
|
||||||
|
<label for="choices-selection-limit">Input limit</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-selection-limit"
|
||||||
|
id="choices-selection-limit"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
<option value="Choice 5">Choice 5</option>
|
||||||
|
<option value="Choice 6">Choice 6</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="prepend-append">
|
||||||
|
<label for="choices-prepend-append">Prepend/append</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-prepend-append"
|
||||||
|
id="choices-prepend-append"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="render-choice-limit">
|
||||||
|
<label for="choices-render-choice-limit">Render choice limit</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-render-choice-limit"
|
||||||
|
id="choices-render-choice-limit"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="search-floor">
|
||||||
|
<label for="choices-search-floor">Search floor</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-floor"
|
||||||
|
id="choices-search-floor"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="placeholder-via-option-value">
|
||||||
|
<label for="choices-placeholder-via-option-value"
|
||||||
|
>Placeholder via empty option value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-placeholder-via-option-value"
|
||||||
|
id="choices-placeholder-via-option-value"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="placeholder-via-option-attr">
|
||||||
|
<label for="choices-placeholder-via-option-attr"
|
||||||
|
>Placeholder via option attribute</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-placeholder-via-option-attr"
|
||||||
|
id="choices-placeholder-via-option-attr"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option placeholder>I am a placeholder</option>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="remote-data">
|
||||||
|
<label for="choices-remote-data">Remote data</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remote-data"
|
||||||
|
id="choices-remote-data"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="scrolling-dropdown">
|
||||||
|
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-scrolling-dropdown"
|
||||||
|
id="choices-scrolling-dropdown"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
<option value="Choice 5">Choice 5</option>
|
||||||
|
<option value="Choice 6">Choice 6</option>
|
||||||
|
<option value="Choice 7">Choice 7</option>
|
||||||
|
<option value="Choice 8">Choice 8</option>
|
||||||
|
<option value="Choice 9">Choice 9</option>
|
||||||
|
<option value="Choice 10">Choice 10</option>
|
||||||
|
<option value="Choice 11">Choice 11</option>
|
||||||
|
<option value="Choice 12">Choice 12</option>
|
||||||
|
<option value="Choice 13">Choice 13</option>
|
||||||
|
<option value="Choice 14">Choice 14</option>
|
||||||
|
<option value="Choice 15">Choice 15</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="groups">
|
||||||
|
<label for="choices-groups">Choice groups</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-groups"
|
||||||
|
id="choices-groups"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<optgroup label="UK">
|
||||||
|
<option value="London">London</option>
|
||||||
|
<option value="Manchester">Manchester</option>
|
||||||
|
<option value="Liverpool">Liverpool</option>
|
||||||
|
</optgroup>
|
||||||
|
<optgroup label="FR">
|
||||||
|
<option value="Paris">Paris</option>
|
||||||
|
<option value="Lyon">Lyon</option>
|
||||||
|
<option value="Marseille">Marseille</option>
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="custom-properties">
|
||||||
|
<label for="choices-custom-properties">Custom properties</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties"
|
||||||
|
id="choices-custom-properties"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="custom-properties-html">
|
||||||
|
<label for="choices-custom-properties-html">Custom properties</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties-html"
|
||||||
|
id="choices-custom-properties-html"
|
||||||
|
>
|
||||||
|
<option value="Dropdown item 1">Label One</option>
|
||||||
|
<option value="Dropdown item 2">Label Two</option>
|
||||||
|
<option
|
||||||
|
value="Dropdown item 3"
|
||||||
|
data-custom-properties="This option is fantastic"
|
||||||
|
>Label Three</option
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value="Dropdown item 4"
|
||||||
|
data-custom-properties="{ 'description': 'foo' }"
|
||||||
|
>Label Four</option
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="non-string-values">
|
||||||
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-non-string-values"
|
||||||
|
id="choices-non-string-values"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="within-form">
|
||||||
|
<form>
|
||||||
|
<label for="choices-within-form">Within form</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-within-form"
|
||||||
|
id="choices-within-form"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="set-choice-by-value">
|
||||||
|
<label for="choices-set-choice-by-value"
|
||||||
|
>Dynamically set choice by value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-set-choice-by-value"
|
||||||
|
id="choices-set-choice-by-value"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="search-by-label">
|
||||||
|
<label for="choices-search-by-label">Search by label</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-by-label"
|
||||||
|
id="choices-search-by-label"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option value="value1">label1</option>
|
||||||
|
<option value="value2">label2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="choices-allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-undefined"
|
||||||
|
id="choices-allowhtml-undefined"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="choices-allowhtml-true">HTML allowed</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-true"
|
||||||
|
id="choices-allowhtml-true"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="choices-allowhtml-false">HTML disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-false"
|
||||||
|
id="choices-allowhtml-false"
|
||||||
|
multiple
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('button.disable')
|
||||||
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.disable();
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('button.enable')
|
||||||
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.enable();
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
|
removeItemButton: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
|
addItems: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-selection-limit', {
|
||||||
|
allowHTML: true,
|
||||||
|
maxItemCount: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
|
prependValue: 'before-',
|
||||||
|
appendValue: '-after',
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
|
renderChoiceLimit: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFloor: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder-via-option-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder-via-option-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
|
shouldSort: false,
|
||||||
|
}).setChoices(async () => {
|
||||||
|
const data = await fetch('/data');
|
||||||
|
return data.json();
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
|
shouldSort: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
value: 'London',
|
||||||
|
label: 'London',
|
||||||
|
customProperties: {
|
||||||
|
country: 'United Kingdom',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
value: 'Berlin',
|
||||||
|
label: 'Berlin',
|
||||||
|
customProperties: {
|
||||||
|
country: 'Germany',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
value: 'Lisbon',
|
||||||
|
label: 'Lisbon',
|
||||||
|
customProperties: {
|
||||||
|
country: 'Portugal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties-html', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: 'Number',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Boolean',
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Object',
|
||||||
|
value: {
|
||||||
|
test: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: 'Array',
|
||||||
|
value: ['test'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-set-choice-by-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
|
new Choices('#choices-search-by-label', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label']
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-undefined', {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
selected: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: '<b>Choice 2</b>',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Choice 3',
|
||||||
|
value: 'Choice 3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
682
public/test/select-one/index.html
Normal file
|
@ -0,0 +1,682 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,user-scalable=no"
|
||||||
|
/>
|
||||||
|
<title>Choices</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
itemprop="description"
|
||||||
|
content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-32x32.png"
|
||||||
|
sizes="32x32"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-16x16.png"
|
||||||
|
sizes="16x16"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="mask-icon"
|
||||||
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
|
color="#00bcd4"
|
||||||
|
/>
|
||||||
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
|
<meta
|
||||||
|
name="msapplication-config"
|
||||||
|
content="../../assets/images/browserconfig.xml"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
|
<!-- Ignore these -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
|
<!-- End ignore these -->
|
||||||
|
|
||||||
|
<!-- Choices includes -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
|
<!-- End Choices includes -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="section">
|
||||||
|
<h2>Select one inputs</h2>
|
||||||
|
<div data-test-hook="basic">
|
||||||
|
<label for="choices-basic">Basic</label>
|
||||||
|
<button class="disable push-bottom">Disable</button>
|
||||||
|
<button class="enable push-bottom">Enable</button>
|
||||||
|
<select class="form-control" name="choices-basic" id="choices-basic">
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Find me">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="remove-button">
|
||||||
|
<label for="choices-remove-button">Remove button</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remove-button"
|
||||||
|
id="choices-remove-button"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-choice">
|
||||||
|
<label for="choices-disabled-choice">Disabled choice</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-choice"
|
||||||
|
id="choices-disabled-choice"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4" disabled>Choice 4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-first-choice-via-options">
|
||||||
|
<label for="choices-disabled-choice-via-options"
|
||||||
|
>Disabled first choice by options</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-choice-via-options"
|
||||||
|
id="choices-disabled-choice-via-options"
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="add-items-disabled">
|
||||||
|
<label for="choices-add-items-disabled">Add items disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-add-items-disabled"
|
||||||
|
id="choices-add-items-disabled"
|
||||||
|
>
|
||||||
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-via-attr">
|
||||||
|
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-disabled-via-attr"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="prepend-append">
|
||||||
|
<label for="choices-prepend-append">Prepend/append</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-prepend-append"
|
||||||
|
id="choices-prepend-append"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="render-choice-limit">
|
||||||
|
<label for="choices-render-choice-limit">Render choice limit</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-render-choice-limit"
|
||||||
|
id="choices-render-choice-limit"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="search-disabled">
|
||||||
|
<label for="choices-search-disabled">Search disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-disabled"
|
||||||
|
id="choices-search-disabled"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="search-floor">
|
||||||
|
<label for="choices-search-floor">Search floor</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-floor"
|
||||||
|
id="choices-search-floor"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="placeholder-via-option-value">
|
||||||
|
<label for="choices-placeholder-via-option-value"
|
||||||
|
>Placeholder via empty option value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-placeholder-via-option-value"
|
||||||
|
id="choices-placeholder-via-option-value"
|
||||||
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="placeholder-via-option-attr">
|
||||||
|
<label for="choices-placeholder-via-option-attr"
|
||||||
|
>Placeholder via option attribute</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-placeholder-via-option-attr"
|
||||||
|
id="choices-placeholder-via-option-attr"
|
||||||
|
>
|
||||||
|
<option placeholder>I am a placeholder</option>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="remote-data">
|
||||||
|
<label for="choices-remote-data">Remote data</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-remote-data"
|
||||||
|
id="choices-remote-data"
|
||||||
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="scrolling-dropdown">
|
||||||
|
<label for="choices-scrolling-dropdown">Scrolling dropdown</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-scrolling-dropdown"
|
||||||
|
id="choices-scrolling-dropdown"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
<option value="Choice 4">Choice 4</option>
|
||||||
|
<option value="Choice 5">Choice 5</option>
|
||||||
|
<option value="Choice 6">Choice 6</option>
|
||||||
|
<option value="Choice 7">Choice 7</option>
|
||||||
|
<option value="Choice 8">Choice 8</option>
|
||||||
|
<option value="Choice 9">Choice 9</option>
|
||||||
|
<option value="Choice 10">Choice 10</option>
|
||||||
|
<option value="Choice 11">Choice 11</option>
|
||||||
|
<option value="Choice 12">Choice 12</option>
|
||||||
|
<option value="Choice 13">Choice 13</option>
|
||||||
|
<option value="Choice 14">Choice 14</option>
|
||||||
|
<option value="Choice 15">Choice 15</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="groups">
|
||||||
|
<label for="choices-groups">Choice groups</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-groups"
|
||||||
|
id="choices-groups"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<optgroup label="UK">
|
||||||
|
<option value="London">London</option>
|
||||||
|
<option value="Manchester">Manchester</option>
|
||||||
|
<option value="Liverpool">Liverpool</option>
|
||||||
|
</optgroup>
|
||||||
|
<optgroup label="FR">
|
||||||
|
<option value="Paris">Paris</option>
|
||||||
|
<option value="Lyon">Lyon</option>
|
||||||
|
<option value="Marseille">Marseille</option>
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="parent-child">
|
||||||
|
<label for="choices-parent">Parent</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-parent"
|
||||||
|
id="choices-parent"
|
||||||
|
>
|
||||||
|
<option value="Parent choice 1">Parent choice 1</option>
|
||||||
|
<option value="Parent choice 2">Parent choice 2</option>
|
||||||
|
<option value="Parent choice 3">Parent choice 3</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="choices-child">Child</label>
|
||||||
|
<select class="form-control" name="choices-child" id="choices-child">
|
||||||
|
<option value="Child choice 1">Child choice 1</option>
|
||||||
|
<option value="Child choice 2">Child choice 2</option>
|
||||||
|
<option value="Child choice 3">Child choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="custom-properties">
|
||||||
|
<label for="choices-custom-properties">Custom properties</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties"
|
||||||
|
id="choices-custom-properties"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="custom-properties-html">
|
||||||
|
<label for="choices-custom-properties-html">Custom properties</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-custom-properties-html"
|
||||||
|
id="choices-custom-properties-html"
|
||||||
|
>
|
||||||
|
<option value="Dropdown item 1">Label One</option>
|
||||||
|
<option value="Dropdown item 2">Label Two</option>
|
||||||
|
<option
|
||||||
|
value="Dropdown item 3"
|
||||||
|
data-custom-properties="This option is fantastic"
|
||||||
|
>Label Three</option
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
value="Dropdown item 4"
|
||||||
|
data-custom-properties="{ 'description': 'foo' }"
|
||||||
|
>Label Four</option
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="non-string-values">
|
||||||
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-non-string-values"
|
||||||
|
id="choices-non-string-values"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="within-form">
|
||||||
|
<form>
|
||||||
|
<label for="choices-within-form">Within form</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-within-form"
|
||||||
|
id="choices-within-form"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="set-choice-by-value">
|
||||||
|
<label for="choices-set-choice-by-value"
|
||||||
|
>Dynamically set choice by value</label
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-set-choice-by-value"
|
||||||
|
id="choices-set-choice-by-value"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="search-by-label">
|
||||||
|
<label for="choices-search-by-label">Search by label</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-search-by-label"
|
||||||
|
id="choices-search-by-label"
|
||||||
|
>
|
||||||
|
<option value="value1">label1</option>
|
||||||
|
<option value="value2">label2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="choices-allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-undefined"
|
||||||
|
id="choices-allowhtml-undefined"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="choices-allowhtml-true">HTML allowed</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-true"
|
||||||
|
id="choices-allowhtml-true"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="choices-allowhtml-false">HTML disabled</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-allowhtml-false"
|
||||||
|
id="choices-allowhtml-false"
|
||||||
|
></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="new-destroy-init">
|
||||||
|
<label for="choices-new-destroy-init">New, Destroy, Init</label>
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
name="choices-new-destroy-init"
|
||||||
|
id="choices-new-destroy-init"
|
||||||
|
>
|
||||||
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
<option value="Choice 2">Choice 2</option>
|
||||||
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
</select>
|
||||||
|
<button class="destroy">Destroy</button>
|
||||||
|
<button class="init">Init</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('button.disable')
|
||||||
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.disable();
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('button.enable')
|
||||||
|
.addEventListener('click', () => {
|
||||||
|
choicesBasic.enable();
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
|
removeItemButton: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
|
removeItemButton: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-choice-via-options', {
|
||||||
|
allowHTML: true,
|
||||||
|
removeItemButton: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
value: 'Choice 1',
|
||||||
|
label: 'Choice 1',
|
||||||
|
disabled: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Choice 2',
|
||||||
|
label: 'Choice 2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Choice 3',
|
||||||
|
label: 'Choice 3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Choice 4',
|
||||||
|
label: 'Choice 4',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
|
addItems: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
|
prependValue: 'before-',
|
||||||
|
appendValue: '-after',
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
|
renderChoiceLimit: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-search-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchEnabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFloor: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder-via-option-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder-via-option-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
|
shouldSort: false,
|
||||||
|
}).setChoices(async () => {
|
||||||
|
const res = await fetch('/data');
|
||||||
|
return res.json();
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
|
shouldSort: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const parent = new Choices('#choices-parent', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
const child = new Choices('#choices-child', {
|
||||||
|
allowHTML: true,
|
||||||
|
}).disable();
|
||||||
|
|
||||||
|
parent.passedElement.element.addEventListener('change', event => {
|
||||||
|
if (event.detail.value === 'Parent choice 2') {
|
||||||
|
child.enable();
|
||||||
|
} else {
|
||||||
|
child.disable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
value: 'London',
|
||||||
|
label: 'London',
|
||||||
|
customProperties: {
|
||||||
|
country: 'United Kingdom',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
value: 'Berlin',
|
||||||
|
label: 'Berlin',
|
||||||
|
customProperties: {
|
||||||
|
country: 'Germany',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
value: 'Lisbon',
|
||||||
|
label: 'Lisbon',
|
||||||
|
customProperties: {
|
||||||
|
country: 'Portugal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties-html', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: 'Number',
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Boolean',
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
label: 'Object',
|
||||||
|
value: {
|
||||||
|
test: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
label: 'Array',
|
||||||
|
value: ['test'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-set-choice-by-value', {
|
||||||
|
allowHTML: true,
|
||||||
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
|
new Choices('#choices-search-by-label', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label']
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-undefined', {
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: '<b>Choice 1</b>',
|
||||||
|
value: 'Choice 1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Choice 2',
|
||||||
|
value: 'Choice 2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const newDestroyInitChoices = new Choices('#choices-new-destroy-init', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
document
|
||||||
|
.querySelector('button.destroy')
|
||||||
|
.addEventListener('click', () => {
|
||||||
|
newDestroyInitChoices.destroy();
|
||||||
|
});
|
||||||
|
document.querySelector('button.init').addEventListener('click', () => {
|
||||||
|
newDestroyInitChoices.init();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
247
public/test/text/index.html
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width,initial-scale=1,user-scalable=no"
|
||||||
|
/>
|
||||||
|
<title>Choices</title>
|
||||||
|
<meta
|
||||||
|
name="description"
|
||||||
|
itemprop="description"
|
||||||
|
content="A lightweight, configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency."
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="apple-touch-icon"
|
||||||
|
sizes="180x180"
|
||||||
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-32x32.png"
|
||||||
|
sizes="32x32"
|
||||||
|
/>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/png"
|
||||||
|
href="../../assets/images/favicon-16x16.png"
|
||||||
|
sizes="16x16"
|
||||||
|
/>
|
||||||
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
|
<link
|
||||||
|
rel="mask-icon"
|
||||||
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
|
color="#00bcd4"
|
||||||
|
/>
|
||||||
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
|
<meta
|
||||||
|
name="msapplication-config"
|
||||||
|
content="../../assets/images/browserconfig.xml"
|
||||||
|
/>
|
||||||
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
|
<!-- Ignore these -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
|
<!-- End ignore these -->
|
||||||
|
|
||||||
|
<!-- Choices includes -->
|
||||||
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
|
<!-- End Choices includes -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="section">
|
||||||
|
<h2>Text inputs</h2>
|
||||||
|
<div data-test-hook="basic">
|
||||||
|
<label for="choices-basic">Basic</label>
|
||||||
|
<input class="form-control" id="choices-basic" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="edit-items">
|
||||||
|
<label for="choices-edit-items">Edit items</label>
|
||||||
|
<input class="form-control" id="choices-edit-items" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="remove-button">
|
||||||
|
<label for="choices-remove-button">Remove button</label>
|
||||||
|
<input class="form-control" id="choices-remove-button" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="unique-values">
|
||||||
|
<label for="choices-unique-values">Unique values</label>
|
||||||
|
<input class="form-control" id="choices-unique-values" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-undefined">
|
||||||
|
<label for="allowhtml-undefined">HTML allowed by default</label>
|
||||||
|
<input class="form-control" id="allowhtml-undefined" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-true">
|
||||||
|
<label for="allowhtml-true">HTML allowed</label>
|
||||||
|
<input class="form-control" id="allowhtml-true" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="allowhtml-false">
|
||||||
|
<label for="allowhtml-false">HTML disabled</label>
|
||||||
|
<input class="form-control" id="allowhtml-false" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="input-limit">
|
||||||
|
<label for="choices-input-limit">Input limit</label>
|
||||||
|
<input class="form-control" id="choices-input-limit" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="add-item-filter">
|
||||||
|
<label for="choices-add-item-filter">Add item filter</label>
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-add-item-filter"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="adding-items-disabled">
|
||||||
|
<label for="choices-adding-items-disabled">Add items disabled</label>
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-adding-items-disabled"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="disabled-via-attr">
|
||||||
|
<label for="choices-disabled-via-attr">Disabled via attribute</label>
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
id="choices-disabled-via-attr"
|
||||||
|
type="text"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="prepend-append">
|
||||||
|
<label for="choices-prepend-append">Prepend/append</label>
|
||||||
|
<input class="form-control" id="choices-prepend-append" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="prepopulated">
|
||||||
|
<label for="choices-prepopulated">Pre-populated choices</label>
|
||||||
|
<input class="form-control" id="choices-prepopulated" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="placeholder">
|
||||||
|
<label for="choices-placeholder">Placeholder</label>
|
||||||
|
<input class="form-control" id="choices-placeholder" type="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div data-test-hook="within-form">
|
||||||
|
<form>
|
||||||
|
<label for="choices-within-form">Within form</label>
|
||||||
|
<input class="form-control" id="choices-within-form" type="text" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-edit-items', {
|
||||||
|
allowHTML: true,
|
||||||
|
editItems: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
|
removeItemButton: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-unique-values', {
|
||||||
|
allowHTML: true,
|
||||||
|
duplicateItemsAllowed: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-undefined', {
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-true', {
|
||||||
|
allowHTML: true,
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#allowhtml-false', {
|
||||||
|
allowHTML: false,
|
||||||
|
items: [
|
||||||
|
'<b>Mason Rogers</b>'
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-input-limit', {
|
||||||
|
allowHTML: true,
|
||||||
|
maxItemCount: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-add-item-filter', {
|
||||||
|
allowHTML: true,
|
||||||
|
addItems: true,
|
||||||
|
addItemFilter: value => {
|
||||||
|
const regex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
const expression = new RegExp(regex.source, 'i');
|
||||||
|
return expression.test(value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-adding-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
|
addItems: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
|
prependValue: 'before-',
|
||||||
|
appendValue: '-after',
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-prepopulated', {
|
||||||
|
allowHTML: true,
|
||||||
|
items: [
|
||||||
|
'Josh Johnson',
|
||||||
|
{
|
||||||
|
value: 'joe@bloggs.co.uk',
|
||||||
|
label: 'Joe Bloggs',
|
||||||
|
customProperties: {
|
||||||
|
description: 'Joe Blogg is such a generic name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder', {
|
||||||
|
allowHTML: true,
|
||||||
|
placeholder: true,
|
||||||
|
placeholderValue: 'I am a placeholder',
|
||||||
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
public/types/cypress/e2e/select-multiple.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=select-multiple.spec.d.ts.map
|
1
public/types/cypress/e2e/select-multiple.spec.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"select-multiple.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/select-multiple.spec.ts"],"names":[],"mappings":""}
|
1
public/types/cypress/e2e/select-one.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=select-one.spec.d.ts.map
|
1
public/types/cypress/e2e/select-one.spec.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"select-one.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/select-one.spec.ts"],"names":[],"mappings":""}
|
1
public/types/cypress/e2e/text.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=text.spec.d.ts.map
|
1
public/types/cypress/e2e/text.spec.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"text.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/e2e/text.spec.ts"],"names":[],"mappings":""}
|
1
public/types/cypress/integration/select-multiple.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=select-multiple.spec.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"select-multiple.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/select-multiple.spec.ts"],"names":[],"mappings":""}
|
1
public/types/cypress/integration/select-one.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=select-one.spec.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"select-one.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/select-one.spec.ts"],"names":[],"mappings":""}
|
1
public/types/cypress/integration/text.spec.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=text.spec.d.ts.map
|
1
public/types/cypress/integration/text.spec.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"text.spec.d.ts","sourceRoot":"","sources":["../../../../cypress/integration/text.spec.ts"],"names":[],"mappings":""}
|
3
public/types/cypress/plugins/index.d.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
declare function _exports(on: any, config: any): void;
|
||||||
|
export = _exports;
|
||||||
|
//# sourceMappingURL=index.d.ts.map
|
1
public/types/cypress/plugins/index.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../cypress/plugins/index.js"],"names":[],"mappings":"AAaiB,sDAGhB"}
|
1
public/types/cypress/support/commands.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=commands.d.ts.map
|
1
public/types/cypress/support/commands.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../cypress/support/commands.js"],"names":[],"mappings":""}
|
2
public/types/cypress/support/e2e.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=e2e.d.ts.map
|
1
public/types/cypress/support/e2e.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"e2e.d.ts","sourceRoot":"","sources":["../../../../cypress/support/e2e.js"],"names":[],"mappings":""}
|
2
public/types/cypress/support/index.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=index.d.ts.map
|
1
public/types/cypress/support/index.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../cypress/support/index.js"],"names":[],"mappings":""}
|
7
public/types/src/index.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Choices from './scripts/choices';
|
||||||
|
export * from './scripts/interfaces';
|
||||||
|
export * from './scripts/constants';
|
||||||
|
export * from './scripts/defaults';
|
||||||
|
export { default as templates } from './scripts/templates';
|
||||||
|
export default Choices;
|
||||||
|
//# sourceMappingURL=index.d.ts.map
|
1
public/types/src/index.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAC;AAExC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE3D,eAAe,OAAO,CAAC"}
|
44
public/types/src/scripts/actions/choices.d.ts
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { ACTION_TYPES } from '../constants';
|
||||||
|
import { Choice } from '../interfaces/choice';
|
||||||
|
export interface AddChoiceAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_CHOICE;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
groupId: number;
|
||||||
|
disabled: boolean;
|
||||||
|
elementId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}
|
||||||
|
export interface Result<T> {
|
||||||
|
item: T;
|
||||||
|
score: number;
|
||||||
|
}
|
||||||
|
export interface FilterChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.FILTER_CHOICES;
|
||||||
|
results: Result<Choice>[];
|
||||||
|
}
|
||||||
|
export interface ActivateChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.ACTIVATE_CHOICES;
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
export interface ClearChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.CLEAR_CHOICES;
|
||||||
|
}
|
||||||
|
export declare const addChoice: ({ value, label, id, groupId, disabled, elementId, customProperties, placeholder, keyCode, }: {
|
||||||
|
value: any;
|
||||||
|
label: any;
|
||||||
|
id: any;
|
||||||
|
groupId: any;
|
||||||
|
disabled: any;
|
||||||
|
elementId: any;
|
||||||
|
customProperties: any;
|
||||||
|
placeholder: any;
|
||||||
|
keyCode: any;
|
||||||
|
}) => AddChoiceAction;
|
||||||
|
export declare const filterChoices: (results: Result<Choice>[]) => FilterChoicesAction;
|
||||||
|
export declare const activateChoices: (active?: boolean) => ActivateChoicesAction;
|
||||||
|
export declare const clearChoices: () => ClearChoicesAction;
|
||||||
|
//# sourceMappingURL=choices.d.ts.map
|
1
public/types/src/scripts/actions/choices.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"choices.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/choices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,OAAO,YAAY,CAAC,UAAU,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,OAAO,YAAY,CAAC,gBAAgB,CAAC;IAC3C,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,YAAY,CAAC,aAAa,CAAC;CACzC;AAED,eAAO,MAAM,SAAS;;;;;;;;;;MAUlB,eAWF,CAAC;AAEH,eAAO,MAAM,aAAa,YACf,OAAO,MAAM,CAAC,EAAE,KACxB,mBAGD,CAAC;AAEH,eAAO,MAAM,eAAe,wBAAoB,qBAG9C,CAAC;AAEH,eAAO,MAAM,YAAY,QAAO,kBAE9B,CAAC"}
|
2
public/types/src/scripts/actions/choices.test.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=choices.test.d.ts.map
|