зеркало из https://github.com/microsoft/sonder-ui.git
trap enter and escape keypresses when updating select menu
This commit is contained in:
Родитель
c963711c9a
Коммит
7ba3da7869
|
@ -11,11 +11,10 @@
|
|||
"dist/"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "stencil build --docs && npm run copy-assets",
|
||||
"start": "stencil build --dev --watch --serve && npm run copy-assets",
|
||||
"build": "stencil build --docs",
|
||||
"start": "stencil build --dev --watch --serve",
|
||||
"test": "stencil test --spec --e2e",
|
||||
"test.watch": "stencil test --spec --e2e --watchAll",
|
||||
"copy-assets": "cp -r src/assets/ www/ && cp src/style.css www/ && cp src/*.html www/"
|
||||
"test.watch": "stencil test --spec --e2e --watchAll"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -170,6 +170,7 @@ export class ComboAutocomplete {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -159,9 +159,11 @@ export class ComboAutoselect {
|
|||
event.preventDefault();
|
||||
return this.onOptionChange(getUpdatedIndex(this.activeIndex, max, action));
|
||||
case MenuActions.CloseSelect:
|
||||
event.preventDefault();
|
||||
this.selectOption(this.activeIndex);
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
this.activeIndex = 0;
|
||||
this.value = this.selectedValue;
|
||||
this.filteredOptions = this.options;
|
||||
|
|
|
@ -156,6 +156,7 @@ export class ComboFilter {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -55,14 +55,16 @@ export class ComboNative {
|
|||
|
||||
return ([
|
||||
<label htmlFor={htmlId} class="combo-label">{label}</label>,
|
||||
<select
|
||||
id={htmlId}
|
||||
class="combo combo-input"
|
||||
required={required ? true: null }
|
||||
onChange={(event: Event) => this.selectHandler((event.target as HTMLSelectElement).value)}
|
||||
>
|
||||
{options.map((option) => <option value={option.value}>{option.name}</option>)}
|
||||
</select>
|
||||
<div class="combo">
|
||||
<select
|
||||
id={htmlId}
|
||||
class="combo-input"
|
||||
required={required ? true: null }
|
||||
onChange={(event: Event) => this.selectHandler((event.target as HTMLSelectElement).value)}
|
||||
>
|
||||
{options.map((option) => <option value={option.value}>{option.name}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -143,6 +143,7 @@ export class ComboNoFilter {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -116,6 +116,7 @@ export class ComboNoInput {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Type:
|
||||
this.activeIndex = Math.max(0, getIndexByLetter(this.options, key));
|
||||
|
|
|
@ -128,6 +128,7 @@ export class ComboReadonly {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Type:
|
||||
this.activeIndex = Math.max(0, getIndexByLetter(this.options, key));
|
||||
|
|
|
@ -164,6 +164,7 @@ export class ListboxButton {
|
|||
case MenuActions.CloseSelect:
|
||||
this.selectOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Type:
|
||||
this.activeIndex = Math.max(0, getIndexByLetter(this.options, key));
|
||||
|
|
|
@ -180,8 +180,10 @@ export class MultiselectButtons {
|
|||
event.preventDefault();
|
||||
return this.onOptionChange(getUpdatedIndex(this.activeIndex, max, action));
|
||||
case MenuActions.CloseSelect:
|
||||
event.preventDefault();
|
||||
return this.updateOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -167,8 +167,10 @@ export class MultiselectCSV {
|
|||
event.preventDefault();
|
||||
return this.onOptionChange(getUpdatedIndex(this.activeIndex, max, action));
|
||||
case MenuActions.CloseSelect:
|
||||
event.preventDefault();
|
||||
return this.updateOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -186,8 +186,10 @@ export class MultiselectInline {
|
|||
event.preventDefault();
|
||||
return this.onOptionChange(getUpdatedIndex(this.activeIndex, max, action));
|
||||
case MenuActions.CloseSelect:
|
||||
event.preventDefault();
|
||||
return this.updateOption(this.activeIndex);
|
||||
case MenuActions.Close:
|
||||
event.preventDefault();
|
||||
return this.updateMenuState(false);
|
||||
case MenuActions.Open:
|
||||
return this.updateMenuState(true);
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
|
||||
<title>Order Pizza</title>
|
||||
<link rel="stylesheet" href="/style.css"></style>
|
||||
<script src="/build/caiacc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="example-form">
|
||||
<h1 id="page-title">Find a Pizza Store</h1>
|
||||
|
||||
<form aria-labelledby="page-title" novalidate>
|
||||
|
||||
<combo-nofilter label="State" class="state-select"></combo-nofilter>
|
||||
|
||||
<combo-readonly label="Store" class="store-select"></combo-readonly>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { states } from './assets/stateData.js';
|
||||
|
||||
const stateCombo = document.querySelector('.state-select');
|
||||
stateCombo.options = states;
|
||||
|
||||
const storeCombo = document.querySelector('.store-select');
|
||||
storeCombo.options = [{ name: 'Amherst', value: 'amherst'}, { name: 'Hadley', value: 'hadley'}, { name: 'Northampton', value: 'northampton'}, { name: 'Greenfield', value: 'greenfield'}];
|
||||
|
||||
const multiCombo = document.querySelector('.multi-select');
|
||||
multiCombo.options = countries;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -22,8 +22,8 @@ body {
|
|||
}
|
||||
|
||||
.combo::after {
|
||||
border-bottom: 1px solid rgba(0,0,0,.42);
|
||||
border-right: 1px solid rgba(0,0,0,.42);
|
||||
border-bottom: 2px solid rgba(0,0,0,.5);
|
||||
border-right: 2px solid rgba(0,0,0,.5);
|
||||
content: '';
|
||||
display: block;
|
||||
height: 12px;
|
||||
|
@ -37,7 +37,7 @@ body {
|
|||
|
||||
.combo-input {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid rgba(0,0,0,.42);
|
||||
border: 2px solid rgba(0,0,0,.5);
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
min-height: calc(1.4em + 26px);
|
||||
|
@ -46,6 +46,12 @@ body {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
select.combo-input {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.open .combo-input {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
font-family: "Segoe UI", SegoeUI, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 18px;
|
||||
line-height: 1.4em;
|
||||
|
@ -16,7 +17,8 @@ body {
|
|||
}
|
||||
|
||||
.example-form {
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0,0,0,.5);
|
||||
border-radius: 5px;
|
||||
max-width: 460px;
|
||||
margin: 100px auto;
|
||||
|
@ -26,17 +28,30 @@ body {
|
|||
.example-form h1 {
|
||||
font-size: 2rem;
|
||||
line-height: 1.1;
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid rgba(0,0,0,.42);
|
||||
.example-form label {
|
||||
font-weight: bold;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.example-form button[type=submit] {
|
||||
background-color: #0067b8;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
min-height: calc(1.4em + 26px);
|
||||
padding: 12px 16px 14px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
margin-top: 1.5em;
|
||||
padding: 0.5em 0.75em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.example-form button[type=submit]:focus {
|
||||
box-shadow: 0 0 6px 2px #0067b8;
|
||||
outline: 4px solid transparent;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
|
||||
<title>Travel profile form</title>
|
||||
<link rel="stylesheet" href="/style.css"></style>
|
||||
<script src="/build/caiacc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="example-form">
|
||||
<h1 id="page-title">Create your travel profile</h1>
|
||||
|
||||
<form aria-labelledby="page-title" novalidate>
|
||||
<label for="name">Name (required)</label>
|
||||
<input type="text" class="form-input" id="name" required>
|
||||
|
||||
<combo-native label="Gender (required)" required="true" class="gender-select form-input"></combo-native>
|
||||
|
||||
<combo-filter label="Current country of residence" class="country-select form-input"></combo-filter>
|
||||
|
||||
<multiselect-csv label="I want to visit (choose all countries that apply):" class="multi-select form-input"></multiselect-csv>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { states } from './assets/stateData.js';
|
||||
import { countries } from './assets/countryData.js';
|
||||
|
||||
const genderCombo = document.querySelector('.gender-select');
|
||||
genderCombo.options = [{ name: 'Female', value: 'f' }, { name: 'Male', value: 'm' }, { name: 'Other', value: 'o' }, { name: 'Prefer not to say', value: 'na' }];
|
||||
|
||||
const countryCombo = document.querySelector('.country-select');
|
||||
countryCombo.options = countries;
|
||||
|
||||
const multiCombo = document.querySelector('.multi-select');
|
||||
multiCombo.options = countries;
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -9,5 +9,10 @@ export const config: Config = {
|
|||
type: 'www',
|
||||
serviceWorker: null // disable service workers
|
||||
}
|
||||
],
|
||||
copy: [
|
||||
{ src: 'assets' },
|
||||
{ src: 'studies' },
|
||||
{ src: 'style.css' }
|
||||
]
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче