Compare commits
165 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 |
|
@ -1,16 +1,22 @@
|
||||||
{
|
{
|
||||||
"parserOptions": {
|
"parser": "@typescript-eslint/parser",
|
||||||
"ecmaVersion": 2020
|
"plugins": ["@typescript-eslint", "prettier", "sort-class-members"],
|
||||||
},
|
|
||||||
"extends": [
|
"extends": [
|
||||||
"airbnb-base",
|
"airbnb-base",
|
||||||
|
"airbnb-typescript",
|
||||||
"plugin:prettier/recommended",
|
"plugin:prettier/recommended",
|
||||||
"plugin:compat/recommended"
|
"plugin:compat/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended"
|
||||||
],
|
],
|
||||||
"plugins": ["prettier", "sort-class-members"],
|
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"browser": true
|
"browser": true,
|
||||||
|
"mocha": true,
|
||||||
|
"cypress/globals": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json",
|
||||||
|
"ecmaVersion": 2020
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"import/prefer-default-export": "off",
|
"import/prefer-default-export": "off",
|
||||||
|
@ -54,23 +60,41 @@
|
||||||
],
|
],
|
||||||
"accessorPairPositioning": "getThenSet"
|
"accessorPairPositioning": "getThenSet"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"lines-between-class-members": "off",
|
||||||
|
"@typescript-eslint/no-namespace": "off",
|
||||||
|
"react/jsx-filename-extension": [0]
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.test.js"],
|
"files": ["*.test.ts"],
|
||||||
"env": {
|
"env": {
|
||||||
"mocha": true
|
"mocha": true
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-restricted-syntax": "off",
|
"no-restricted-syntax": "off",
|
||||||
"compat/compat": "off",
|
"compat/compat": "off",
|
||||||
"no-new": "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/**/*.spec.js"],
|
"files": ["cypress/**"],
|
||||||
"plugins": ["cypress"],
|
"plugins": ["cypress"],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": "warn"
|
||||||
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"cypress/globals": true
|
"cypress/globals": true
|
||||||
}
|
}
|
||||||
|
@ -83,10 +107,17 @@
|
||||||
"Array.prototype.includes",
|
"Array.prototype.includes",
|
||||||
"Symbol",
|
"Symbol",
|
||||||
"Symbol.iterator",
|
"Symbol.iterator",
|
||||||
|
"DOMTokenList",
|
||||||
"Object.assign",
|
"Object.assign",
|
||||||
"CustomEvent",
|
"CustomEvent",
|
||||||
"Element.prototype.classList",
|
"Element.prototype.classList",
|
||||||
"Element.prototype.closest"
|
"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.
|
24
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,28 +1,28 @@
|
||||||
<!--- Provide a general summary of your changes in the Title above -->
|
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
<!--- Describe your changes in detail -->
|
|
||||||
|
|
||||||
## Motivation and Context
|
<!--- Describe your changes in detail -->
|
||||||
<!--- Why is this change required? What problem does it solve? -->
|
<!--- Why is this change required? What problem does it solve? -->
|
||||||
<!--- If it fixes an open issue, please link to the issue here. -->
|
<!--- If it fixes an open issue, please link to the issue here. -->
|
||||||
|
|
||||||
## How Has This Been Tested?
|
## Screenshots (if appropriate)
|
||||||
<!--- Please describe in detail how you tested your changes. -->
|
|
||||||
<!--- Include details of your testing environment, tests ran to see how -->
|
|
||||||
<!--- your change affects other areas of the code, etc. -->
|
|
||||||
|
|
||||||
## Screenshots (if appropriate):
|
|
||||||
|
|
||||||
## Types of changes
|
## Types of changes
|
||||||
|
|
||||||
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
<!--- 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)
|
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||||
- [ ] New feature (non-breaking change which adds functionality)
|
- [ ] New feature (non-breaking change which adds functionality)
|
||||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||||
|
|
||||||
## Checklist:
|
## Checklist
|
||||||
|
|
||||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
<!--- 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! -->
|
<!--- 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.
|
- [ ] 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.
|
- [ ] My change requires a change to the documentation.
|
||||||
- [ ] I have updated the documentation accordingly.
|
- [ ] 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 |
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}}
|
12
.github/workflows/bundlesize.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: BundleSize
|
name: Bundle size checks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -12,18 +12,18 @@ jobs:
|
||||||
measure:
|
measure:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 18
|
||||||
|
|
||||||
- name: Install dependencies and build
|
- name: Install dependencies and build
|
||||||
run: |
|
run: |
|
||||||
npm ci
|
npm ci
|
||||||
npm run build
|
npm run build
|
||||||
env:
|
env:
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
HUSKY_SKIP_INSTALL: true
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
32
.github/workflows/cypress.yml
vendored
|
@ -1,32 +0,0 @@
|
||||||
name: Cypress
|
|
||||||
|
|
||||||
on: [pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test-e2e:
|
|
||||||
name: integration tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 10
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm ci
|
|
||||||
env:
|
|
||||||
HUSKY_SKIP_INSTALL: true
|
|
||||||
|
|
||||||
- name: run Cypress
|
|
||||||
run: npx run-p --race start cypress:run
|
|
||||||
env:
|
|
||||||
CI: true
|
|
||||||
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 }}
|
|
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 }}
|
31
.github/workflows/lint.yml
vendored
|
@ -1,9 +1,10 @@
|
||||||
name: Lint
|
name: Code linting
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'src/scripts/**'
|
- 'src/scripts/**'
|
||||||
|
- 'src/styles/**'
|
||||||
- package-lock.json
|
- package-lock.json
|
||||||
- '.browserslistrc'
|
- '.browserslistrc'
|
||||||
|
|
||||||
|
@ -11,28 +12,30 @@ jobs:
|
||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 18
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm install --no-optional --no-audit --ignore-scripts
|
run: npm ci
|
||||||
env:
|
env:
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
CYPRESS_INSTALL_BINARY: 0
|
||||||
HUSKY_SKIP_INSTALL: true
|
HUSKY_SKIP_INSTALL: true
|
||||||
|
|
||||||
- name: run eslint
|
- name: run eslint
|
||||||
run: |
|
run: npm run lint:js
|
||||||
CHANGED_JS=$(git --no-pager diff --name-only ..origin/master | grep '^src\/scripts\/.*\.js$' | xargs ls -d 2>/dev/null | paste -sd " " -)
|
|
||||||
if [[ -z $(sed -e 's/[[:space:]]*$//' <<<${CHANGED_JS}) ]]; then CHANGED_JS="src/scripts"; fi
|
|
||||||
echo $CHANGED_JS
|
|
||||||
node node_modules/eslint/bin/eslint.js $CHANGED_JS
|
|
||||||
|
|
||||||
- name: Lint JS bundle
|
## Can't use same eslint config for TypeScript and JavaScript
|
||||||
run: |
|
## TypeScript rules cause rule definition not found errors
|
||||||
npm run js:build
|
## Can be re-enabled if this is resolved: https://github.com/eslint/eslint/issues/14851
|
||||||
npx eslint --no-ignore ./public/assets/scripts/*.js
|
# - 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
|
6
.github/workflows/polyfills-sync.yml
vendored
|
@ -11,13 +11,13 @@ jobs:
|
||||||
sync:
|
sync:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 18
|
||||||
|
|
||||||
- name: Check Polyfills documentation and settings sync
|
- name: Check Polyfills documentation and settings sync
|
||||||
run: node .github/actions-scripts/polyfills-sync.js
|
run: node .github/actions-scripts/polyfills-sync.js
|
||||||
|
|
88
.github/workflows/publish.yml
vendored
|
@ -1,88 +0,0 @@
|
||||||
name: Publish Package
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 10
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- 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}}
|
|
||||||
|
|
||||||
publish-npm:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 10
|
|
||||||
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}}
|
|
||||||
|
|
||||||
deploy-gh-pages:
|
|
||||||
needs: publish-npm
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 10
|
|
||||||
registry-url: https://registry.npmjs.org/
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run build
|
|
||||||
rm -rf public/test
|
|
||||||
- name: Deploy
|
|
||||||
uses: peaceiris/actions-gh-pages@v2.5.0
|
|
||||||
env:
|
|
||||||
ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
|
|
||||||
PUBLISH_BRANCH: gh-pages
|
|
||||||
PUBLISH_DIR: ./public
|
|
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 }}
|
27
.github/workflows/types.yml
vendored
|
@ -1,27 +0,0 @@
|
||||||
name: TypeScript Check
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'types/index.d.ts'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tsc:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v1
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 12
|
|
||||||
|
|
||||||
- name: Install TypeScript
|
|
||||||
run: npm install -g typescript
|
|
||||||
|
|
||||||
- name: Install required dependencies
|
|
||||||
run: npm i --only=production --no-optional --no-audit --ignore-scripts
|
|
||||||
|
|
||||||
- name: Check typings file
|
|
||||||
run: tsc types/index.d.ts
|
|
8
.github/workflows/unit-tests.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Unit Tests
|
name: Unit tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
@ -11,13 +11,13 @@ jobs:
|
||||||
test-unit:
|
test-unit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 18
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm install --no-optional --no-audit --ignore-scripts
|
run: npm install --no-optional --no-audit --ignore-scripts
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
require:
|
require:
|
||||||
- '@babel/register'
|
- 'ts-node/register'
|
||||||
- './config/jsdom.js'
|
- './config/jsdom.js'
|
||||||
|
|
||||||
exit: true
|
exit: true
|
||||||
|
spec: src/**/**/*.test.ts
|
||||||
spec: src/**/*.test.js
|
extension:
|
||||||
|
- ts
|
||||||
|
- js
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
|
"endOfLine": "lf",
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.svg"],
|
"files": ["*.svg"],
|
||||||
|
@ -8,6 +9,12 @@
|
||||||
"parser": "html",
|
"parser": "html",
|
||||||
"htmlWhitespaceSensitivity": "ignore"
|
"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
|
||||||
|
}
|
||||||
|
}
|
9
.vscode/settings.json
vendored
|
@ -59,5 +59,14 @@
|
||||||
"fileMatch": [".prettierrc.json"],
|
"fileMatch": [".prettierrc.json"],
|
||||||
"url": "http://json.schemastore.org/prettierrc"
|
"url": "http://json.schemastore.org/prettierrc"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"stylelint.validate": [
|
||||||
|
"css",
|
||||||
|
"less",
|
||||||
|
"postcss",
|
||||||
|
"scss"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
154
README.md
|
@ -1,8 +1,8 @@
|
||||||
# Choices.js [![Actions Status](https://github.com/jshjohnson/Choices/workflows/Unit%20Tests/badge.svg)](https://github.com/jshjohnson/Choices/actions) [![npm](https://img.shields.io/npm/v/choices.js.svg)](https://www.npmjs.com/package/choices.js) [![codebeat badge](https://codebeat.co/badges/55120150-5866-42d8-8010-6aaaff5d3fa1)](https://codebeat.co/projects/github-com-jshjohnson-choices-master)
|
# Choices.js [![Actions Status](https://github.com/jshjohnson/Choices/workflows/Build%20and%20test/badge.svg)](https://github.com/jshjohnson/Choices/actions) [![Actions Status](https://github.com/jshjohnson/Choices/workflows/Bundle%20size%20checks/badge.svg)](https://github.com/jshjohnson/Choices/actions) [![npm](https://img.shields.io/npm/v/choices.js.svg)](https://www.npmjs.com/package/choices.js)
|
||||||
|
|
||||||
A vanilla, lightweight (~19kb gzipped 🎉), configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.
|
A vanilla, lightweight (~19kb gzipped 🎉), configurable select box/text input plugin. Similar to Select2 and Selectize but without the jQuery dependency.
|
||||||
|
|
||||||
[Demo](https://joshuajohnson.co.uk/Choices/)
|
[Demo](https://choices-js.github.io/Choices/)
|
||||||
|
|
||||||
## TL;DR
|
## TL;DR
|
||||||
|
|
||||||
|
@ -19,8 +19,28 @@ A vanilla, lightweight (~19kb gzipped 🎉), configurable select box/text input
|
||||||
|
|
||||||
### Interested in writing your own ES6 JavaScript plugins? Check out [ES6.io](https://ES6.io/friend/JOHNSON) for great tutorials! 💪🏼
|
### Interested in writing your own ES6 JavaScript plugins? Check out [ES6.io](https://ES6.io/friend/JOHNSON) for great tutorials! 💪🏼
|
||||||
|
|
||||||
|
### Sponsored by:
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://wanderermaps.com/" target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="https://cdn.shopify.com/s/files/1/0614/3357/7715/files/Logo_BlackWithBackground_200x.png?v=1644802773" alt="Wanderer Maps logo">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Setup](#setup)
|
||||||
|
- [Terminology](#terminology)
|
||||||
|
- [Input Types](#input-types)
|
||||||
|
- [Configuration Options](#configuration-options)
|
||||||
|
- [Callbacks](#callbacks)
|
||||||
|
- [Events](#events)
|
||||||
|
- [Methods](#methods)
|
||||||
|
- [Development](#development)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
With [NPM](https://www.npmjs.com/package/choices.js):
|
With [NPM](https://www.npmjs.com/package/choices.js):
|
||||||
|
@ -45,13 +65,27 @@ From a [CDN](https://www.jsdelivr.com/package/npm/choices.js):
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/base.min.css"
|
href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/base.min.css"
|
||||||
/>
|
/>
|
||||||
|
<!-- Or versioned -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/styles/base.min.css"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Include Choices CSS -->
|
<!-- Include Choices CSS -->
|
||||||
<link
|
<link
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"
|
href="https://cdn.jsdelivr.net/npm/choices.js/public/assets/styles/choices.min.css"
|
||||||
/>
|
/>
|
||||||
<!-- Include Choices JavaScript -->
|
<!-- Or versioned -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/styles/choices.min.css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Include Choices JavaScript (latest) -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/choices.js/public/assets/scripts/choices.min.js"></script>
|
||||||
|
<!-- Or versioned -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/choices.js@9.0.1/public/assets/scripts/choices.min.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
Or include Choices directly:
|
Or include Choices directly:
|
||||||
|
@ -93,6 +127,7 @@ Or include Choices directly:
|
||||||
removeItems: true,
|
removeItems: true,
|
||||||
removeItemButton: false,
|
removeItemButton: false,
|
||||||
editItems: false,
|
editItems: false,
|
||||||
|
allowHTML: true,
|
||||||
duplicateItemsAllowed: true,
|
duplicateItemsAllowed: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
paste: true,
|
paste: true,
|
||||||
|
@ -105,7 +140,7 @@ Or include Choices directly:
|
||||||
resetScrollPosition: true,
|
resetScrollPosition: true,
|
||||||
shouldSort: true,
|
shouldSort: true,
|
||||||
shouldSortItems: false,
|
shouldSortItems: false,
|
||||||
sortFn: () => {...},
|
sorter: () => {...},
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: null,
|
placeholderValue: null,
|
||||||
searchPlaceholderValue: null,
|
searchPlaceholderValue: null,
|
||||||
|
@ -116,14 +151,16 @@ Or include Choices directly:
|
||||||
noResultsText: 'No results found',
|
noResultsText: 'No results found',
|
||||||
noChoicesText: 'No choices to choose from',
|
noChoicesText: 'No choices to choose from',
|
||||||
itemSelectText: 'Press to select',
|
itemSelectText: 'Press to select',
|
||||||
|
uniqueItemText: 'Only unique values can be added',
|
||||||
|
customAddItemText: 'Only values matching specific conditions can be added',
|
||||||
addItemText: (value) => {
|
addItemText: (value) => {
|
||||||
return `Press Enter to add <b>"${value}"</b>`;
|
return `Press Enter to add <b>"${value}"</b>`;
|
||||||
},
|
},
|
||||||
maxItemText: (maxItemCount) => {
|
maxItemText: (maxItemCount) => {
|
||||||
return `Only ${maxItemCount} values can be added`;
|
return `Only ${maxItemCount} values can be added`;
|
||||||
},
|
},
|
||||||
itemComparer: (choice, item) => {
|
valueComparer: (value1, value2) => {
|
||||||
return choice === item;
|
return value1 === value2;
|
||||||
},
|
},
|
||||||
classNames: {
|
classNames: {
|
||||||
containerOuter: 'choices',
|
containerOuter: 'choices',
|
||||||
|
@ -147,16 +184,18 @@ Or include Choices directly:
|
||||||
openState: 'is-open',
|
openState: 'is-open',
|
||||||
disabledState: 'is-disabled',
|
disabledState: 'is-disabled',
|
||||||
highlightedState: 'is-highlighted',
|
highlightedState: 'is-highlighted',
|
||||||
|
selectedState: 'is-selected',
|
||||||
flippedState: 'is-flipped',
|
flippedState: 'is-flipped',
|
||||||
loadingState: 'is-loading',
|
loadingState: 'is-loading',
|
||||||
noResults: 'has-no-results',
|
noResults: 'has-no-results',
|
||||||
noChoices: 'has-no-choices'
|
noChoices: 'has-no-choices'
|
||||||
},
|
},
|
||||||
// Choices uses the great Fuse library for searching. You
|
// Choices uses the great Fuse library for searching. You
|
||||||
// can find more options here: https://github.com/krisk/Fuse#options
|
// can find more options here: https://fusejs.io/api/options.html
|
||||||
fuseOptions: {
|
fuseOptions: {
|
||||||
include: 'score'
|
includeScore: true
|
||||||
},
|
},
|
||||||
|
labelId: '',
|
||||||
callbackOnInit: null,
|
callbackOnInit: null,
|
||||||
callbackOnCreateTemplates: null
|
callbackOnCreateTemplates: null
|
||||||
});
|
});
|
||||||
|
@ -170,13 +209,23 @@ Or include Choices directly:
|
||||||
| Group | A group is a collection of choices. A group should be seen as equivalent to a `<optgroup></optgroup>` element within a select input. |
|
| Group | A group is a collection of choices. A group should be seen as equivalent to a `<optgroup></optgroup>` element within a select input. |
|
||||||
| Item | An item is an inputted value (text input) or a selected choice (select element). In the context of a select element, an item is equivalent to a selected option element: `<option value="Hello" selected></option>` whereas in the context of a text input an item is equivalent to `<input type="text" value="Hello">` |
|
| Item | An item is an inputted value (text input) or a selected choice (select element). In the context of a select element, an item is equivalent to a selected option element: `<option value="Hello" selected></option>` whereas in the context of a text input an item is equivalent to `<input type="text" value="Hello">` |
|
||||||
|
|
||||||
## Configuration options
|
## Input Types
|
||||||
|
|
||||||
|
Choices works with the following input types, referenced in the documentation as noted.
|
||||||
|
|
||||||
|
| HTML Element | Documentation "Input Type" |
|
||||||
|
| -------------------------------------------------------------------------------------------------------| -------------------------- |
|
||||||
|
| [`<input type="text">`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input) | `text` |
|
||||||
|
| [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select) | `select-one` |
|
||||||
|
| [`<select multiple>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#attr-multiple) | `select-multiple` |
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
### silent
|
### silent
|
||||||
|
|
||||||
**Type:** `Boolean` **Default:** `false`
|
**Type:** `Boolean` **Default:** `false`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-single`, `select-multiple`
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
**Usage:** Optionally suppress console errors and warnings.
|
**Usage:** Optionally suppress console errors and warnings.
|
||||||
|
|
||||||
|
@ -287,6 +336,16 @@ Pass an array of objects:
|
||||||
|
|
||||||
**Usage:** Whether a user can edit items. An item's value can be edited by pressing the backspace.
|
**Usage:** Whether a user can edit items. An item's value can be edited by pressing the backspace.
|
||||||
|
|
||||||
|
### allowHTML
|
||||||
|
|
||||||
|
**Type:** `Boolean` **Default:** `true`
|
||||||
|
|
||||||
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
**Usage:** Whether HTML should be rendered in all Choices elements. If `false`, all elements (placeholder, items, etc.) will be treated as plain text. If `true`, this can be used to perform XSS scripting attacks if you load choices from a remote source.
|
||||||
|
|
||||||
|
**Deprecation Warning:** This will default to `false` in a future release.
|
||||||
|
|
||||||
### duplicateItemsAllowed
|
### duplicateItemsAllowed
|
||||||
|
|
||||||
**Type:** `Boolean` **Default:** `true`
|
**Type:** `Boolean` **Default:** `true`
|
||||||
|
@ -301,7 +360,7 @@ Pass an array of objects:
|
||||||
|
|
||||||
**Input types affected:** `text`
|
**Input types affected:** `text`
|
||||||
|
|
||||||
**Usage:** What divides each value. The default delimiter seperates each value with a comma: `"Value 1, Value 2, Value 3"`.
|
**Usage:** What divides each value. The default delimiter separates each value with a comma: `"Value 1, Value 2, Value 3"`.
|
||||||
|
|
||||||
### paste
|
### paste
|
||||||
|
|
||||||
|
@ -408,7 +467,7 @@ new Choices(element, {
|
||||||
|
|
||||||
**Usage:** Whether items should be sorted. If false, items will appear in the order they were selected.
|
**Usage:** Whether items should be sorted. If false, items will appear in the order they were selected.
|
||||||
|
|
||||||
### sortFn
|
### sorter
|
||||||
|
|
||||||
**Type:** `Function` **Default:** sortByAlpha
|
**Type:** `Function` **Default:** sortByAlpha
|
||||||
|
|
||||||
|
@ -421,7 +480,7 @@ new Choices(element, {
|
||||||
```js
|
```js
|
||||||
// Sorting via length of label from largest to smallest
|
// Sorting via length of label from largest to smallest
|
||||||
const example = new Choices(element, {
|
const example = new Choices(element, {
|
||||||
sortFn: function(a, b) {
|
sorter: function(a, b) {
|
||||||
return b.label.length - a.label.length;
|
return b.label.length - a.label.length;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -431,11 +490,11 @@ const example = new Choices(element, {
|
||||||
|
|
||||||
**Type:** `Boolean` **Default:** `true`
|
**Type:** `Boolean` **Default:** `true`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-multiple`
|
**Input types affected:** `text`
|
||||||
|
|
||||||
**Usage:** Whether the input should show a placeholder. Used in conjunction with `placeholderValue`. If `placeholder` is set to true and no value is passed to `placeholderValue`, the passed input's placeholder attribute will be used as the placeholder value.
|
**Usage:** Whether the input should show a placeholder. Used in conjunction with `placeholderValue`. If `placeholder` is set to true and no value is passed to `placeholderValue`, the passed input's placeholder attribute will be used as the placeholder value.
|
||||||
|
|
||||||
**Note:** For single select boxes, the recommended way of adding a placeholder is as follows:
|
**Note:** For select boxes, the recommended way of adding a placeholder is as follows:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<select>
|
<select>
|
||||||
|
@ -452,7 +511,7 @@ For backward compatibility, `<option placeholder>This is a placeholder</option>`
|
||||||
|
|
||||||
**Type:** `String` **Default:** `null`
|
**Type:** `String` **Default:** `null`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-multiple`
|
**Input types affected:** `text`
|
||||||
|
|
||||||
**Usage:** The value of the inputs placeholder.
|
**Usage:** The value of the inputs placeholder.
|
||||||
|
|
||||||
|
@ -536,13 +595,29 @@ For backward compatibility, `<option placeholder>This is a placeholder</option>`
|
||||||
|
|
||||||
**Usage:** The text that is shown when a user has focus on the input but has already reached the [max item count](https://github.com/jshjohnson/Choices#maxitemcount). To access the max item count, pass a function with a `maxItemCount` argument (see the [default config](https://github.com/jshjohnson/Choices#setup) for an example), otherwise pass a string.
|
**Usage:** The text that is shown when a user has focus on the input but has already reached the [max item count](https://github.com/jshjohnson/Choices#maxitemcount). To access the max item count, pass a function with a `maxItemCount` argument (see the [default config](https://github.com/jshjohnson/Choices#setup) for an example), otherwise pass a string.
|
||||||
|
|
||||||
### itemComparer
|
### valueComparer
|
||||||
|
|
||||||
**Type:** `Function` **Default:** `strict equality`
|
**Type:** `Function` **Default:** `strict equality`
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
**Usage:** Compare choice and value in appropriate way (e.g. deep equality for objects). To compare choice and value, pass a function with a `itemComparer` argument (see the [default config](https://github.com/jshjohnson/Choices#setup) for an example).
|
**Usage:** A custom compare function used when finding choices by value (using `setChoiceByValue`).
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
|
```js
|
||||||
|
const example = new Choices(element, {
|
||||||
|
valueComparer: (a, b) => value.trim() === b.trim(),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### labelId
|
||||||
|
|
||||||
|
**Type:** `String` **Default:** ``
|
||||||
|
|
||||||
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
**Usage:** The labelId improves accessibility. If set, it will add aria-labelledby to the choices element.
|
||||||
|
|
||||||
### classNames
|
### classNames
|
||||||
|
|
||||||
|
@ -570,6 +645,7 @@ classNames: {
|
||||||
openState: 'is-open',
|
openState: 'is-open',
|
||||||
disabledState: 'is-disabled',
|
disabledState: 'is-disabled',
|
||||||
highlightedState: 'is-highlighted',
|
highlightedState: 'is-highlighted',
|
||||||
|
selectedState: 'is-selected',
|
||||||
flippedState: 'is-flipped',
|
flippedState: 'is-flipped',
|
||||||
selectedState: 'is-highlighted',
|
selectedState: 'is-highlighted',
|
||||||
}
|
}
|
||||||
|
@ -597,10 +673,12 @@ classNames: {
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-one`, `select-multiple`
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
**Usage:** Function to run on template creation. Through this callback it is possible to provide custom templates for the various components of Choices (see terminology). For Choices to work with custom templates, it is important you maintain the various data attributes defined [here](https://github.com/jshjohnson/Choices/blob/master/src/scripts/templates.js).
|
**Usage:** Function to run on template creation. Through this callback it is possible to provide custom templates for the various components of Choices (see terminology). For Choices to work with custom templates, it is important you maintain the various data attributes defined [here](https://github.com/Choices-js/Choices/blob/master/src/scripts/templates.ts).
|
||||||
If you want just extend a little original template then you may use `Choices.defaults.templates` to get access to
|
If you want just extend a little original template then you may use `Choices.defaults.templates` to get access to
|
||||||
original template function.
|
original template function.
|
||||||
|
|
||||||
|
Templates receive the full Choices config as the first argument to any template, which allows you to conditionally display things based on the options specified.
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -620,7 +698,7 @@ or more complex:
|
||||||
const example = new Choices(element, {
|
const example = new Choices(element, {
|
||||||
callbackOnCreateTemplates: function(template) {
|
callbackOnCreateTemplates: function(template) {
|
||||||
return {
|
return {
|
||||||
item: (classNames, data) => {
|
item: ({ classNames }, data) => {
|
||||||
return template(`
|
return template(`
|
||||||
<div class="${classNames.item} ${
|
<div class="${classNames.item} ${
|
||||||
data.highlighted
|
data.highlighted
|
||||||
|
@ -635,7 +713,7 @@ const example = new Choices(element, {
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
},
|
},
|
||||||
choice: (classNames, data) => {
|
choice: ({ classNames }, data) => {
|
||||||
return template(`
|
return template(`
|
||||||
<div class="${classNames.item} ${classNames.itemChoice} ${
|
<div class="${classNames.item} ${classNames.itemChoice} ${
|
||||||
data.disabled ? classNames.itemDisabled : classNames.itemSelectable
|
data.disabled ? classNames.itemDisabled : classNames.itemSelectable
|
||||||
|
@ -697,7 +775,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### addItem
|
### addItem
|
||||||
|
|
||||||
**Arguments:** `id, value, label, groupValue, keyCode`
|
**Payload:** `id, value, label, customProperties, groupValue, keyCode`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-one`, `select-multiple`
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -705,7 +783,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### removeItem
|
### removeItem
|
||||||
|
|
||||||
**Arguments:** `id, value, label, groupValue`
|
**Payload:** `id, value, label, customProperties, groupValue`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-one`, `select-multiple`
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -713,7 +791,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### highlightItem
|
### highlightItem
|
||||||
|
|
||||||
**Arguments:** `id, value, label, groupValue`
|
**Payload:** `id, value, label, groupValue`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-multiple`
|
**Input types affected:** `text`, `select-multiple`
|
||||||
|
|
||||||
|
@ -721,7 +799,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### unhighlightItem
|
### unhighlightItem
|
||||||
|
|
||||||
**Arguments:** `id, value, label, groupValue`
|
**Payload:** `id, value, label, groupValue`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-multiple`
|
**Input types affected:** `text`, `select-multiple`
|
||||||
|
|
||||||
|
@ -729,7 +807,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### choice
|
### choice
|
||||||
|
|
||||||
**Arguments:** `choice`
|
**Payload:** `choice`
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -738,7 +816,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### change
|
### change
|
||||||
|
|
||||||
**Arguments:** `value`
|
**Payload:** `value`
|
||||||
|
|
||||||
**Input types affected:** `text`, `select-one`, `select-multiple`
|
**Input types affected:** `text`, `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -746,7 +824,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### search
|
### search
|
||||||
|
|
||||||
**Arguments:** `value`, `resultCount`
|
**Payload:** `value`, `resultCount`
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -754,7 +832,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### showDropdown
|
### showDropdown
|
||||||
|
|
||||||
**Arguments:** -
|
**Payload:** -
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -762,7 +840,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### hideDropdown
|
### hideDropdown
|
||||||
|
|
||||||
**Arguments:** -
|
**Payload:** -
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -770,7 +848,7 @@ example.passedElement.element.addEventListener(
|
||||||
|
|
||||||
### highlightChoice
|
### highlightChoice
|
||||||
|
|
||||||
**Arguments:** `el`
|
**Payload:** `el`
|
||||||
|
|
||||||
**Input types affected:** `select-one`, `select-multiple`
|
**Input types affected:** `select-one`, `select-multiple`
|
||||||
|
|
||||||
|
@ -1026,15 +1104,15 @@ example.setChoiceByValue('Two'); // Choice with value of 'Two' has now been sele
|
||||||
|
|
||||||
## Browser compatibility
|
## Browser compatibility
|
||||||
|
|
||||||
Choices is compiled using [Babel](https://babeljs.io/) targeting browsers [with more that 1% of global usage](https://github.com/jshjohnson/Choices/blob/master/.browserslistrc) and expecting that features [listed below](https://github.com/jshjohnson/Choices/blob/master/.eslintrc.json#L62) are available or polyfilled in browser.
|
Choices is compiled using [Babel](https://babeljs.io/) targeting browsers [with more than 1% of global usage](https://github.com/jshjohnson/Choices/blob/master/.browserslistrc) and expecting that features [listed below](https://github.com/jshjohnson/Choices/blob/master/.eslintrc.json#L62) are available or polyfilled in browser.
|
||||||
You may see exact list of target browsers by running `npx browserslist` withing this repository folder.
|
You may see exact list of target browsers by running `npx browserslist` within this repository folder.
|
||||||
If you need to support a browser that does not have one of the features listed below,
|
If you need to support a browser that does not have one of the features listed below,
|
||||||
I suggest including a polyfill from the very good [polyfill.io](https://polyfill.io/v3/):
|
I suggest including a polyfill from the very good [polyfill.io](https://polyfill.io/v3/):
|
||||||
|
|
||||||
**Polyfill example used for the demo:**
|
**Polyfill example used for the demo:**
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=es5,es6,fetch,Array.prototype.includes,CustomEvent,Element.prototype.closest"></script>
|
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=Array.from%2Ces5%2Ces6%2CSymbol%2CSymbol.iterator%2CDOMTokenList%2CObject.assign%2CCustomEvent%2CElement.prototype.classList%2CElement.prototype.closest%2CElement.prototype.dataset%2CArray.prototype.find%2CArray.prototype.includes"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
**Features used in Choices:**
|
**Features used in Choices:**
|
||||||
|
@ -1045,15 +1123,17 @@ Array.prototype.find
|
||||||
Array.prototype.includes
|
Array.prototype.includes
|
||||||
Symbol
|
Symbol
|
||||||
Symbol.iterator
|
Symbol.iterator
|
||||||
|
DOMTokenList
|
||||||
Object.assign
|
Object.assign
|
||||||
CustomEvent
|
CustomEvent
|
||||||
Element.prototype.classList
|
Element.prototype.classList
|
||||||
Element.prototype.closest
|
Element.prototype.closest
|
||||||
|
Element.prototype.dataset
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
To setup a local environment: clone this repo, navigate into it's directory in a terminal window and run the following command:
|
To setup a local environment: clone this repo, navigate into its directory in a terminal window and run the following command:
|
||||||
|
|
||||||
`npm install`
|
`npm install`
|
||||||
|
|
||||||
|
@ -1072,6 +1152,10 @@ To setup a local environment: clone this repo, navigate into it's directory in a
|
||||||
| `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 |
|
||||||
| `npm run css:build` | Compile, minify and prefix SCSS files to CSS |
|
| `npm run css:build` | Compile, minify and prefix SCSS files to CSS |
|
||||||
|
|
||||||
|
### Interested in contributing?
|
||||||
|
|
||||||
|
We're always interested in having more active maintainers. Please get in touch if you're interested 👍
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
|
@ -42,6 +42,7 @@ global.HTMLSelectElement = window.HTMLSelectElement;
|
||||||
global.HTMLInputElement = window.HTMLInputElement;
|
global.HTMLInputElement = window.HTMLInputElement;
|
||||||
global.DocumentFragment = window.DocumentFragment;
|
global.DocumentFragment = window.DocumentFragment;
|
||||||
global.requestAnimationFrame = window.requestAnimationFrame;
|
global.requestAnimationFrame = window.requestAnimationFrame;
|
||||||
|
window.matchMedia = () => true;
|
||||||
|
|
||||||
copyProps(window, global);
|
copyProps(window, global);
|
||||||
|
|
||||||
|
|
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}',
|
||||||
|
},
|
||||||
|
})
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"baseUrl": "http://localhost:3001/test",
|
|
||||||
"video": false,
|
|
||||||
"projectId": "n7g5qp"
|
|
||||||
}
|
|
|
@ -1,6 +1,10 @@
|
||||||
describe('Choices - select multiple', () => {
|
describe('Choices - select multiple', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/select-multiple.html');
|
cy.visit('/select-multiple', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
|
@ -30,6 +34,7 @@ describe('Choices - select multiple', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__input--cloned')
|
.find('.choices__input--cloned')
|
||||||
|
.wait(200) // Otherwise these tests are flaky
|
||||||
.type('{esc}');
|
.type('{esc}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,7 +67,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -72,7 +77,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -80,7 +85,7 @@ describe('Choices - select multiple', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
expect($select.val()).to.contain(selectedChoiceText);
|
expect($select.val()).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -89,7 +94,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.each($choice => {
|
.each(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.equal(selectedChoiceText);
|
expect($choice.text().trim()).to.not.equal(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -114,7 +119,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal('No choices to choose from');
|
expect(dropdownText).to.equal('No choices to choose from');
|
||||||
});
|
});
|
||||||
|
@ -130,7 +135,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
removedChoiceText = $choice.text().trim();
|
removedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -151,7 +156,7 @@ describe('Choices - select multiple', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
expect(val).to.not.contain(removedChoiceText);
|
expect(val).to.not.contain(removedChoiceText);
|
||||||
});
|
});
|
||||||
|
@ -171,7 +176,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 2');
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -187,7 +192,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 3');
|
expect($choice.text().trim()).to.equal('Choice 3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -202,7 +207,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal('No results found');
|
expect(dropdownText).to.equal('No results found');
|
||||||
});
|
});
|
||||||
|
@ -346,10 +351,10 @@ describe('Choices - select multiple', () => {
|
||||||
|
|
||||||
describe('selection limit', () => {
|
describe('selection limit', () => {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const selectionLimit = 5;
|
const selectionLimit = 5;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -370,7 +375,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=selection-limit]')
|
cy.get('[data-test-hook=selection-limit]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
`Only ${selectionLimit} values can be added`,
|
`Only ${selectionLimit} values can be added`,
|
||||||
|
@ -397,7 +402,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -407,7 +412,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(
|
expect($choice.data('value')).to.equal(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -418,7 +423,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(
|
expect($choice.text()).to.not.contain(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -460,7 +465,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.contain(searchTerm);
|
expect($choice.text().trim()).to.not.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -478,7 +483,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.contain(searchTerm);
|
expect($choice.text().trim()).to.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -486,20 +491,42 @@ describe('Choices - select multiple', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('placeholder', () => {
|
describe('placeholder via empty option value', () => {
|
||||||
/*
|
|
||||||
{
|
|
||||||
placeholder: true,
|
|
||||||
placeholderValue: 'I am a placeholder',
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
describe('when no value has been inputted', () => {
|
describe('when no value has been inputted', () => {
|
||||||
it('displays a placeholder', () => {
|
it('displays a placeholder', () => {
|
||||||
cy.get('[data-test-hook=placeholder]')
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
.find('.choices__input--cloned')
|
.find('.choices__input--cloned')
|
||||||
.should('have.attr', 'placeholder', 'I am a placeholder');
|
.should('have.attr', 'placeholder', 'I am a placeholder');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when a value has been inputted', () => {
|
||||||
|
it('does not display a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('test')
|
||||||
|
.should('not.have.value', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('placeholder via option attribute', () => {
|
||||||
|
describe('when no value has been inputted', () => {
|
||||||
|
it('displays a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('have.attr', 'placeholder', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a value has been inputted', () => {
|
||||||
|
it('does not display a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('test')
|
||||||
|
.should('not.have.value', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('remote data', () => {
|
describe('remote data', () => {
|
||||||
|
@ -548,7 +575,7 @@ describe('Choices - select multiple', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__item')
|
.find('.choices__list--dropdown .choices__list .choices__item')
|
||||||
.then($choices => {
|
.then(($choices) => {
|
||||||
choicesCount = $choices.length;
|
choicesCount = $choices.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -560,19 +587,20 @@ describe('Choices - select multiple', () => {
|
||||||
it('highlights first choice on dropdown open', () => {
|
it('highlights first choice on dropdown open', () => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 1');
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('scrolls to next choice on down arrow', () => {
|
it('scrolls to next choice on down arrow', () => {
|
||||||
for (let index = 0; index < choicesCount; index++) {
|
for (let index = 1; index <= choicesCount; index++) {
|
||||||
cy.wait(100);
|
cy.wait(100);
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.invoke('text')
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
.then((text) => {
|
||||||
|
expect(text.trim()).to.equal(`Choice ${index}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
|
@ -595,8 +623,9 @@ describe('Choices - select multiple', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.invoke('text')
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index}`);
|
.then((text) => {
|
||||||
|
expect(text.trim()).to.equal(`Choice ${index}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
|
@ -614,7 +643,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.then($group => {
|
.then(($group) => {
|
||||||
groupValue = $group.text().trim();
|
groupValue = $group.text().trim();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -635,7 +664,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.not.equal(groupValue);
|
expect($group.text().trim()).to.not.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -666,7 +695,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.equal(groupValue);
|
expect($group.text().trim()).to.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -706,7 +735,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(city);
|
expect($choice.text().trim()).to.equal(city);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -718,13 +747,75 @@ describe('Choices - select multiple', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('non-string values', () => {
|
describe('custom properties via HTML', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
.find('.choices')
|
.find('.choices')
|
||||||
.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('on input', () => {
|
||||||
|
it('filters choices based on a string custom property', () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
searchText: 'fantastic',
|
||||||
|
label: 'Label Three',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(({ searchText, label }) => {
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(searchText);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal(label);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{selectall}{del}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters choices based on a JSON custom property', () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
searchText: 'foo',
|
||||||
|
label: 'Label Four',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(({ searchText, label }) => {
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(searchText);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal(label);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{selectall}{del}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('non-string values', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=non-string-values]').find('.choices').click();
|
||||||
|
});
|
||||||
|
|
||||||
it('displays expected amount of choices in dropdown', () => {
|
it('displays expected amount of choices in dropdown', () => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
@ -738,7 +829,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
$selectedChoice = $choice;
|
$selectedChoice = $choice;
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -746,7 +837,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -756,7 +847,7 @@ describe('Choices - select multiple', () => {
|
||||||
describe('selecting choice', () => {
|
describe('selecting choice', () => {
|
||||||
describe('on enter key', () => {
|
describe('on enter key', () => {
|
||||||
it('selects choice', () => {
|
it('selects choice', () => {
|
||||||
cy.get('[data-test-hook=within-form] form').then($form => {
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
$form.submit(() => {
|
$form.submit(() => {
|
||||||
// this will fail the test if the form submits
|
// this will fail the test if the form submits
|
||||||
throw new Error('Form submitted');
|
throw new Error('Form submitted');
|
||||||
|
@ -771,7 +862,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain('Choice 1');
|
expect($item).to.contain('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -786,7 +877,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(
|
expect($choice.text().trim()).to.equal(
|
||||||
dynamicallySelectedChoiceValue,
|
dynamicallySelectedChoiceValue,
|
||||||
);
|
);
|
||||||
|
@ -797,7 +888,7 @@ describe('Choices - select multiple', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.each($choice => {
|
.each(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.equal(
|
expect($choice.text().trim()).to.not.equal(
|
||||||
dynamicallySelectedChoiceValue,
|
dynamicallySelectedChoiceValue,
|
||||||
);
|
);
|
||||||
|
@ -807,7 +898,7 @@ describe('Choices - select multiple', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
||||||
});
|
});
|
||||||
|
@ -824,7 +915,7 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('No results found');
|
expect($choice.text().trim()).to.equal('No results found');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -838,10 +929,83 @@ describe('Choices - select multiple', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('label1');
|
expect($choice.text().trim()).to.equal('label1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text in dropdown', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-undefined]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not show html as text in dropdown', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text when selected', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--multiple .choices__item')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 1</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 2</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -1,48 +1,63 @@
|
||||||
describe('Choices - select one', () => {
|
describe('Choices - select one', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/select-one.html');
|
cy.visit('/select-one', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
describe('basic', () => {
|
describe('basic', () => {
|
||||||
beforeEach(() => {
|
describe('focusing on container', () => {
|
||||||
// open dropdown
|
describe('pressing enter key', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
it('toggles the dropdown', () => {
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('focusing on text input', () => {
|
|
||||||
it('displays a dropdown of choices', () => {
|
|
||||||
cy.get('[data-test-hook=basic]')
|
|
||||||
.find('.choices__list--dropdown')
|
|
||||||
.should('be.visible');
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=basic]')
|
|
||||||
.find('.choices__list--dropdown .choices__list')
|
|
||||||
.children()
|
|
||||||
.should('have.length', 4)
|
|
||||||
.each(($choice, index) => {
|
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('pressing escape', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__input--cloned')
|
.find('.choices')
|
||||||
.type('{esc}');
|
.focus()
|
||||||
});
|
.type('{enter}');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices')
|
||||||
|
.focus()
|
||||||
|
.type('{enter}');
|
||||||
|
|
||||||
it('closes the dropdown', () => {
|
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('not.be.visible');
|
.should('not.be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('pressing an alpha-numeric key', () => {
|
||||||
|
it('opens the dropdown and the input value', () => {
|
||||||
|
const inputValue = 'test';
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices')
|
||||||
|
.focus()
|
||||||
|
.type(inputValue);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__list--dropdown')
|
||||||
|
.should('be.visible');
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=basic]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('have.value', inputValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('selecting choices', () => {
|
describe('selecting choices', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// open dropdown
|
||||||
|
cy.get('[data-test-hook=basic]').find('.choices').click();
|
||||||
|
});
|
||||||
|
|
||||||
const selectedChoiceText = 'Choice 1';
|
const selectedChoiceText = 'Choice 1';
|
||||||
|
|
||||||
it('allows selecting choices from dropdown', () => {
|
it('allows selecting choices from dropdown', () => {
|
||||||
|
@ -55,7 +70,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -71,13 +86,18 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('searching choices', () => {
|
describe('searching choices', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// open dropdown
|
||||||
|
cy.get('[data-test-hook=basic]').find('.choices').click();
|
||||||
|
});
|
||||||
|
|
||||||
describe('on input', () => {
|
describe('on input', () => {
|
||||||
describe('searching by label', () => {
|
describe('searching by label', () => {
|
||||||
it('displays choices filtered by inputted value', () => {
|
it('displays choices filtered by inputted value', () => {
|
||||||
|
@ -89,7 +109,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 2');
|
expect($choice.text().trim()).to.equal('Choice 2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -105,7 +125,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 3');
|
expect($choice.text().trim()).to.equal('Choice 3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -120,7 +140,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal('No results found');
|
expect(dropdownText).to.equal('No results found');
|
||||||
});
|
});
|
||||||
|
@ -186,7 +206,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
removedChoiceText = $choice.text().trim();
|
removedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -209,7 +229,7 @@ describe('Choices - select one', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
|
|
||||||
expect(val).to.not.contain(removedChoiceText);
|
expect(val).to.not.contain(removedChoiceText);
|
||||||
|
@ -228,7 +248,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=disabled-choice]')
|
cy.get('[data-test-hook=disabled-choice]')
|
||||||
.find('.choices__list--dropdown .choices__item--disabled')
|
.find('.choices__list--dropdown .choices__item--disabled')
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -238,7 +258,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(selectedChoiceText);
|
expect($choice.text()).to.not.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -285,9 +305,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('on click', () => {
|
describe('on click', () => {
|
||||||
it('does not open choice dropdown', () => {
|
it('does not open choice dropdown', () => {
|
||||||
cy.get('[data-test-hook=disabled-via-attr]')
|
cy.get('[data-test-hook=disabled-via-attr]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=disabled-via-attr]')
|
cy.get('[data-test-hook=disabled-via-attr]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
|
@ -315,7 +333,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.last()
|
.last()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
selectedChoiceText = $choice.text().trim();
|
selectedChoiceText = $choice.text().trim();
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -325,7 +343,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(
|
expect($choice.data('value')).to.equal(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -336,7 +354,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(
|
expect($choice.text()).to.not.contain(
|
||||||
`before-${selectedChoiceText}-after`,
|
`before-${selectedChoiceText}-after`,
|
||||||
);
|
);
|
||||||
|
@ -369,9 +387,7 @@ describe('Choices - select one', () => {
|
||||||
const selectedChoiceText = 'Choice 3';
|
const selectedChoiceText = 'Choice 3';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=search-disabled]')
|
cy.get('[data-test-hook=search-disabled]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not display a search input', () => {
|
it('does not display a search input', () => {
|
||||||
|
@ -390,7 +406,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=search-disabled]')
|
cy.get('[data-test-hook=search-disabled]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain(selectedChoiceText);
|
expect($item).to.contain(selectedChoiceText);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -422,7 +438,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.not.contain(searchTerm);
|
expect($choice.text().trim()).to.not.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -440,7 +456,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.contain(searchTerm);
|
expect($choice.text().trim()).to.contain(searchTerm);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -448,6 +464,102 @@ describe('Choices - select one', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('placeholder via empty option value', () => {
|
||||||
|
describe('when no choice has been selected', () => {
|
||||||
|
it('displays a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__list--single')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should('have.class', 'choices__placeholder')
|
||||||
|
.and(($placeholder) => {
|
||||||
|
expect($placeholder).to.contain('I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a choice has been selected', () => {
|
||||||
|
it('does not display a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('not.have.value', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when choice list is open', () => {
|
||||||
|
it('displays the placeholder choice first', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-value]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should('have.class', 'choices__placeholder')
|
||||||
|
.should('have.text', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('placeholder via option attribute', () => {
|
||||||
|
describe('when no choice has been selected', () => {
|
||||||
|
it('displays a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__list--single')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should('have.class', 'choices__placeholder')
|
||||||
|
.and(($placeholder) => {
|
||||||
|
expect($placeholder).to.contain('I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when a choice has been selected', () => {
|
||||||
|
it('does not display a placeholder', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.should('not.have.value', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when choice list is open', () => {
|
||||||
|
it('displays the placeholder choice first', () => {
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.focus();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=placeholder-via-option-attr]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should('have.class', 'choices__placeholder')
|
||||||
|
.should('have.text', 'I am a placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('remote data', () => {
|
describe('remote data', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.reload(true);
|
cy.reload(true);
|
||||||
|
@ -458,9 +570,10 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=remote-data]')
|
cy.get('[data-test-hook=remote-data]')
|
||||||
.find('.choices__list--single')
|
.find('.choices__list--single')
|
||||||
.children()
|
.children()
|
||||||
|
.should('have.length', 1)
|
||||||
.first()
|
.first()
|
||||||
.should('have.class', 'choices__placeholder')
|
.should('have.class', 'choices__placeholder')
|
||||||
.and($placeholder => {
|
.and(($placeholder) => {
|
||||||
expect($placeholder).to.contain('Loading...');
|
expect($placeholder).to.contain('Loading...');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -483,10 +596,14 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=remote-data]')
|
cy.get('[data-test-hook=remote-data]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.should('have.length', 50)
|
.should('have.length', 51) // 50 choices + 1 placeholder choice
|
||||||
.each(($choice, index) => {
|
.each(($choice, index) => {
|
||||||
expect($choice.text().trim()).to.equal(`Label ${index + 1}`);
|
if (index === 0) {
|
||||||
expect($choice.data('value')).to.equal(`Value ${index + 1}`);
|
expect($choice.text().trim()).to.equal('I am a placeholder');
|
||||||
|
} else {
|
||||||
|
expect($choice.text().trim()).to.equal(`Label ${index}`);
|
||||||
|
expect($choice.data('value')).to.equal(`Value ${index}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -499,19 +616,17 @@ describe('Choices - select one', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__item')
|
.find('.choices__list--dropdown .choices__list .choices__item')
|
||||||
.then($choices => {
|
.then(($choices) => {
|
||||||
choicesCount = $choices.length;
|
choicesCount = $choices.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('highlights first choice on dropdown open', () => {
|
it('highlights first choice on dropdown open', () => {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Choice 1');
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -520,7 +635,7 @@ describe('Choices - select one', () => {
|
||||||
for (let index = 0; index < choicesCount; index++) {
|
for (let index = 0; index < choicesCount; index++) {
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
expect($choice.text().trim()).to.equal(`Choice ${index + 1}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -544,7 +659,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=scrolling-dropdown]')
|
cy.get('[data-test-hook=scrolling-dropdown]')
|
||||||
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
.find('.choices__list--dropdown .choices__list .is-highlighted')
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(`Choice ${index}`);
|
expect($choice.text().trim()).to.equal(`Choice ${index}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -563,7 +678,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.then($group => {
|
.then(($group) => {
|
||||||
groupValue = $group.text().trim();
|
groupValue = $group.text().trim();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -584,7 +699,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.not.equal(groupValue);
|
expect($group.text().trim()).to.not.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -615,7 +730,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=groups]')
|
cy.get('[data-test-hook=groups]')
|
||||||
.find('.choices__list--dropdown .choices__list .choices__group')
|
.find('.choices__list--dropdown .choices__list .choices__group')
|
||||||
.first()
|
.first()
|
||||||
.should($group => {
|
.should(($group) => {
|
||||||
expect($group.text().trim()).to.equal(groupValue);
|
expect($group.text().trim()).to.equal(groupValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -685,9 +800,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('custom properties', () => {
|
describe('custom properties', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=custom-properties]')
|
cy.get('[data-test-hook=custom-properties]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('on input', () => {
|
describe('on input', () => {
|
||||||
|
@ -716,7 +829,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(city);
|
expect($choice.text().trim()).to.equal(city);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -728,13 +841,75 @@ describe('Choices - select one', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('non-string values', () => {
|
describe('custom properties via HTML', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
.find('.choices')
|
.find('.choices')
|
||||||
.click();
|
.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('on input', () => {
|
||||||
|
it('filters choices based on a string custom property', () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
searchText: 'fantastic',
|
||||||
|
label: 'Label Three',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(({ searchText, label }) => {
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(searchText);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal(label);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{selectall}{del}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filters choices based on a JSON custom property', () => {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
searchText: 'foo',
|
||||||
|
label: 'Label Four',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(({ searchText, label }) => {
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type(searchText);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal(label);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=custom-properties-html]')
|
||||||
|
.find('.choices__input--cloned')
|
||||||
|
.type('{selectall}{del}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('non-string values', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=non-string-values]').find('.choices').click();
|
||||||
|
});
|
||||||
|
|
||||||
it('displays expected amount of choices in dropdown', () => {
|
it('displays expected amount of choices in dropdown', () => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
@ -748,7 +923,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.then($choice => {
|
.then(($choice) => {
|
||||||
$selectedChoice = $choice;
|
$selectedChoice = $choice;
|
||||||
})
|
})
|
||||||
.click();
|
.click();
|
||||||
|
@ -756,7 +931,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=non-string-values]')
|
cy.get('[data-test-hook=non-string-values]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
expect($item.text().trim()).to.equal($selectedChoice.text().trim());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -766,7 +941,7 @@ describe('Choices - select one', () => {
|
||||||
describe('selecting choice', () => {
|
describe('selecting choice', () => {
|
||||||
describe('on enter key', () => {
|
describe('on enter key', () => {
|
||||||
it('does not submit form', () => {
|
it('does not submit form', () => {
|
||||||
cy.get('[data-test-hook=within-form] form').then($form => {
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
$form.submit(() => {
|
$form.submit(() => {
|
||||||
// this will fail the test if the form submits
|
// this will fail the test if the form submits
|
||||||
throw new Error('Form submitted');
|
throw new Error('Form submitted');
|
||||||
|
@ -779,14 +954,12 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__input--cloned')
|
.find('.choices__input--cloned')
|
||||||
.type('{enter}');
|
.type('{enter}');
|
||||||
|
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($item => {
|
.should(($item) => {
|
||||||
expect($item).to.contain('Choice 1');
|
expect($item).to.contain('Choice 1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -801,7 +974,7 @@ describe('Choices - select one', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--single .choices__item')
|
.find('.choices__list--single .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(
|
expect($choice.text().trim()).to.equal(
|
||||||
dynamicallySelectedChoiceValue,
|
dynamicallySelectedChoiceValue,
|
||||||
);
|
);
|
||||||
|
@ -811,7 +984,7 @@ describe('Choices - select one', () => {
|
||||||
it('does not remove choice from dropdown list', () => {
|
it('does not remove choice from dropdown list', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.then($choicesList => {
|
.then(($choicesList) => {
|
||||||
expect($choicesList).to.contain(dynamicallySelectedChoiceValue);
|
expect($choicesList).to.contain(dynamicallySelectedChoiceValue);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -819,7 +992,7 @@ describe('Choices - select one', () => {
|
||||||
it('updates the value of the original input', () => {
|
it('updates the value of the original input', () => {
|
||||||
cy.get('[data-test-hook=set-choice-by-value]')
|
cy.get('[data-test-hook=set-choice-by-value]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.should($select => {
|
.should(($select) => {
|
||||||
const val = $select.val() || [];
|
const val = $select.val() || [];
|
||||||
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
expect(val).to.contain(dynamicallySelectedChoiceValue);
|
||||||
});
|
});
|
||||||
|
@ -828,9 +1001,7 @@ describe('Choices - select one', () => {
|
||||||
|
|
||||||
describe('searching by label only', () => {
|
describe('searching by label only', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.get('[data-test-hook=search-by-label]')
|
cy.get('[data-test-hook=search-by-label]').find('.choices').click();
|
||||||
.find('.choices')
|
|
||||||
.click();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets zero results when searching by value', () => {
|
it('gets zero results when searching by value', () => {
|
||||||
|
@ -842,7 +1013,7 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('No results found');
|
expect($choice.text().trim()).to.equal('No results found');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -856,10 +1027,123 @@ describe('Choices - select one', () => {
|
||||||
.find('.choices__list--dropdown .choices__list')
|
.find('.choices__list--dropdown .choices__list')
|
||||||
.children()
|
.children()
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('label1');
|
expect($choice.text().trim()).to.equal('label1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('disabling first choice via options', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
|
.find('.choices')
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
|
||||||
|
let disabledValue;
|
||||||
|
|
||||||
|
it('disables the first choice', () => {
|
||||||
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should('have.class', 'choices__item--disabled')
|
||||||
|
.then(($choice) => {
|
||||||
|
disabledValue = $choice.val();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('selects the first enabled choice', () => {
|
||||||
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
|
.find('.choices__input[hidden]')
|
||||||
|
.then(($option) => {
|
||||||
|
expect($option.text().trim()).to.not.equal(disabledValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=disabled-first-choice-via-options]')
|
||||||
|
.find('.choices__item.choices__item--selectable')
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.not.equal(disabledValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to true', () => {
|
||||||
|
it('does not show html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-true]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('Choice 1');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('set to false', () => {
|
||||||
|
it('shows html as text', () => {
|
||||||
|
cy.get('[data-test-hook=allowhtml-false]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.first()
|
||||||
|
.should(($choice) => {
|
||||||
|
expect($choice.text().trim()).to.equal('<b>Choice 1</b>');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('re-initialising a choices instance', () => {
|
||||||
|
it('preserves the choices list', () => {
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.should('have.length', 3);
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
.find('button.destroy')
|
||||||
|
.click();
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]').find('button.init').click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
.find('.choices__list--dropdown .choices__list')
|
||||||
|
.children()
|
||||||
|
.should('have.length', 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('destroying the choices instance', () => {
|
||||||
|
it('preserves the original select element', () => {
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
.find('button.destroy')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-test-hook=new-destroy-init]')
|
||||||
|
.find('select')
|
||||||
|
.children()
|
||||||
|
.should('have.length', 3);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -1,6 +1,10 @@
|
||||||
describe('Choices - text element', () => {
|
describe('Choices - text element', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.visit('/text.html');
|
cy.visit('/text', {
|
||||||
|
onBeforeLoad(win) {
|
||||||
|
cy.stub(win.console, 'warn').as('consoleWarn');
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('scenarios', () => {
|
describe('scenarios', () => {
|
||||||
|
@ -17,7 +21,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($el => {
|
.should(($el) => {
|
||||||
expect($el).to.contain(textInput);
|
expect($el).to.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -42,7 +46,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=basic]')
|
cy.get('[data-test-hook=basic]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
`Press Enter to add "${textInput}"`,
|
`Press Enter to add "${textInput}"`,
|
||||||
|
@ -74,7 +78,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=edit-items]')
|
cy.get('[data-test-hook=edit-items]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(`${textInput}-edited`);
|
expect($choice.data('value')).to.equal(`${textInput}-edited`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -90,7 +94,7 @@ describe('Choices - text element', () => {
|
||||||
it('highlights all items', () => {
|
it('highlights all items', () => {
|
||||||
cy.get('[data-test-hook=edit-items]')
|
cy.get('[data-test-hook=edit-items]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.each($choice => {
|
.each(($choice) => {
|
||||||
expect($choice.hasClass('is-highlighted')).to.equal(true);
|
expect($choice.hasClass('is-highlighted')).to.equal(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -124,7 +128,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(1);
|
expect($items.length).to.equal(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -137,7 +141,7 @@ describe('Choices - text element', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(0);
|
expect($items.length).to.equal(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -152,7 +156,7 @@ describe('Choices - text element', () => {
|
||||||
|
|
||||||
cy.get('[data-test-hook=remove-button]')
|
cy.get('[data-test-hook=remove-button]')
|
||||||
.find('.choices__input[hidden]')
|
.find('.choices__input[hidden]')
|
||||||
.then($input => {
|
.then(($input) => {
|
||||||
expect($input.val()).to.not.contain(textInput);
|
expect($input.val()).to.not.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -175,7 +179,7 @@ describe('Choices - text element', () => {
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.first()
|
.first()
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(1);
|
expect($items.length).to.equal(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -185,7 +189,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=unique-values]')
|
cy.get('[data-test-hook=unique-values]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
'Only unique values can be added',
|
'Only unique values can be added',
|
||||||
|
@ -212,7 +216,7 @@ describe('Choices - text element', () => {
|
||||||
.find('.choices__list--multiple')
|
.find('.choices__list--multiple')
|
||||||
.first()
|
.first()
|
||||||
.children()
|
.children()
|
||||||
.should($items => {
|
.should(($items) => {
|
||||||
expect($items.length).to.equal(inputLimit);
|
expect($items.length).to.equal(inputLimit);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -222,7 +226,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=input-limit]')
|
cy.get('[data-test-hook=input-limit]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
`Only ${inputLimit} values can be added`,
|
`Only ${inputLimit} values can be added`,
|
||||||
|
@ -245,7 +249,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=add-item-filter]')
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal(input);
|
expect($choice.text().trim()).to.equal(input);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -261,7 +265,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=add-item-filter]')
|
cy.get('[data-test-hook=add-item-filter]')
|
||||||
.find('.choices__list--dropdown')
|
.find('.choices__list--dropdown')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.should($dropdown => {
|
.should(($dropdown) => {
|
||||||
const dropdownText = $dropdown.text().trim();
|
const dropdownText = $dropdown.text().trim();
|
||||||
expect(dropdownText).to.equal(
|
expect(dropdownText).to.equal(
|
||||||
'Only values matching specific conditions can be added',
|
'Only values matching specific conditions can be added',
|
||||||
|
@ -283,7 +287,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
|
expect($choice.data('value')).to.equal(`before-${textInput}-after`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -292,7 +296,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=prepend-append]')
|
cy.get('[data-test-hook=prepend-append]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text()).to.not.contain(`before-${textInput}-after`);
|
expect($choice.text()).to.not.contain(`before-${textInput}-after`);
|
||||||
expect($choice.text()).to.contain(textInput);
|
expect($choice.text()).to.contain(textInput);
|
||||||
});
|
});
|
||||||
|
@ -319,21 +323,21 @@ describe('Choices - text element', () => {
|
||||||
it('pre-populates choices', () => {
|
it('pre-populates choices', () => {
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.should($choices => {
|
.should(($choices) => {
|
||||||
expect($choices.length).to.equal(2);
|
expect($choices.length).to.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.first()
|
.first()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Josh Johnson');
|
expect($choice.text().trim()).to.equal('Josh Johnson');
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-test-hook=prepopulated]')
|
cy.get('[data-test-hook=prepopulated]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($choice => {
|
.should(($choice) => {
|
||||||
expect($choice.text().trim()).to.equal('Joe Bloggs');
|
expect($choice.text().trim()).to.equal('Joe Bloggs');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -355,11 +359,53 @@ describe('Choices - text element', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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('within form', () => {
|
||||||
describe('inputting item', () => {
|
describe('inputting item', () => {
|
||||||
describe('on enter key', () => {
|
describe('on enter key', () => {
|
||||||
it('does not submit form', () => {
|
it('does not submit form', () => {
|
||||||
cy.get('[data-test-hook=within-form] form').then($form => {
|
cy.get('[data-test-hook=within-form] form').then(($form) => {
|
||||||
$form.submit(() => {
|
$form.submit(() => {
|
||||||
// this will fail the test if the form submits
|
// this will fail the test if the form submits
|
||||||
throw new Error('Form submitted');
|
throw new Error('Form submitted');
|
||||||
|
@ -374,7 +420,7 @@ describe('Choices - text element', () => {
|
||||||
cy.get('[data-test-hook=within-form]')
|
cy.get('[data-test-hook=within-form]')
|
||||||
.find('.choices__list--multiple .choices__item')
|
.find('.choices__list--multiple .choices__item')
|
||||||
.last()
|
.last()
|
||||||
.should($el => {
|
.should(($el) => {
|
||||||
expect($el).to.contain(textInput);
|
expect($el).to.contain(textInput);
|
||||||
});
|
});
|
||||||
});
|
});
|
|
@ -14,4 +14,4 @@
|
||||||
module.exports = (on, config) => {
|
module.exports = (on, config) => {
|
||||||
// `on` is used to hook into various events Cypress emits
|
// `on` is used to hook into various events Cypress emits
|
||||||
// `config` is the resolved Cypress config
|
// `config` is the resolved Cypress config
|
||||||
}
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
// ***********************************************************
|
// ***********************************************************
|
||||||
|
|
||||||
// Import commands.js using ES2015 syntax:
|
// Import commands.js using ES2015 syntax:
|
||||||
import './commands'
|
import './commands';
|
||||||
|
|
||||||
// Alternatively you can use CommonJS syntax:
|
// Alternatively you can use CommonJS syntax:
|
||||||
// require('./commands')
|
// require('./commands')
|
|
@ -11,6 +11,7 @@
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"strictNullChecks": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
30764
package-lock.json
generated
117
package.json
|
@ -1,31 +1,32 @@
|
||||||
{
|
{
|
||||||
"name": "choices.js",
|
"name": "choices.js",
|
||||||
"version": "8.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.js",
|
"main": "./public/assets/scripts/choices.js",
|
||||||
"types": "./types/index.d.ts",
|
"types": "./public/types/src/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "run-p js:watch css:watch",
|
"start": "run-p js:watch css:watch",
|
||||||
"build": "run-p js:build css:build",
|
"build": "run-p js:build css:build",
|
||||||
"lint": "eslint src/scripts",
|
"lint": "run-p lint:js lint:scss",
|
||||||
|
"lint:js": "eslint src/scripts/**/*.ts",
|
||||||
|
"lint:scss": "stylelint src/**/*.scss",
|
||||||
"bundlesize": "bundlesize",
|
"bundlesize": "bundlesize",
|
||||||
"cypress:run": "$(npm bin)/cypress run",
|
"cypress:run": "cypress run --browser chrome",
|
||||||
"cypress:open": "$(npm bin)/cypress open",
|
"cypress:open": "cypress open",
|
||||||
"cypress:ci": "cypress run --record --group --ci-build-id $GITHUB_SHA",
|
"cypress:ci": "cypress run --browser chrome --record --group $GITHUB_REF --ci-build-id $GITHUB_SHA",
|
||||||
"test": "run-s test:unit test:e2e",
|
"test": "run-s test:unit test:e2e",
|
||||||
"test:unit": "NODE_ENV=test mocha",
|
"test:unit": "cross-env TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha",
|
||||||
"test:unit:watch": "NODE_ENV=test mocha --watch --inspect=5556",
|
"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:unit:coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text --reporter=text-summary mocha",
|
||||||
"test:e2e": "run-p --race start cypress:run",
|
"test:e2e": "run-p --race start cypress:run",
|
||||||
"js:watch": "NODE_ENV=development node server.js",
|
"js:watch": "cross-env NODE_ENV=development node server.js",
|
||||||
"js:build": "webpack --config webpack.config.prod.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": "run-s css:sass css:prefix css:min",
|
"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 public/assets/styles/*.css --use autoprefixer --no-map --env prod --dir 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 --output public/assets/styles/base.min.css && csso public/assets/styles/choices.css --output 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",
|
||||||
"deploy": "git subtree push --prefix public origin gh-pages",
|
"deploy": "git subtree push --prefix public origin gh-pages",
|
||||||
"postversion": "git push --no-verify --atomic --follow-tags",
|
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
"files": [
|
"files": [
|
||||||
"public/assets/scripts",
|
"public/assets/scripts",
|
||||||
"public/assets/styles",
|
"public/assets/styles",
|
||||||
|
"public/types",
|
||||||
"src",
|
"src",
|
||||||
"!src/**/*.test.js",
|
"!src/**/*.test.js",
|
||||||
"types"
|
"types"
|
||||||
|
@ -54,45 +56,61 @@
|
||||||
"js"
|
"js"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.6.4",
|
"@babel/core": "^7.20.5",
|
||||||
"@babel/preset-env": "^7.6.3",
|
"@babel/preset-env": "^7.20.2",
|
||||||
"@babel/register": "^7.6.2",
|
"@babel/register": "^7.18.9",
|
||||||
"autoprefixer": "^9.6.5",
|
"@types/chai": "^4.3.4",
|
||||||
"babel-loader": "^8.0.6",
|
"@types/mocha": "^10.0.1",
|
||||||
"bundlesize": "^0.18.0",
|
"@types/sinon": "^10.0.13",
|
||||||
"chai": "^4.2.0",
|
"@types/sinon-chai": "^3.2.9",
|
||||||
"csso-cli": "^3.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
"cypress": "3.5.0",
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
"eslint": "^6.6.0",
|
"autoprefixer": "^10.4.13",
|
||||||
"eslint-config-airbnb-base": "^14.0.0",
|
"babel-loader": "^9.1.0",
|
||||||
"eslint-config-prettier": "^6.5.0",
|
"bundlesize": "^0.18.1",
|
||||||
"eslint-loader": "^3.0.2",
|
"chai": "^4.3.7",
|
||||||
"eslint-plugin-compat": "3.3.0",
|
"cross-env": "^7.0.3",
|
||||||
"eslint-plugin-cypress": "^2.7.0",
|
"csso-cli": "^4.0.1",
|
||||||
"eslint-plugin-import": "^2.18.2",
|
"cypress": "11.2.0",
|
||||||
"eslint-plugin-prettier": "^3.1.1",
|
"eslint": "^8.28.0",
|
||||||
"eslint-plugin-sort-class-members": "^1.6.0",
|
"eslint-config-airbnb-base": "^15.0.0",
|
||||||
"express": "^4.16.4",
|
"eslint-config-airbnb-typescript": "^17.0.0",
|
||||||
"husky": "^3.0.9",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"jsdom": "^15.2.0",
|
"eslint-plugin-compat": "4.0.2",
|
||||||
"lint-staged": "^9.4.2",
|
"eslint-plugin-cypress": "^2.12.1",
|
||||||
"mocha": "^6.2.2",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"node-sass": "^4.12.0",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"nodemon": "^1.18.10",
|
"eslint-plugin-sort-class-members": "^1.15.2",
|
||||||
|
"eslint-webpack-plugin": "^3.2.0",
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"husky": "^8.0.2",
|
||||||
|
"jsdom": "^20.0.3",
|
||||||
|
"lint-staged": "^13.0.4",
|
||||||
|
"mocha": "^10.1.0",
|
||||||
|
"nodemon": "^2.0.20",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"nyc": "^14.1.1",
|
"nyc": "^15.1.0",
|
||||||
"postcss-cli": "^6.1.3",
|
"postcss": "^8.4.19",
|
||||||
"prettier": "^1.18.2",
|
"postcss-cli": "^10.0.0",
|
||||||
"sinon": "^7.5.0",
|
"prettier": "^2.8.0",
|
||||||
"webpack": "^4.41.2",
|
"sass": "^1.56.1",
|
||||||
"webpack-cli": "^3.3.9",
|
"sinon": "^15.0.0",
|
||||||
"webpack-dev-middleware": "^3.7.2",
|
"sinon-chai": "^3.7.0",
|
||||||
"webpack-hot-middleware": "^2.25.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": {
|
||||||
"deepmerge": "^4.2.0",
|
"deepmerge": "^4.2.2",
|
||||||
"fuse.js": "^3.4.5",
|
"fuse.js": "^6.6.2",
|
||||||
"redux": "^4.0.4"
|
"redux": "^4.2.0"
|
||||||
},
|
},
|
||||||
"npmName": "choices.js",
|
"npmName": "choices.js",
|
||||||
"npmFileMap": [
|
"npmFileMap": [
|
||||||
|
@ -100,6 +118,7 @@
|
||||||
"files": [
|
"files": [
|
||||||
"public/assets/scripts/*",
|
"public/assets/scripts/*",
|
||||||
"public/assets/styles/*",
|
"public/assets/styles/*",
|
||||||
|
"public/types/*",
|
||||||
"src/icons/*"
|
"src/icons/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -115,11 +134,11 @@
|
||||||
"bundlesize": [
|
"bundlesize": [
|
||||||
{
|
{
|
||||||
"path": "public/assets/scripts/choices.min.js",
|
"path": "public/assets/scripts/choices.min.js",
|
||||||
"maxSize": "20 kB"
|
"maxSize": "25 kB"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "public/assets/styles/choices.min.css",
|
"path": "public/assets/styles/choices.min.css",
|
||||||
"maxSize": "1.8 kB"
|
"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>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// get polyfill settings from top level config
|
// get polyfill settings from top level config
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { settings } = require('../../../.eslintrc.json');
|
const { settings } = require('../../../.eslintrc.json');
|
||||||
|
@ -6,19 +5,23 @@ const { settings } = require('../../../.eslintrc.json');
|
||||||
// Adding non-polyfilable Symbol-related functions as they are most probably
|
// Adding non-polyfilable Symbol-related functions as they are most probably
|
||||||
// behind the flag
|
// behind the flag
|
||||||
|
|
||||||
settings.polyfills.push('Symbol.toStringTag', 'Symbol.for', 'Object.getOwnPropertySymbols', 'Object.getOwnPropertyDescriptors')
|
settings.polyfills.push(
|
||||||
|
'Symbol.toStringTag',
|
||||||
|
'Symbol.for',
|
||||||
|
'Object.getOwnPropertySymbols',
|
||||||
|
'Object.getOwnPropertyDescriptors',
|
||||||
|
'Promise', // Promise is gate checked
|
||||||
|
);
|
||||||
|
|
||||||
module.exports = /** @type {import('eslint').Linter.Config} */({
|
module.exports = /** @type {import('eslint').Linter.Config} */ ({
|
||||||
root: true,
|
root: true,
|
||||||
extends: [
|
extends: ['plugin:compat/recommended'],
|
||||||
"plugin:compat/recommended"
|
|
||||||
],
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
// ensure that it's compatible with ES5 browsers, so, no `const`, etc
|
// ensure that it's compatible with ES5 browsers, so, no `const`, etc
|
||||||
ecmaVersion: 5
|
ecmaVersion: 5,
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
browser: true
|
browser: true,
|
||||||
},
|
},
|
||||||
settings
|
settings,
|
||||||
})
|
});
|
||||||
|
|
13
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,10 +21,10 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
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,10 +113,6 @@ h6,
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
label + p {
|
label + p {
|
||||||
margin-top: -4px;
|
margin-top: -4px;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +123,6 @@ label + p {
|
||||||
max-width: 40em;
|
max-width: 40em;
|
||||||
padding: 48px;
|
padding: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 620px) {
|
@media (max-width: 620px) {
|
||||||
.container {
|
.container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -135,11 +130,10 @@ label + p {
|
||||||
}
|
}
|
||||||
|
|
||||||
.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 {
|
||||||
|
@ -151,7 +145,7 @@ label + p {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo__img {
|
.logo-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -184,4 +178,4 @@ label + p {
|
||||||
margin-bottom: 24px;
|
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,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;-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}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}
|
*{-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,56 +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;
|
||||||
-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] {
|
.choices [hidden] {
|
||||||
display: none !important;
|
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;
|
||||||
|
@ -61,23 +56,23 @@
|
||||||
height: 20px;
|
height: 20px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
border-radius: 10em;
|
border-radius: 10em;
|
||||||
opacity: 0.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;
|
||||||
content: '';
|
}
|
||||||
|
.choices[data-type*=select-one]::after {
|
||||||
|
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;
|
||||||
|
@ -85,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;
|
||||||
|
@ -118,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: 0.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,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;
|
||||||
}
|
}
|
||||||
|
@ -163,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%;
|
||||||
}
|
}
|
||||||
|
@ -182,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;
|
||||||
|
@ -194,83 +176,74 @@
|
||||||
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: 0.25rem 0.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;
|
||||||
|
@ -279,22 +252,20 @@
|
||||||
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: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,7 +280,6 @@
|
||||||
.choices__item--disabled {
|
.choices__item--disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
@ -325,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;
|
||||||
}
|
}
|
||||||
|
@ -349,12 +317,18 @@
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
@ -363,4 +337,4 @@
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===== End of Choices ======*/
|
/* ===== 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
|
@ -47,12 +47,12 @@
|
||||||
<!-- End ignore these -->
|
<!-- End ignore these -->
|
||||||
|
|
||||||
<!-- Optional includes -->
|
<!-- Optional includes -->
|
||||||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es5%2Ces6%2CArray.prototype.includes%2Cfetch%2CCustomEvent%2CElement.prototype.closest"></script>
|
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=Array.from%2Ces5%2Ces6%2CSymbol%2CSymbol.iterator%2CDOMTokenList%2CObject.assign%2CCustomEvent%2CElement.prototype.classList%2CElement.prototype.closest%2CElement.prototype.dataset%2CArray.prototype.find%2CArray.prototype.includes%2Cfetch"></script>
|
||||||
<!-- End optional includes -->
|
<!-- End optional includes -->
|
||||||
|
|
||||||
<!-- Choices includes -->
|
<!-- Choices includes -->
|
||||||
<link rel="stylesheet" href="assets/styles/choices.min.css" />
|
<link rel="stylesheet" href="assets/styles/choices.min.css" />
|
||||||
<script src="assets/scripts/choices.min.js"></script>
|
<script src="assets/scripts/choices.js"></script>
|
||||||
<!-- End Choices includes -->
|
<!-- End Choices includes -->
|
||||||
|
|
||||||
<!--[if lt IE 9]>
|
<!--[if lt IE 9]>
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
<img
|
<img
|
||||||
src="assets/images/logo.svg"
|
src="assets/images/logo.svg"
|
||||||
alt="Choices.js logo"
|
alt="Choices.js logo"
|
||||||
class="logo__img hidden-ie"
|
class="logo-img hidden-ie"
|
||||||
/>
|
/>
|
||||||
<h1 class="visible-ie">Choices.js</h1>
|
<h1 class="visible-ie">Choices.js</h1>
|
||||||
</a>
|
</a>
|
||||||
|
@ -96,6 +96,13 @@
|
||||||
tutorials! 💪🏼</strong
|
tutorials! 💪🏼</strong
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
<p class="h4 text-center">
|
||||||
|
<strong>Sponsored by:</strong>
|
||||||
|
<br />
|
||||||
|
<a href="https://wanderermaps.com/" target="_blank" rel="noopener noreferrer">
|
||||||
|
<img src="https://cdn.shopify.com/s/files/1/0614/3357/7715/files/Logo_BlackWithBackground_150x.png?v=1644802773" alt="Wanderer Maps logo">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2>Text inputs</h2>
|
<h2>Text inputs</h2>
|
||||||
|
@ -214,6 +221,7 @@
|
||||||
placeholder="This is a placeholder"
|
placeholder="This is a placeholder"
|
||||||
multiple
|
multiple
|
||||||
>
|
>
|
||||||
|
<option value="">Choose a city</option>
|
||||||
<optgroup label="UK">
|
<optgroup label="UK">
|
||||||
<option value="London">London</option>
|
<option value="London">London</option>
|
||||||
<option value="Manchester">Manchester</option>
|
<option value="Manchester">Manchester</option>
|
||||||
|
@ -287,7 +295,9 @@
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2>Single select input</h2>
|
<h2>Single select input</h2>
|
||||||
<label for="choices-single-default">Default</label>
|
<label id="choices-single-default-label" for="choices-single-default"
|
||||||
|
>Default</label
|
||||||
|
>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
data-trigger
|
data-trigger
|
||||||
|
@ -336,8 +346,8 @@
|
||||||
data-trigger
|
data-trigger
|
||||||
name="choices-single-groups"
|
name="choices-single-groups"
|
||||||
id="choices-single-groups"
|
id="choices-single-groups"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
>
|
>
|
||||||
|
<option value="">Choose a city</option>
|
||||||
<optgroup label="UK">
|
<optgroup label="UK">
|
||||||
<option value="London">London</option>
|
<option value="London">London</option>
|
||||||
<option value="Manchester">Manchester</option>
|
<option value="Manchester">Manchester</option>
|
||||||
|
@ -376,7 +386,6 @@
|
||||||
data-trigger
|
data-trigger
|
||||||
name="choices-single-rtl"
|
name="choices-single-rtl"
|
||||||
id="choices-single-rtl"
|
id="choices-single-rtl"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
dir="rtl"
|
dir="rtl"
|
||||||
>
|
>
|
||||||
<option value="Choice 1">Choice 1</option>
|
<option value="Choice 1">Choice 1</option>
|
||||||
|
@ -402,7 +411,6 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-single-preset-options"
|
name="choices-single-preset-options"
|
||||||
id="choices-single-preset-options"
|
id="choices-single-preset-options"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
></select>
|
></select>
|
||||||
|
|
||||||
<label for="choices-single-selected-option"
|
<label for="choices-single-selected-option"
|
||||||
|
@ -415,7 +423,6 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-single-selected-option"
|
name="choices-single-selected-option"
|
||||||
id="choices-single-selected-option"
|
id="choices-single-selected-option"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
></select>
|
></select>
|
||||||
|
|
||||||
<label for="choices-with-custom-props-via-html"
|
<label for="choices-with-custom-props-via-html"
|
||||||
|
@ -433,14 +440,22 @@
|
||||||
data-custom-properties="This option is fantastic"
|
data-custom-properties="This option is fantastic"
|
||||||
>Label Three</option
|
>Label Three</option
|
||||||
>
|
>
|
||||||
|
<option
|
||||||
|
value="Dropdown item 4"
|
||||||
|
data-custom-properties="{ 'description': 'foo' }"
|
||||||
|
>Label Four</option
|
||||||
|
>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="choices-single-no-sorting">Options without sorting</label>
|
<label
|
||||||
|
id="choices-single-no-sorting-label"
|
||||||
|
for="choices-single-no-sorting"
|
||||||
|
>Options without sorting</label
|
||||||
|
>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-single-no-sorting"
|
name="choices-single-no-sorting"
|
||||||
id="choices-single-no-sorting"
|
id="choices-single-no-sorting"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
>
|
>
|
||||||
<option value="Madrid">Madrid</option>
|
<option value="Madrid">Madrid</option>
|
||||||
<option value="Toronto">Toronto</option>
|
<option value="Toronto">Toronto</option>
|
||||||
|
@ -467,7 +482,6 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-single-custom-templates"
|
name="choices-single-custom-templates"
|
||||||
id="choices-single-custom-templates"
|
id="choices-single-custom-templates"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
>
|
>
|
||||||
<option value="React">React</option>
|
<option value="React">React</option>
|
||||||
<option value="Angular">Angular</option>
|
<option value="Angular">Angular</option>
|
||||||
|
@ -481,12 +495,8 @@
|
||||||
'Cities' is 'London'
|
'Cities' is 'London'
|
||||||
</p>
|
</p>
|
||||||
<label for="cities">Cities</label>
|
<label for="cities">Cities</label>
|
||||||
<select
|
<select class="form-control" name="cities" id="cities">
|
||||||
class="form-control"
|
<option value="">Choose a city</option>
|
||||||
name="cities"
|
|
||||||
id="cities"
|
|
||||||
placeholder="Choose a city"
|
|
||||||
>
|
|
||||||
<option value="Leeds">Leeds</option>
|
<option value="Leeds">Leeds</option>
|
||||||
<option value="Manchester">Manchester</option>
|
<option value="Manchester">Manchester</option>
|
||||||
<option value="London">London</option>
|
<option value="London">London</option>
|
||||||
|
@ -495,12 +505,8 @@
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="tube-stations">Tube stations</label>
|
<label for="tube-stations">Tube stations</label>
|
||||||
<select
|
<select class="form-control" name="tube-stations" id="tube-stations">
|
||||||
class="form-control"
|
<option value="">Choose a tube station</option>
|
||||||
name="tube-stations"
|
|
||||||
id="tube-stations"
|
|
||||||
placeholder="Choose a tube station"
|
|
||||||
>
|
|
||||||
<option value="Moorgate">Moorgate</option>
|
<option value="Moorgate">Moorgate</option>
|
||||||
<option value="St Pauls">St Pauls</option>
|
<option value="St Pauls">St Pauls</option>
|
||||||
<option value="Old Street">Old Street</option>
|
<option value="Old Street">Old Street</option>
|
||||||
|
@ -515,12 +521,7 @@
|
||||||
<p>Change the values and press reset to restore to initial state.</p>
|
<p>Change the values and press reset to restore to initial state.</p>
|
||||||
<form>
|
<form>
|
||||||
<label for="reset-simple">Change me!</label>
|
<label for="reset-simple">Change me!</label>
|
||||||
<select
|
<select class="form-control" name="reset-simple" id="reset-simple">
|
||||||
class="form-control"
|
|
||||||
name="reset-simple"
|
|
||||||
id="reset-simple"
|
|
||||||
placeholder="Choose an option"
|
|
||||||
>
|
|
||||||
<option value="Option 1">Option 1</option>
|
<option value="Option 1">Option 1</option>
|
||||||
<option value="Option 2" selected>Option 2</option>
|
<option value="Option 2" selected>Option 2</option>
|
||||||
<option value="Option 3">Option 3</option>
|
<option value="Option 3">Option 3</option>
|
||||||
|
@ -533,7 +534,6 @@
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="reset-multiple"
|
name="reset-multiple"
|
||||||
id="reset-multiple"
|
id="reset-multiple"
|
||||||
placeholder="This is a placeholder"
|
|
||||||
multiple
|
multiple
|
||||||
>
|
>
|
||||||
<option value="Choice 1" selected>Choice 1</option>
|
<option value="Choice 1" selected>Choice 1</option>
|
||||||
|
@ -552,6 +552,7 @@
|
||||||
for (i = 0; i < genericExamples.length; ++i) {
|
for (i = 0; i < genericExamples.length; ++i) {
|
||||||
var element = genericExamples[i];
|
var element = genericExamples[i];
|
||||||
new Choices(element, {
|
new Choices(element, {
|
||||||
|
allowHTML: true,
|
||||||
placeholderValue: 'This is a placeholder set in the config',
|
placeholderValue: 'This is a placeholder set in the config',
|
||||||
searchPlaceholderValue: 'This is a search placeholder',
|
searchPlaceholderValue: 'This is a search placeholder',
|
||||||
});
|
});
|
||||||
|
@ -560,20 +561,23 @@
|
||||||
var textRemove = new Choices(
|
var textRemove = new Choices(
|
||||||
document.getElementById('choices-text-remove-button'),
|
document.getElementById('choices-text-remove-button'),
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
editItems: true,
|
editItems: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var textUniqueVals = new Choices('#choices-text-unique-values', {
|
var textUniqueVals = new Choices('#choices-text-unique-values', {
|
||||||
|
allowHTML: true,
|
||||||
paste: false,
|
paste: false,
|
||||||
duplicateItemsAllowed: false,
|
duplicateItemsAllowed: false,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
var texti18n = new Choices('#choices-text-i18n', {
|
var texti18n = new Choices('#choices-text-i18n', {
|
||||||
|
allowHTML: true,
|
||||||
paste: false,
|
paste: false,
|
||||||
duplicateItemsAllowed: false,
|
duplicateItemsAllowed: false,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
|
@ -590,6 +594,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var textEmailFilter = new Choices('#choices-text-email-filter', {
|
var textEmailFilter = new Choices('#choices-text-email-filter', {
|
||||||
|
allowHTML: true,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
addItemFilter: function(value) {
|
addItemFilter: function(value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -603,6 +608,7 @@
|
||||||
}).setValue(['joe@bloggs.com']);
|
}).setValue(['joe@bloggs.com']);
|
||||||
|
|
||||||
var textDisabled = new Choices('#choices-text-disabled', {
|
var textDisabled = new Choices('#choices-text-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
removeItems: false,
|
removeItems: false,
|
||||||
}).disable();
|
}).disable();
|
||||||
|
@ -610,12 +616,14 @@
|
||||||
var textPrependAppendVal = new Choices(
|
var textPrependAppendVal = new Choices(
|
||||||
'#choices-text-prepend-append-value',
|
'#choices-text-prepend-append-value',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'item-',
|
prependValue: 'item-',
|
||||||
appendValue: '-' + Date.now(),
|
appendValue: '-' + Date.now(),
|
||||||
},
|
}
|
||||||
).removeActiveItems();
|
).removeActiveItems();
|
||||||
|
|
||||||
var textPresetVal = new Choices('#choices-text-preset-values', {
|
var textPresetVal = new Choices('#choices-text-preset-values', {
|
||||||
|
allowHTML: true,
|
||||||
items: [
|
items: [
|
||||||
'Josh Johnson',
|
'Josh Johnson',
|
||||||
{
|
{
|
||||||
|
@ -630,15 +638,17 @@
|
||||||
|
|
||||||
var multipleDefault = new Choices(
|
var multipleDefault = new Choices(
|
||||||
document.getElementById('choices-multiple-groups'),
|
document.getElementById('choices-multiple-groups'),
|
||||||
|
{ allowHTML: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
var multipleFetch = new Choices('#choices-multiple-remote-fetch', {
|
var multipleFetch = new Choices('#choices-multiple-remote-fetch', {
|
||||||
|
allowHTML: false,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: 'Pick an Strokes record',
|
placeholderValue: 'Pick an Strokes record',
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
}).setChoices(function() {
|
}).setChoices(function() {
|
||||||
return fetch(
|
return fetch(
|
||||||
'https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
'https://api.discogs.com/artists/55980/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW'
|
||||||
)
|
)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
return response.json();
|
return response.json();
|
||||||
|
@ -653,12 +663,14 @@
|
||||||
var multipleCancelButton = new Choices(
|
var multipleCancelButton = new Choices(
|
||||||
'#choices-multiple-remove-button',
|
'#choices-multiple-remove-button',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Use label on event */
|
/* Use label on event */
|
||||||
var choicesSelect = new Choices('#choices-multiple-labels', {
|
var choicesSelect = new Choices('#choices-multiple-labels', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
choices: [
|
choices: [
|
||||||
{ value: 'One', label: 'Label One' },
|
{ value: 'One', label: 'Label One' },
|
||||||
|
@ -673,7 +685,7 @@
|
||||||
],
|
],
|
||||||
'value',
|
'value',
|
||||||
'label',
|
'label',
|
||||||
false,
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
choicesSelect.passedElement.element.addEventListener(
|
choicesSelect.passedElement.element.addEventListener(
|
||||||
|
@ -681,7 +693,7 @@
|
||||||
function(event) {
|
function(event) {
|
||||||
document.getElementById('message').innerHTML =
|
document.getElementById('message').innerHTML =
|
||||||
'You just added "' + event.detail.label + '"';
|
'You just added "' + event.detail.label + '"';
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
choicesSelect.passedElement.element.addEventListener(
|
choicesSelect.passedElement.element.addEventListener(
|
||||||
|
@ -689,15 +701,16 @@
|
||||||
function(event) {
|
function(event) {
|
||||||
document.getElementById('message').innerHTML =
|
document.getElementById('message').innerHTML =
|
||||||
'You just removed "' + event.detail.label + '"';
|
'You just removed "' + event.detail.label + '"';
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
var singleFetch = new Choices('#choices-single-remote-fetch', {
|
||||||
|
allowHTML: false,
|
||||||
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
searchPlaceholderValue: 'Search for an Arctic Monkeys record',
|
||||||
})
|
})
|
||||||
.setChoices(function() {
|
.setChoices(function() {
|
||||||
return fetch(
|
return fetch(
|
||||||
'https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
'https://api.discogs.com/artists/391170/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW'
|
||||||
)
|
)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
return response.json();
|
return response.json();
|
||||||
|
@ -713,11 +726,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
var singleXhrRemove = new Choices('#choices-single-remove-xhr', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
searchPlaceholderValue: "Search for a Smiths' record",
|
searchPlaceholderValue: "Search for a Smiths' record",
|
||||||
}).setChoices(function(callback) {
|
}).setChoices(function(callback) {
|
||||||
return fetch(
|
return fetch(
|
||||||
'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW',
|
'https://api.discogs.com/artists/83080/releases?token=QBRmstCkwXEvCjTclCpumbtNwvVkEzGAdELXyRyW'
|
||||||
)
|
)
|
||||||
.then(function(res) {
|
.then(function(res) {
|
||||||
return res.json();
|
return res.json();
|
||||||
|
@ -729,12 +743,8 @@
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
var genericExamples = new Choices('[data-trigger]', {
|
|
||||||
placeholderValue: 'This is a placeholder set in the config',
|
|
||||||
searchPlaceholderValue: 'This is a search placeholder',
|
|
||||||
});
|
|
||||||
|
|
||||||
var singleNoSearch = new Choices('#choices-single-no-search', {
|
var singleNoSearch = new Choices('#choices-single-no-search', {
|
||||||
|
allowHTML: true,
|
||||||
searchEnabled: false,
|
searchEnabled: false,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
choices: [
|
choices: [
|
||||||
|
@ -750,10 +760,11 @@
|
||||||
],
|
],
|
||||||
'value',
|
'value',
|
||||||
'label',
|
'label',
|
||||||
false,
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
var singlePresetOpts = new Choices('#choices-single-preset-options', {
|
var singlePresetOpts = new Choices('#choices-single-preset-options', {
|
||||||
|
allowHTML: true,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
}).setChoices(
|
}).setChoices(
|
||||||
[
|
[
|
||||||
|
@ -779,10 +790,11 @@
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'value',
|
'value',
|
||||||
'label',
|
'label'
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleSelectedOpt = new Choices('#choices-single-selected-option', {
|
var singleSelectedOpt = new Choices('#choices-single-selected-option', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.description'],
|
searchFields: ['label', 'value', 'customProperties.description'],
|
||||||
choices: [
|
choices: [
|
||||||
{ value: 'One', label: 'Label One', selected: true },
|
{ value: 'One', label: 'Label One', selected: true },
|
||||||
|
@ -800,17 +812,21 @@
|
||||||
var customChoicesPropertiesViaDataAttributes = new Choices(
|
var customChoicesPropertiesViaDataAttributes = new Choices(
|
||||||
'#choices-with-custom-props-via-html',
|
'#choices-with-custom-props-via-html',
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties'],
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var singleNoSorting = new Choices('#choices-single-no-sorting', {
|
var singleNoSorting = new Choices('#choices-single-no-sorting', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
|
labelId: 'choices-single-no-sorting-label',
|
||||||
});
|
});
|
||||||
|
|
||||||
var cities = new Choices(document.getElementById('cities'));
|
var cities = new Choices(document.getElementById('cities'), { allowHTML: true });
|
||||||
var tubeStations = new Choices(
|
var tubeStations = new Choices(
|
||||||
document.getElementById('tube-stations'),
|
document.getElementById('tube-stations'),
|
||||||
|
{ allowHTML: true }
|
||||||
).disable();
|
).disable();
|
||||||
|
|
||||||
cities.passedElement.element.addEventListener('change', function(e) {
|
cities.passedElement.element.addEventListener('change', function(e) {
|
||||||
|
@ -824,11 +840,12 @@
|
||||||
var customTemplates = new Choices(
|
var customTemplates = new Choices(
|
||||||
document.getElementById('choices-single-custom-templates'),
|
document.getElementById('choices-single-custom-templates'),
|
||||||
{
|
{
|
||||||
|
allowHTML: true,
|
||||||
callbackOnCreateTemplates: function(strToEl) {
|
callbackOnCreateTemplates: function(strToEl) {
|
||||||
var classNames = this.config.classNames;
|
var classNames = this.config.classNames;
|
||||||
var itemSelectText = this.config.itemSelectText;
|
var itemSelectText = this.config.itemSelectText;
|
||||||
return {
|
return {
|
||||||
item: function(classNames, data) {
|
item: function({ classNames }, data) {
|
||||||
return strToEl(
|
return strToEl(
|
||||||
'\
|
'\
|
||||||
<div\
|
<div\
|
||||||
|
@ -838,7 +855,7 @@
|
||||||
String(
|
String(
|
||||||
data.highlighted
|
data.highlighted
|
||||||
? classNames.highlightedState
|
? classNames.highlightedState
|
||||||
: classNames.itemSelectable,
|
: classNames.itemSelectable
|
||||||
) +
|
) +
|
||||||
'"\
|
'"\
|
||||||
data-item\
|
data-item\
|
||||||
|
@ -859,10 +876,10 @@
|
||||||
String(data.label) +
|
String(data.label) +
|
||||||
'\
|
'\
|
||||||
</div>\
|
</div>\
|
||||||
',
|
'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
choice: function(classNames, data) {
|
choice: function({ classNames }, data) {
|
||||||
return strToEl(
|
return strToEl(
|
||||||
'\
|
'\
|
||||||
<div\
|
<div\
|
||||||
|
@ -874,7 +891,7 @@
|
||||||
String(
|
String(
|
||||||
data.disabled
|
data.disabled
|
||||||
? classNames.itemDisabled
|
? classNames.itemDisabled
|
||||||
: classNames.itemSelectable,
|
: classNames.itemSelectable
|
||||||
) +
|
) +
|
||||||
'"\
|
'"\
|
||||||
data-select-text="' +
|
data-select-text="' +
|
||||||
|
@ -885,7 +902,7 @@
|
||||||
String(
|
String(
|
||||||
data.disabled
|
data.disabled
|
||||||
? 'data-choice-disabled aria-disabled="true"'
|
? 'data-choice-disabled aria-disabled="true"'
|
||||||
: 'data-choice-selectable',
|
: 'data-choice-selectable'
|
||||||
) +
|
) +
|
||||||
'\
|
'\
|
||||||
data-id="' +
|
data-id="' +
|
||||||
|
@ -896,7 +913,7 @@
|
||||||
'"\
|
'"\
|
||||||
' +
|
' +
|
||||||
String(
|
String(
|
||||||
data.groupId > 0 ? 'role="treeitem"' : 'role="option"',
|
data.groupId > 0 ? 'role="treeitem"' : 'role="option"'
|
||||||
) +
|
) +
|
||||||
'\
|
'\
|
||||||
>\
|
>\
|
||||||
|
@ -904,17 +921,20 @@
|
||||||
String(data.label) +
|
String(data.label) +
|
||||||
'\
|
'\
|
||||||
</div>\
|
</div>\
|
||||||
',
|
'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
var resetSimple = new Choices(document.getElementById('reset-simple'));
|
var resetSimple = new Choices(document.getElementById('reset-simple'), {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
var resetMultiple = new Choices('#reset-multiple', {
|
var resetMultiple = new Choices('#reset-multiple', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,43 +15,40 @@
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
sizes="180x180"
|
sizes="180x180"
|
||||||
href="../assets/images/apple-touch-icon.png"
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-32x32.png"
|
href="../../assets/images/favicon-32x32.png"
|
||||||
sizes="32x32"
|
sizes="32x32"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-16x16.png"
|
href="../../assets/images/favicon-16x16.png"
|
||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="../assets/images/manifest.json" />
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
<link
|
<link
|
||||||
rel="mask-icon"
|
rel="mask-icon"
|
||||||
href="../assets/images/safari-pinned-tab.svg"
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
color="#00bcd4"
|
color="#00bcd4"
|
||||||
/>
|
/>
|
||||||
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
<meta
|
<meta
|
||||||
name="msapplication-config"
|
name="msapplication-config"
|
||||||
content="../assets/images/browserconfig.xml"
|
content="../../assets/images/browserconfig.xml"
|
||||||
/>
|
/>
|
||||||
<meta name="theme-color" content="#ffffff" />
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
<!-- Ignore these -->
|
<!-- Ignore these -->
|
||||||
<link rel="stylesheet" href="../assets/styles/base.min.css?version=6.0.3" />
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
<!-- End ignore these -->
|
<!-- End ignore these -->
|
||||||
|
|
||||||
<!-- Choices includes -->
|
<!-- Choices includes -->
|
||||||
<link
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
rel="stylesheet"
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
href="../assets/styles/choices.min.css?version=6.0.3"
|
|
||||||
/>
|
|
||||||
<script src="../assets/scripts/choices.min.js?version=6.0.3"></script>
|
|
||||||
<!-- End Choices includes -->
|
<!-- End Choices includes -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -194,14 +191,34 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="placeholder">
|
<div data-test-hook="placeholder-via-option-value">
|
||||||
<label for="choices-placeholder">Placeholder</label>
|
<label for="choices-placeholder-via-option-value"
|
||||||
|
>Placeholder via empty option value</label
|
||||||
|
>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-placeholder"
|
name="choices-placeholder-via-option-value"
|
||||||
id="choices-placeholder"
|
id="choices-placeholder-via-option-value"
|
||||||
multiple
|
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 1">Choice 1</option>
|
||||||
<option value="Choice 2">Choice 2</option>
|
<option value="Choice 2">Choice 2</option>
|
||||||
<option value="Choice 3">Choice 3</option>
|
<option value="Choice 3">Choice 3</option>
|
||||||
|
@ -215,7 +232,9 @@
|
||||||
name="choices-remote-data"
|
name="choices-remote-data"
|
||||||
id="choices-remote-data"
|
id="choices-remote-data"
|
||||||
multiple
|
multiple
|
||||||
></select>
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="scrolling-dropdown">
|
<div data-test-hook="scrolling-dropdown">
|
||||||
|
@ -275,6 +294,28 @@
|
||||||
></select>
|
></select>
|
||||||
</div>
|
</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">
|
<div data-test-hook="non-string-values">
|
||||||
<label for="choices-non-string-values">Non-string values</label>
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
<select
|
<select
|
||||||
|
@ -326,11 +367,43 @@
|
||||||
<option value="value2">label2</option>
|
<option value="value2">label2</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('button.disable')
|
.querySelector('button.disable')
|
||||||
|
@ -345,40 +418,54 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-choice');
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-add-items-disabled', {
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-selection-limit', {
|
new Choices('#choices-selection-limit', {
|
||||||
|
allowHTML: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-render-choice-limit', {
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
renderChoiceLimit: 1,
|
renderChoiceLimit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-floor', {
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
searchFloor: 5,
|
searchFloor: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder', {
|
new Choices('#choices-placeholder-via-option-value', {
|
||||||
placeholder: true,
|
allowHTML: true,
|
||||||
placeholderValue: 'I am a placeholder',
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-placeholder-via-option-attr', {
|
||||||
|
allowHTML: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remote-data', {
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).setChoices(async () => {
|
}).setChoices(async () => {
|
||||||
const data = await fetch('/data');
|
const data = await fetch('/data');
|
||||||
|
@ -386,12 +473,16 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-groups');
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-custom-properties', {
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.country'],
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -421,7 +512,13 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties-html', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-non-string-values', {
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
@ -448,13 +545,83 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
new Choices('#choices-set-choice-by-value', {
|
||||||
'Choice 2',
|
allowHTML: true,
|
||||||
);
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
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>
|
</script>
|
||||||
</body>
|
</body>
|
|
@ -15,43 +15,40 @@
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
sizes="180x180"
|
sizes="180x180"
|
||||||
href="../assets/images/apple-touch-icon.png"
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-32x32.png"
|
href="../../assets/images/favicon-32x32.png"
|
||||||
sizes="32x32"
|
sizes="32x32"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-16x16.png"
|
href="../../assets/images/favicon-16x16.png"
|
||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="../assets/images/manifest.json" />
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
<link
|
<link
|
||||||
rel="mask-icon"
|
rel="mask-icon"
|
||||||
href="../assets/images/safari-pinned-tab.svg"
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
color="#00bcd4"
|
color="#00bcd4"
|
||||||
/>
|
/>
|
||||||
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
<meta
|
<meta
|
||||||
name="msapplication-config"
|
name="msapplication-config"
|
||||||
content="../assets/images/browserconfig.xml"
|
content="../../assets/images/browserconfig.xml"
|
||||||
/>
|
/>
|
||||||
<meta name="theme-color" content="#ffffff" />
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
<!-- Ignore these -->
|
<!-- Ignore these -->
|
||||||
<link rel="stylesheet" href="../assets/styles/base.min.css?version=6.0.3" />
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
<!-- End ignore these -->
|
<!-- End ignore these -->
|
||||||
|
|
||||||
<!-- Choices includes -->
|
<!-- Choices includes -->
|
||||||
<link
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
rel="stylesheet"
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
href="../assets/styles/choices.min.css?version=6.0.3"
|
|
||||||
/>
|
|
||||||
<script src="../assets/scripts/choices.min.js?version=6.0.3"></script>
|
|
||||||
<!-- End Choices includes -->
|
<!-- End Choices includes -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -99,6 +96,18 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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">
|
<div data-test-hook="add-items-disabled">
|
||||||
<label for="choices-add-items-disabled">Add items disabled</label>
|
<label for="choices-add-items-disabled">Add items disabled</label>
|
||||||
<select
|
<select
|
||||||
|
@ -178,13 +187,47 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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">
|
<div data-test-hook="remote-data">
|
||||||
<label for="choices-remote-data">Remote data</label>
|
<label for="choices-remote-data">Remote data</label>
|
||||||
<select
|
<select
|
||||||
class="form-control"
|
class="form-control"
|
||||||
name="choices-remote-data"
|
name="choices-remote-data"
|
||||||
id="choices-remote-data"
|
id="choices-remote-data"
|
||||||
></select>
|
>
|
||||||
|
<option value="">I am a placeholder</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-test-hook="scrolling-dropdown">
|
<div data-test-hook="scrolling-dropdown">
|
||||||
|
@ -262,6 +305,28 @@
|
||||||
></select>
|
></select>
|
||||||
</div>
|
</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">
|
<div data-test-hook="non-string-values">
|
||||||
<label for="choices-non-string-values">Non-string values</label>
|
<label for="choices-non-string-values">Non-string values</label>
|
||||||
<select
|
<select
|
||||||
|
@ -310,11 +375,55 @@
|
||||||
<option value="value2">label2</option>
|
<option value="value2">label2</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const choicesBasic = new Choices('#choices-basic');
|
const choicesBasic = new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('button.disable')
|
.querySelector('button.disable')
|
||||||
|
@ -329,37 +438,79 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-choice', {
|
new Choices('#choices-disabled-choice', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: 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', {
|
new Choices('#choices-add-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-render-choice-limit', {
|
new Choices('#choices-render-choice-limit', {
|
||||||
|
allowHTML: true,
|
||||||
renderChoiceLimit: 1,
|
renderChoiceLimit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-disabled', {
|
new Choices('#choices-search-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
searchEnabled: false,
|
searchEnabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-search-floor', {
|
new Choices('#choices-search-floor', {
|
||||||
|
allowHTML: true,
|
||||||
searchFloor: 5,
|
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', {
|
new Choices('#choices-remote-data', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
}).setChoices(async () => {
|
}).setChoices(async () => {
|
||||||
const res = await fetch('/data');
|
const res = await fetch('/data');
|
||||||
|
@ -367,13 +518,20 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-scrolling-dropdown', {
|
new Choices('#choices-scrolling-dropdown', {
|
||||||
|
allowHTML: true,
|
||||||
shouldSort: false,
|
shouldSort: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-groups');
|
new Choices('#choices-groups', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
const parent = new Choices('#choices-parent');
|
const parent = new Choices('#choices-parent', {
|
||||||
const child = new Choices('#choices-child').disable();
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
const child = new Choices('#choices-child', {
|
||||||
|
allowHTML: true,
|
||||||
|
}).disable();
|
||||||
|
|
||||||
parent.passedElement.element.addEventListener('change', event => {
|
parent.passedElement.element.addEventListener('change', event => {
|
||||||
if (event.detail.value === 'Parent choice 2') {
|
if (event.detail.value === 'Parent choice 2') {
|
||||||
|
@ -384,6 +542,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-custom-properties', {
|
new Choices('#choices-custom-properties', {
|
||||||
|
allowHTML: true,
|
||||||
searchFields: ['label', 'value', 'customProperties.country'],
|
searchFields: ['label', 'value', 'customProperties.country'],
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
|
@ -413,7 +572,13 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new Choices('#choices-custom-properties-html', {
|
||||||
|
allowHTML: true,
|
||||||
|
searchFields: ['label', 'value', 'customProperties'],
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-non-string-values', {
|
new Choices('#choices-non-string-values', {
|
||||||
|
allowHTML: true,
|
||||||
choices: [
|
choices: [
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
|
@ -440,13 +605,77 @@
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-set-choice-by-value').setChoiceByValue(
|
new Choices('#choices-set-choice-by-value', {
|
||||||
'Choice 2',
|
allowHTML: true,
|
||||||
);
|
}).setChoiceByValue('Choice 2');
|
||||||
|
|
||||||
new Choices('#choices-search-by-label', { searchFields: ['label'] });
|
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>
|
</script>
|
||||||
</body>
|
</body>
|
|
@ -15,43 +15,40 @@
|
||||||
<link
|
<link
|
||||||
rel="apple-touch-icon"
|
rel="apple-touch-icon"
|
||||||
sizes="180x180"
|
sizes="180x180"
|
||||||
href="../assets/images/apple-touch-icon.png"
|
href="../../assets/images/apple-touch-icon.png"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-32x32.png"
|
href="../../assets/images/favicon-32x32.png"
|
||||||
sizes="32x32"
|
sizes="32x32"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="icon"
|
||||||
type="image/png"
|
type="image/png"
|
||||||
href="../assets/images/favicon-16x16.png"
|
href="../../assets/images/favicon-16x16.png"
|
||||||
sizes="16x16"
|
sizes="16x16"
|
||||||
/>
|
/>
|
||||||
<link rel="manifest" href="../assets/images/manifest.json" />
|
<link rel="manifest" href="../../assets/images/manifest.json" />
|
||||||
<link
|
<link
|
||||||
rel="mask-icon"
|
rel="mask-icon"
|
||||||
href="../assets/images/safari-pinned-tab.svg"
|
href="../../assets/images/safari-pinned-tab.svg"
|
||||||
color="#00bcd4"
|
color="#00bcd4"
|
||||||
/>
|
/>
|
||||||
<link rel="shortcut icon" href="../assets/images/favicon.ico" />
|
<link rel="shortcut icon" href="../../assets/images/favicon.ico" />
|
||||||
<meta
|
<meta
|
||||||
name="msapplication-config"
|
name="msapplication-config"
|
||||||
content="../assets/images/browserconfig.xml"
|
content="../../assets/images/browserconfig.xml"
|
||||||
/>
|
/>
|
||||||
<meta name="theme-color" content="#ffffff" />
|
<meta name="theme-color" content="#ffffff" />
|
||||||
|
|
||||||
<!-- Ignore these -->
|
<!-- Ignore these -->
|
||||||
<link rel="stylesheet" href="../assets/styles/base.min.css?version=6.0.3" />
|
<link rel="stylesheet" href="../../assets/styles/base.min.css" />
|
||||||
<!-- End ignore these -->
|
<!-- End ignore these -->
|
||||||
|
|
||||||
<!-- Choices includes -->
|
<!-- Choices includes -->
|
||||||
<link
|
<link rel="stylesheet" href="../../assets/styles/choices.min.css" />
|
||||||
rel="stylesheet"
|
<script src="../../assets/scripts/choices.min.js"></script>
|
||||||
href="../assets/styles/choices.min.css?version=6.0.3"
|
|
||||||
/>
|
|
||||||
<script src="../assets/scripts/choices.min.js?version=6.0.3"></script>
|
|
||||||
<!-- End Choices includes -->
|
<!-- End Choices includes -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -79,6 +76,21 @@
|
||||||
<input class="form-control" id="choices-unique-values" type="text" />
|
<input class="form-control" id="choices-unique-values" type="text" />
|
||||||
</div>
|
</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">
|
<div data-test-hook="input-limit">
|
||||||
<label for="choices-input-limit">Input limit</label>
|
<label for="choices-input-limit">Input limit</label>
|
||||||
<input class="form-control" id="choices-input-limit" type="text" />
|
<input class="form-control" id="choices-input-limit" type="text" />
|
||||||
|
@ -137,25 +149,52 @@
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
new Choices('#choices-basic');
|
new Choices('#choices-basic', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-edit-items', {
|
new Choices('#choices-edit-items', {
|
||||||
|
allowHTML: true,
|
||||||
editItems: true,
|
editItems: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-remove-button', {
|
new Choices('#choices-remove-button', {
|
||||||
|
allowHTML: true,
|
||||||
removeItemButton: true,
|
removeItemButton: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-unique-values', {
|
new Choices('#choices-unique-values', {
|
||||||
|
allowHTML: true,
|
||||||
duplicateItemsAllowed: false,
|
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', {
|
new Choices('#choices-input-limit', {
|
||||||
|
allowHTML: true,
|
||||||
maxItemCount: 5,
|
maxItemCount: 5,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-add-item-filter', {
|
new Choices('#choices-add-item-filter', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: true,
|
addItems: true,
|
||||||
addItemFilter: value => {
|
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 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,}))$/;
|
||||||
|
@ -165,17 +204,22 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-adding-items-disabled', {
|
new Choices('#choices-adding-items-disabled', {
|
||||||
|
allowHTML: true,
|
||||||
addItems: false,
|
addItems: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-disabled-via-attr');
|
new Choices('#choices-disabled-via-attr', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepend-append', {
|
new Choices('#choices-prepend-append', {
|
||||||
|
allowHTML: true,
|
||||||
prependValue: 'before-',
|
prependValue: 'before-',
|
||||||
appendValue: '-after',
|
appendValue: '-after',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-prepopulated', {
|
new Choices('#choices-prepopulated', {
|
||||||
|
allowHTML: true,
|
||||||
items: [
|
items: [
|
||||||
'Josh Johnson',
|
'Josh Johnson',
|
||||||
{
|
{
|
||||||
|
@ -189,11 +233,14 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-placeholder', {
|
new Choices('#choices-placeholder', {
|
||||||
|
allowHTML: true,
|
||||||
placeholder: true,
|
placeholder: true,
|
||||||
placeholderValue: 'I am a placeholder',
|
placeholderValue: 'I am a placeholder',
|
||||||
});
|
});
|
||||||
|
|
||||||
new Choices('#choices-within-form');
|
new Choices('#choices-within-form', {
|
||||||
|
allowHTML: true,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
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
|
1
public/types/src/scripts/actions/choices.test.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"choices.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/choices.test.ts"],"names":[],"mappings":""}
|
15
public/types/src/scripts/actions/groups.d.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { ACTION_TYPES } from '../constants';
|
||||||
|
export interface AddGroupAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_GROUP;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
active: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}
|
||||||
|
export declare const addGroup: ({ value, id, active, disabled, }: {
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
active: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}) => AddGroupAction;
|
||||||
|
//# sourceMappingURL=groups.d.ts.map
|
1
public/types/src/scripts/actions/groups.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"groups.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/groups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,YAAY,CAAC,SAAS,CAAC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,QAAQ;QAMf,MAAM;WACH,MAAM;YACL,OAAO;cACL,OAAO;MACf,cAMF,CAAC"}
|
2
public/types/src/scripts/actions/groups.test.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=groups.test.d.ts.map
|
1
public/types/src/scripts/actions/groups.test.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"groups.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/groups.test.ts"],"names":[],"mappings":""}
|
35
public/types/src/scripts/actions/items.d.ts
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { ACTION_TYPES } from '../constants';
|
||||||
|
export interface AddItemAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_ITEM;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
choiceId: number;
|
||||||
|
groupId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}
|
||||||
|
export interface RemoveItemAction {
|
||||||
|
type: typeof ACTION_TYPES.REMOVE_ITEM;
|
||||||
|
id: number;
|
||||||
|
choiceId: number;
|
||||||
|
}
|
||||||
|
export interface HighlightItemAction {
|
||||||
|
type: typeof ACTION_TYPES.HIGHLIGHT_ITEM;
|
||||||
|
id: number;
|
||||||
|
highlighted: boolean;
|
||||||
|
}
|
||||||
|
export declare const addItem: ({ value, label, id, choiceId, groupId, customProperties, placeholder, keyCode, }: {
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
choiceId: number;
|
||||||
|
groupId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}) => AddItemAction;
|
||||||
|
export declare const removeItem: (id: number, choiceId: number) => RemoveItemAction;
|
||||||
|
export declare const highlightItem: (id: number, highlighted: boolean) => HighlightItemAction;
|
||||||
|
//# sourceMappingURL=items.d.ts.map
|
1
public/types/src/scripts/actions/items.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,YAAY,CAAC,WAAW,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,OAAO;QAUd,MAAM;WACH,MAAM;WACN,MAAM;cACH,MAAM;aACP,MAAM;sBACG,MAAM;iBACX,OAAO;aACX,MAAM;MACb,aAUF,CAAC;AAEH,eAAO,MAAM,UAAU,OAAQ,MAAM,YAAY,MAAM,KAAG,gBAIxD,CAAC;AAEH,eAAO,MAAM,aAAa,OACpB,MAAM,eACG,OAAO,KACnB,mBAID,CAAC"}
|
2
public/types/src/scripts/actions/items.test.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=items.test.d.ts.map
|
1
public/types/src/scripts/actions/items.test.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"items.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/items.test.ts"],"names":[],"mappings":""}
|
17
public/types/src/scripts/actions/misc.d.ts
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import { ACTION_TYPES } from '../constants';
|
||||||
|
import { State } from '../interfaces/state';
|
||||||
|
export interface ClearAllAction {
|
||||||
|
type: typeof ACTION_TYPES.CLEAR_ALL;
|
||||||
|
}
|
||||||
|
export interface ResetToAction {
|
||||||
|
type: typeof ACTION_TYPES.RESET_TO;
|
||||||
|
state: State;
|
||||||
|
}
|
||||||
|
export interface SetIsLoadingAction {
|
||||||
|
type: typeof ACTION_TYPES.SET_IS_LOADING;
|
||||||
|
isLoading: boolean;
|
||||||
|
}
|
||||||
|
export declare const clearAll: () => ClearAllAction;
|
||||||
|
export declare const resetTo: (state: State) => ResetToAction;
|
||||||
|
export declare const setIsLoading: (isLoading: boolean) => SetIsLoadingAction;
|
||||||
|
//# sourceMappingURL=misc.d.ts.map
|
1
public/types/src/scripts/actions/misc.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/misc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,YAAY,CAAC,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;IACnC,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,YAAY,CAAC,cAAc,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,QAAO,cAE1B,CAAC;AAEH,eAAO,MAAM,OAAO,UAAW,KAAK,KAAG,aAGrC,CAAC;AAEH,eAAO,MAAM,YAAY,cAAe,OAAO,KAAG,kBAGhD,CAAC"}
|
2
public/types/src/scripts/actions/misc.test.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=misc.test.d.ts.map
|
1
public/types/src/scripts/actions/misc.test.d.ts.map
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"misc.test.d.ts","sourceRoot":"","sources":["../../../../../src/scripts/actions/misc.test.ts"],"names":[],"mappings":""}
|
218
public/types/src/scripts/choices.d.ts
vendored
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
import { Container, Dropdown, Input, List, WrappedInput, WrappedSelect } from './components';
|
||||||
|
import { Choice } from './interfaces/choice';
|
||||||
|
import { Group } from './interfaces/group';
|
||||||
|
import { Item } from './interfaces/item';
|
||||||
|
import { Notice } from './interfaces/notice';
|
||||||
|
import { Options } from './interfaces/options';
|
||||||
|
import { State } from './interfaces/state';
|
||||||
|
import Store from './store/store';
|
||||||
|
import templates from './templates';
|
||||||
|
/**
|
||||||
|
* Choices
|
||||||
|
* @author Josh Johnson<josh@joshuajohnson.co.uk>
|
||||||
|
*/
|
||||||
|
declare class Choices implements Choices {
|
||||||
|
static get defaults(): {
|
||||||
|
options: Partial<Options>;
|
||||||
|
templates: typeof templates;
|
||||||
|
};
|
||||||
|
initialised: boolean;
|
||||||
|
config: Options;
|
||||||
|
passedElement: WrappedInput | WrappedSelect;
|
||||||
|
containerOuter: Container;
|
||||||
|
containerInner: Container;
|
||||||
|
choiceList: List;
|
||||||
|
itemList: List;
|
||||||
|
input: Input;
|
||||||
|
dropdown: Dropdown;
|
||||||
|
_isTextElement: boolean;
|
||||||
|
_isSelectOneElement: boolean;
|
||||||
|
_isSelectMultipleElement: boolean;
|
||||||
|
_isSelectElement: boolean;
|
||||||
|
_store: Store;
|
||||||
|
_templates: typeof templates;
|
||||||
|
_initialState: State;
|
||||||
|
_currentState: State;
|
||||||
|
_prevState: State;
|
||||||
|
_currentValue: string;
|
||||||
|
_canSearch: boolean;
|
||||||
|
_isScrollingOnIe: boolean;
|
||||||
|
_highlightPosition: number;
|
||||||
|
_wasTap: boolean;
|
||||||
|
_isSearching: boolean;
|
||||||
|
_placeholderValue: string | null;
|
||||||
|
_baseId: string;
|
||||||
|
_direction: HTMLElement['dir'];
|
||||||
|
_idNames: {
|
||||||
|
itemChoice: string;
|
||||||
|
};
|
||||||
|
_presetGroups: Group[] | HTMLOptGroupElement[] | Element[];
|
||||||
|
_presetOptions: Item[] | HTMLOptionElement[];
|
||||||
|
_presetChoices: Partial<Choice>[];
|
||||||
|
_presetItems: Item[] | string[];
|
||||||
|
constructor(element?: string | Element | HTMLInputElement | HTMLSelectElement, userConfig?: Partial<Options>);
|
||||||
|
init(): void;
|
||||||
|
destroy(): void;
|
||||||
|
enable(): this;
|
||||||
|
disable(): this;
|
||||||
|
highlightItem(item: Item, runEvent?: boolean): this;
|
||||||
|
unhighlightItem(item: Item): this;
|
||||||
|
highlightAll(): this;
|
||||||
|
unhighlightAll(): this;
|
||||||
|
removeActiveItemsByValue(value: string): this;
|
||||||
|
removeActiveItems(excludedId: number): this;
|
||||||
|
removeHighlightedItems(runEvent?: boolean): this;
|
||||||
|
showDropdown(preventInputFocus?: boolean): this;
|
||||||
|
hideDropdown(preventInputBlur?: boolean): this;
|
||||||
|
getValue(valueOnly?: boolean): string[] | Item[] | Item | string;
|
||||||
|
setValue(items: string[] | Item[]): this;
|
||||||
|
setChoiceByValue(value: string | string[]): this;
|
||||||
|
/**
|
||||||
|
* Set choices of select input via an array of objects (or function that returns array of object or promise of it),
|
||||||
|
* a value field name and a label field name.
|
||||||
|
* This behaves the same as passing items via the choices option but can be called after initialising Choices.
|
||||||
|
* This can also be used to add groups of choices (see example 2); Optionally pass a true `replaceChoices` value to remove any existing choices.
|
||||||
|
* Optionally pass a `customProperties` object to add additional data to your choices (useful when searching/filtering etc).
|
||||||
|
*
|
||||||
|
* **Input types affected:** select-one, select-multiple
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices([
|
||||||
|
* {value: 'One', label: 'Label One', disabled: true},
|
||||||
|
* {value: 'Two', label: 'Label Two', selected: true},
|
||||||
|
* {value: 'Three', label: 'Label Three'},
|
||||||
|
* ], 'value', 'label', false);
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices(async () => {
|
||||||
|
* try {
|
||||||
|
* const items = await fetch('/items');
|
||||||
|
* return items.json()
|
||||||
|
* } catch(err) {
|
||||||
|
* console.error(err)
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```js
|
||||||
|
* const example = new Choices(element);
|
||||||
|
*
|
||||||
|
* example.setChoices([{
|
||||||
|
* label: 'Group one',
|
||||||
|
* id: 1,
|
||||||
|
* disabled: false,
|
||||||
|
* choices: [
|
||||||
|
* {value: 'Child One', label: 'Child One', selected: true},
|
||||||
|
* {value: 'Child Two', label: 'Child Two', disabled: true},
|
||||||
|
* {value: 'Child Three', label: 'Child Three'},
|
||||||
|
* ]
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* label: 'Group two',
|
||||||
|
* id: 2,
|
||||||
|
* disabled: false,
|
||||||
|
* choices: [
|
||||||
|
* {value: 'Child Four', label: 'Child Four', disabled: true},
|
||||||
|
* {value: 'Child Five', label: 'Child Five'},
|
||||||
|
* {value: 'Child Six', label: 'Child Six', customProperties: {
|
||||||
|
* description: 'Custom description about child six',
|
||||||
|
* random: 'Another random custom property'
|
||||||
|
* }},
|
||||||
|
* ]
|
||||||
|
* }], 'value', 'label', false);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
setChoices(choicesArrayOrFetcher?: Choice[] | Group[] | ((instance: Choices) => Choice[] | Promise<Choice[]>), value?: string, label?: string, replaceChoices?: boolean): this | Promise<this>;
|
||||||
|
clearChoices(): this;
|
||||||
|
clearStore(): this;
|
||||||
|
clearInput(): this;
|
||||||
|
_render(): void;
|
||||||
|
_renderChoices(): void;
|
||||||
|
_renderItems(): void;
|
||||||
|
_createGroupsFragment(groups: Group[], choices: Choice[], fragment?: DocumentFragment): DocumentFragment;
|
||||||
|
_createChoicesFragment(choices: Choice[], fragment?: DocumentFragment, withinGroup?: boolean): DocumentFragment;
|
||||||
|
_createItemsFragment(items: Item[], fragment?: DocumentFragment): DocumentFragment;
|
||||||
|
_triggerChange(value: any): void;
|
||||||
|
_selectPlaceholderChoice(placeholderChoice: Choice): void;
|
||||||
|
_handleButtonAction(activeItems?: Item[], element?: HTMLElement): void;
|
||||||
|
_handleItemAction(activeItems?: Item[], element?: HTMLElement, hasShiftKey?: boolean): void;
|
||||||
|
_handleChoiceAction(activeItems?: Item[], element?: HTMLElement): void;
|
||||||
|
_handleBackspace(activeItems?: Item[]): void;
|
||||||
|
_startLoading(): void;
|
||||||
|
_stopLoading(): void;
|
||||||
|
_handleLoadingState(setLoading?: boolean): void;
|
||||||
|
_handleSearch(value: string): void;
|
||||||
|
_canAddItem(activeItems: Item[], value: string): Notice;
|
||||||
|
_searchChoices(value: string): number;
|
||||||
|
_addEventListeners(): void;
|
||||||
|
_removeEventListeners(): void;
|
||||||
|
_onKeyDown(event: KeyboardEvent): void;
|
||||||
|
_onKeyUp({ target, keyCode, }: Pick<KeyboardEvent, 'target' | 'keyCode'>): void;
|
||||||
|
_onSelectKey(event: KeyboardEvent, hasItems: boolean): void;
|
||||||
|
_onEnterKey(event: KeyboardEvent, activeItems: Item[], hasActiveDropdown: boolean): void;
|
||||||
|
_onEscapeKey(hasActiveDropdown: boolean): void;
|
||||||
|
_onDirectionKey(event: KeyboardEvent, hasActiveDropdown: boolean): void;
|
||||||
|
_onDeleteKey(event: KeyboardEvent, activeItems: Item[], hasFocusedInput: boolean): void;
|
||||||
|
_onTouchMove(): void;
|
||||||
|
_onTouchEnd(event: TouchEvent): void;
|
||||||
|
/**
|
||||||
|
* Handles mousedown event in capture mode for containetOuter.element
|
||||||
|
*/
|
||||||
|
_onMouseDown(event: MouseEvent): void;
|
||||||
|
/**
|
||||||
|
* Handles mouseover event over this.dropdown
|
||||||
|
* @param {MouseEvent} event
|
||||||
|
*/
|
||||||
|
_onMouseOver({ target }: Pick<MouseEvent, 'target'>): void;
|
||||||
|
_onClick({ target }: Pick<MouseEvent, 'target'>): void;
|
||||||
|
_onFocus({ target }: Pick<FocusEvent, 'target'>): void;
|
||||||
|
_onBlur({ target }: Pick<FocusEvent, 'target'>): void;
|
||||||
|
_onFormReset(): void;
|
||||||
|
_highlightChoice(el?: HTMLElement | null): void;
|
||||||
|
_addItem({ value, label, choiceId, groupId, customProperties, placeholder, keyCode, }: {
|
||||||
|
value: string;
|
||||||
|
label?: string | null;
|
||||||
|
choiceId?: number;
|
||||||
|
groupId?: number;
|
||||||
|
customProperties?: object;
|
||||||
|
placeholder?: boolean;
|
||||||
|
keyCode?: number;
|
||||||
|
}): void;
|
||||||
|
_removeItem(item: Item): void;
|
||||||
|
_addChoice({ value, label, isSelected, isDisabled, groupId, customProperties, placeholder, keyCode, }: {
|
||||||
|
value: string;
|
||||||
|
label?: string | null;
|
||||||
|
isSelected?: boolean;
|
||||||
|
isDisabled?: boolean;
|
||||||
|
groupId?: number;
|
||||||
|
customProperties?: Record<string, any>;
|
||||||
|
placeholder?: boolean;
|
||||||
|
keyCode?: number;
|
||||||
|
}): void;
|
||||||
|
_addGroup({ group, id, valueKey, labelKey }: {
|
||||||
|
group: any;
|
||||||
|
id: any;
|
||||||
|
valueKey?: string | undefined;
|
||||||
|
labelKey?: string | undefined;
|
||||||
|
}): void;
|
||||||
|
_getTemplate(template: string, ...args: any): any;
|
||||||
|
_createTemplates(): void;
|
||||||
|
_createElements(): void;
|
||||||
|
_createStructure(): void;
|
||||||
|
_addPredefinedGroups(groups: Group[] | HTMLOptGroupElement[] | Element[]): void;
|
||||||
|
_addPredefinedChoices(choices: Partial<Choice>[]): void;
|
||||||
|
_addPredefinedItems(items: Item[] | string[]): void;
|
||||||
|
_setChoiceOrItem(item: any): void;
|
||||||
|
_findAndSelectChoiceByValue(value: string): void;
|
||||||
|
_generatePlaceholderValue(): string | null;
|
||||||
|
}
|
||||||
|
export default Choices;
|
||||||
|
//# sourceMappingURL=choices.d.ts.map
|