@advanced-rest-client/oauth2-scope-selector
Advanced tools
Comparing version 3.0.0-preview.3 to 3.0.0
@@ -75,1 +75,5 @@ <a name="2.0.2"></a> | ||
# [3.0.0](https://github.com/advanced-rest-client/oauth2-scope-selector/compare/1.0.6...3.0.0) (2019-08-20) | ||
@@ -15,12 +15,8 @@ /** | ||
import {PolymerElement} from '@polymer/polymer/polymer-element.js'; | ||
import {html, css, LitElement} from 'lit-element'; | ||
import {IronValidatableBehavior} from '@polymer/iron-validatable-behavior/iron-validatable-behavior.js'; | ||
import {ValidatableMixin} from '@anypoint-web-components/validatable-mixin/validatable-mixin.js'; | ||
import {IronControlState} from '@polymer/iron-behaviors/iron-control-state.js'; | ||
import {ControlStateMixin} from '@anypoint-web-components/anypoint-control-mixins/anypoint-control-mixins.js'; | ||
import {html} from '@polymer/polymer/lib/utils/html-tag.js'; | ||
import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js'; | ||
declare namespace UiElements { | ||
@@ -39,3 +35,3 @@ | ||
* supported by the endpoint. When the list is set, autocomplete is enabled. | ||
* Autocomplete is supported by `paper-autocomplete` element. | ||
* Autocomplete is supported by `anypoint-autocomplete` element. | ||
* | ||
@@ -99,30 +95,8 @@ * Setting `prevent-custom-scopes` dissallows adding a scope that is not defined | ||
* ``` | ||
* | ||
* ## Changes in version 2 | ||
* | ||
* - `scopes` property is renamed to `value` | ||
* - The element can now work with `iron-form` as a form element. | ||
* | ||
* ### Styling | ||
* `<oauth2-scope-selector>` provides the following custom properties and mixins for styling: | ||
* | ||
* Custom property | Description | Default | ||
* ----------------|-------------|---------- | ||
* `--oauth2-scope-selector` | Mixin applied to the element | `{}` | ||
* `--oauth2-scope-selector-label` | Mixin applied to the label element (title of the control) | `{}` | ||
* `--oauth2-scope-selector-list-item` | Mixin applied to each selected scope item. Consider setting `paper-item` styles for theming. | `{}` | ||
* `--oauth2-scope-selector-item-description-color` | Color of the description of the scope when `allowedScopes` contains description. | `#737373` | ||
* | ||
* ### Theming | ||
* Use this mixins as a theming option across all ARC elements. | ||
* | ||
* Custom property | Description | Default | ||
* ----------------|-------------|---------- | ||
* `--icon-button` | Mixin applied to `paper-icon-buttons`. | `{}` | ||
* `--icon-button-hover` | Mixin applied to `paper-icon-buttons` when hovered. | `{}` | ||
* `--form-label` | Mixin applied to all labels that are form elements | `{}` | ||
* `--api-form-action-icon-color` | Color of the add and remove scope buttons | `rgba(0, 0, 0, 0.74)` | ||
* `--api-form-action-icon-hover-color` | Color of the add and remove scope buttons when hovered | `rgba(0, 0, 0, 0.84)` | ||
*/ | ||
class OAuth2ScopeSelector { | ||
class OAuth2ScopeSelector extends | ||
ValidatableMixin( | ||
ControlStateMixin( | ||
Object)) { | ||
readonly _invalidMessage: any; | ||
@@ -136,19 +110,2 @@ /** | ||
/** | ||
* Form input name | ||
*/ | ||
name: string|null|undefined; | ||
/** | ||
* Current value entered by the user. This is not a scope and it is not | ||
* yet in the scopes list. User has to accept the scope before it become | ||
* available in the scopes list. | ||
*/ | ||
currentValue: string|null|undefined; | ||
/** | ||
* Target for `paper-autocomplete` | ||
*/ | ||
readonly inputTarget: HTMLElement|null|undefined; | ||
/** | ||
* List of available scopes. | ||
@@ -172,2 +129,27 @@ * It can be either list of string or list of object. If this is the | ||
/** | ||
* Returns true if the value is invalid. | ||
* | ||
* If `autoValidate` is true, the `invalid` attribute is managed automatically, | ||
* which can clobber attempts to manage it manually. | ||
*/ | ||
invalid: boolean|null|undefined; | ||
/** | ||
* Form input name | ||
*/ | ||
name: string|null|undefined; | ||
/** | ||
* Current value entered by the user. This is not a scope and it is not | ||
* yet in the scopes list. User has to accept the scope before it become | ||
* available in the scopes list. | ||
*/ | ||
currentValue: string|null|undefined; | ||
/** | ||
* Target for `anypoint-autocomplete` | ||
*/ | ||
_inputTarget: object|null|undefined; | ||
/** | ||
* allowed to be add. | ||
@@ -180,3 +162,3 @@ */ | ||
*/ | ||
readonly _allowedIsObject: boolean|null|undefined; | ||
_allowedIsObject: boolean|null|undefined; | ||
@@ -191,22 +173,26 @@ /** | ||
*/ | ||
readonly _autocompleteScopes: any[]|null|undefined; | ||
_autocompleteScopes: any[]|null|undefined; | ||
/** | ||
* True if the element has attached autocomplete element. | ||
* Set to true to mark the input as required. | ||
*/ | ||
readonly hasAutocomplete: object|null; | ||
required: boolean|null|undefined; | ||
/** | ||
* Returns true if the value is invalid. | ||
* | ||
* If `autoValidate` is true, the `invalid` attribute is managed automatically, | ||
* which can clobber attempts to manage it manually. | ||
* When set the editor is in read only mode. | ||
*/ | ||
invalid: boolean|null|undefined; | ||
readOnly: boolean|null|undefined; | ||
/** | ||
* Set to true to mark the input as required. | ||
* Enables Anypoint legacy styling | ||
*/ | ||
required: boolean|null|undefined; | ||
ready(): void; | ||
legacy: boolean|null|undefined; | ||
/** | ||
* Enables Material Design outlined style | ||
*/ | ||
outlined: boolean|null|undefined; | ||
_scopesListTemplate(): any; | ||
render(): any; | ||
firstUpdated(): void; | ||
_invalidChanged(invalid: any): void; | ||
@@ -225,3 +211,3 @@ | ||
/** | ||
* Handler for the `paper-autocomplete` selected event. | ||
* Handler for the `anypoint-autocomplete` selected event. | ||
*/ | ||
@@ -261,10 +247,2 @@ _suggestionSelected(e: Event|null): void; | ||
/** | ||
* Computes value for `hasAutocomplete`. | ||
* | ||
* @param scopes List of scopes | ||
* @returns True if scopes are set | ||
*/ | ||
_computeHasAutocomplete(scopes: any[]|null): Boolean|null; | ||
/** | ||
* Compute function for the _allowedIsObject. Check first item of the | ||
@@ -295,2 +273,3 @@ * `allowedScopes` array if it is an object (return `true`) or | ||
_handleAutoValidate(autoValidate: any): void; | ||
_currentValueHandler(e: any): void; | ||
} | ||
@@ -297,0 +276,0 @@ } |
@@ -14,15 +14,19 @@ /** | ||
*/ | ||
import {PolymerElement} from '../../@polymer/polymer/polymer-element.js'; | ||
import {IronValidatableBehavior} from '../../@polymer/iron-validatable-behavior/iron-validatable-behavior.js'; | ||
import {IronControlState} from '../../@polymer/iron-behaviors/iron-control-state.js'; | ||
import {html} from '../../@polymer/polymer/lib/utils/html-tag.js'; | ||
import {mixinBehaviors} from '../../@polymer/polymer/lib/legacy/class.js'; | ||
import '../../@polymer/polymer/lib/elements/dom-repeat.js'; | ||
import '../../@polymer/polymer/lib/elements/dom-if.js'; | ||
import '../../@polymer/iron-flex-layout/iron-flex-layout.js'; | ||
import '../../@polymer/paper-input/paper-input.js'; | ||
import '../../@polymer/paper-icon-button/paper-icon-button.js'; | ||
import '../../@polymer/paper-toast/paper-toast.js'; | ||
import '../../@advanced-rest-client/arc-icons/arc-icons.js'; | ||
import '../../@advanced-rest-client/paper-autocomplete/paper-autocomplete.js'; | ||
import { | ||
html, | ||
css, | ||
LitElement | ||
} from 'lit-element'; | ||
import { | ||
ValidatableMixin | ||
} from '@anypoint-web-components/validatable-mixin/validatable-mixin.js'; | ||
import { | ||
ControlStateMixin | ||
} from '@anypoint-web-components/anypoint-control-mixins/anypoint-control-mixins.js'; | ||
import '@anypoint-web-components/anypoint-input/anypoint-input.js'; | ||
import '@anypoint-web-components/anypoint-button/anypoint-icon-button.js'; | ||
import '@anypoint-web-components/anypoint-autocomplete/anypoint-autocomplete.js'; | ||
import '@polymer/paper-toast/paper-toast.js'; | ||
import '@advanced-rest-client/arc-icons/arc-icons.js'; | ||
import '@polymer/iron-icon/iron-icon.js'; | ||
/** | ||
@@ -39,3 +43,3 @@ A selector for OAuth 2.0 scope. Provides the UI to enter a scope for OAuth 2.0 settings. | ||
supported by the endpoint. When the list is set, autocomplete is enabled. | ||
Autocomplete is supported by `paper-autocomplete` element. | ||
Autocomplete is supported by `anypoint-autocomplete` element. | ||
@@ -100,143 +104,164 @@ Setting `prevent-custom-scopes` dissallows adding a scope that is not defined | ||
## Changes in version 2 | ||
- `scopes` property is renamed to `value` | ||
- The element can now work with `iron-form` as a form element. | ||
### Styling | ||
`<oauth2-scope-selector>` provides the following custom properties and mixins for styling: | ||
Custom property | Description | Default | ||
----------------|-------------|---------- | ||
`--oauth2-scope-selector` | Mixin applied to the element | `{}` | ||
`--oauth2-scope-selector-label` | Mixin applied to the label element (title of the control) | `{}` | ||
`--oauth2-scope-selector-list-item` | Mixin applied to each selected scope item. Consider setting `paper-item` styles for theming. | `{}` | ||
`--oauth2-scope-selector-item-description-color` | Color of the description of the scope when `allowedScopes` contains description. | `#737373` | ||
### Theming | ||
Use this mixins as a theming option across all ARC elements. | ||
Custom property | Description | Default | ||
----------------|-------------|---------- | ||
`--icon-button` | Mixin applied to `paper-icon-buttons`. | `{}` | ||
`--icon-button-hover` | Mixin applied to `paper-icon-buttons` when hovered. | `{}` | ||
`--form-label` | Mixin applied to all labels that are form elements | `{}` | ||
`--api-form-action-icon-color` | Color of the add and remove scope buttons | `rgba(0, 0, 0, 0.74)` | ||
`--api-form-action-icon-hover-color` | Color of the add and remove scope buttons when hovered | `rgba(0, 0, 0, 0.84)` | ||
@customElement | ||
@polymer | ||
@demo demo/index.html | ||
@memberof UiElements | ||
@appliesMixin ValidatableMixin | ||
@appliesMixin ControlStateMixin | ||
*/ | ||
class OAuth2ScopeSelector extends mixinBehaviors([IronControlState, IronValidatableBehavior], PolymerElement) { | ||
static get template() { | ||
return html` | ||
<style> | ||
:host { | ||
display: block; | ||
outline: none; | ||
@apply --oauth2-scope-selector; | ||
} | ||
class OAuth2ScopeSelector extends ControlStateMixin(ValidatableMixin(LitElement)) { | ||
static get styles() { | ||
return css ` | ||
:host { | ||
display: block; | ||
outline: none; | ||
box-sizing: border-box; | ||
.form-label { | ||
@apply --form-label; | ||
@apply --oauth2-scope-selector-label; | ||
} | ||
font-size: var(--arc-font-body1-font-size); | ||
font-weight: var(--arc-font-body1-font-weight); | ||
line-height: var(--arc-font-body1-line-height); | ||
} | ||
.item { | ||
width: calc(100% - 32px); | ||
@apply --oauth2-scope-selector-list-item; | ||
} | ||
anypoint-autocomplete { | ||
top: 52px; | ||
} | ||
paper-autocomplete { | ||
top: 52px; | ||
} | ||
.input-container { | ||
position: relative; | ||
} | ||
.input-container { | ||
position: relative; | ||
} | ||
.add-button, | ||
.delete-icon { | ||
margin-left: 12px; | ||
} | ||
.add-button, | ||
.delete-icon { | ||
color: var(--api-form-action-icon-color, rgba(0, 0, 0, 0.74)); | ||
transition: color 0.25s linear; | ||
margin-left: 8px; | ||
@apply --icon-button; | ||
} | ||
.form-label { | ||
margin: 12px 8px; | ||
} | ||
.add-button:hover, | ||
.delete-icon:hover { | ||
color: var(--api-form-action-icon-hover-color, rgba(0, 0, 0, 0.84)); | ||
@apply --icon-button-hover; | ||
} | ||
.scopes-list { | ||
list-style: none; | ||
margin: 12px 8px; | ||
padding: 0; | ||
} | ||
.scope-item { | ||
@apply --layout-horizontal; | ||
@apply --layout-center; | ||
} | ||
.scope-item { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
} | ||
.scope-display { | ||
overflow: hidden; | ||
@apply --arc-font-body1; | ||
font-size: 16px; | ||
} | ||
.scope-display { | ||
overflow: hidden; | ||
font-size: 16px; | ||
} | ||
.scope-item[two-line] { | ||
margin-bottom: 12px; | ||
} | ||
.scope-item[two-line] { | ||
margin-bottom: 12px; | ||
} | ||
.scope-item[two-line] .scope-display { | ||
font-weight: 400; | ||
} | ||
.scope-item[two-line] .scope-display { | ||
font-weight: 400; | ||
} | ||
.scope-item-label { | ||
text-overflow: ellipsis; | ||
overflow: hidden; | ||
white-space: nowrap; | ||
.scope-item-label { | ||
text-overflow: ellipsis; | ||
overflow: hidden; | ||
white-space: nowrap; | ||
} | ||
.scope-display div[secondary] { | ||
font-size: 14px; | ||
font-weight: 400; | ||
line-height: 20px; | ||
color: var(--oauth2-scope-selector-item-description-color, #737373); | ||
}`; | ||
} | ||
_scopesListTemplate() { | ||
const value = this.value; | ||
if (!value || !value.length) { | ||
return; | ||
} | ||
const { | ||
readOnly, | ||
_allowedIsObject | ||
} = this; | ||
return value.map((item, index) => html` | ||
<li class="scope-item" ?two-line="${_allowedIsObject}"> | ||
<div class="scope-display"> | ||
<div class="scope-item-label">${item}</div> | ||
<div secondary="">${this._computeItemDescription(item, _allowedIsObject)}</div> | ||
</div> | ||
<anypoint-icon-button | ||
class="delete-icon" | ||
data-index="${index}" | ||
data-action="remove-scope" | ||
@click="${this._removeScope}" | ||
?disabled="${readOnly}" | ||
aria-label="Press to remove this scope from the list" | ||
title="Remove scope"> | ||
<iron-icon icon="arc:remove-circle-outline"></iron-icon> | ||
</anypoint-icon-button> | ||
</li>`); | ||
} | ||
.scope-display div[secondary] { | ||
font-size: 14px; | ||
font-weight: 400; | ||
line-height: 20px; | ||
color: var(--oauth2-scope-selector-item-description-color, #737373); | ||
} | ||
</style> | ||
render() { | ||
const { | ||
name, | ||
invalid, | ||
currentValue, | ||
readOnly, | ||
legacy, | ||
outlined, | ||
_autocompleteScopes, | ||
_inputTarget, | ||
_invalidMessage | ||
} = this; | ||
return html ` | ||
<div class="container"> | ||
<label class="form-label">Scopes</label> | ||
<div class="input-container"> | ||
<paper-input name="[[name]]" no-label-float="" invalid="[[invalid]]" label="Scope value" | ||
class="scope-input" value="{{currentValue}}" on-keydown="_keyDown" autocomplete="off" | ||
title="Enter authorization scopes for this API endpoint."> | ||
<paper-icon-button class="add-button" data-action="add-scope" | ||
slot="suffix" icon="arc:add-circle-outline" | ||
on-click="_appendScope" title="Add scope"></paper-icon-button> | ||
</paper-input> | ||
<template is="dom-if" if="[[hasAutocomplete]]"> | ||
<paper-autocomplete target="[[inputTarget]]" source="[[_autocompleteScopes]]" | ||
on-selected="_suggestionSelected" open-on-focus=""></paper-autocomplete> | ||
</template> | ||
<anypoint-input | ||
name="${name}" | ||
?invalid="${invalid}" | ||
class="scope-input" | ||
.value="${currentValue}" | ||
?readOnly="${readOnly}" | ||
?outlined="${outlined}" | ||
?legacy="${legacy}" | ||
title="Enter authorization scopes for this API endpoint" | ||
.invalidMessage="${_invalidMessage}" | ||
@value-changed="${this._currentValueHandler}" | ||
@keydown="${this._keyDown}"> | ||
<label slot="label">Scope value</label> | ||
<anypoint-icon-button | ||
class="add-button" | ||
data-action="add-scope" | ||
slot="suffix" | ||
@click="${this._appendScope}" | ||
?disabled="${readOnly}" | ||
aria-label="Press to add current scope to the list" | ||
title="Add scope"> | ||
<iron-icon icon="arc:add-circle-outline"></iron-icon> | ||
</anypoint-icon-button> | ||
</anypoint-input> | ||
${_autocompleteScopes && _autocompleteScopes.length ? | ||
html`<anypoint-autocomplete | ||
.target="${_inputTarget}" | ||
.source="${_autocompleteScopes}" | ||
@selected="${this._suggestionSelected}" | ||
></anypoint-autocomplete>` : ''} | ||
</div> | ||
<section class="scopes-list" role="list"> | ||
<template is="dom-repeat" items="[[value]]"> | ||
<div class="scope-item" two-line\$="[[_allowedIsObject]]"> | ||
<div class="scope-display"> | ||
<div class="scope-item-label">[[item]]</div> | ||
<div secondary="">[[_computeItemDescription(item, _allowedIsObject)]]</div> | ||
</div> | ||
<paper-icon-button class="delete-icon" data-action="remove-scope" | ||
icon="arc:remove-circle-outline" on-click="_removeScope" title="Remove scope"></paper-icon-button> | ||
</div> | ||
</template> | ||
</section> | ||
<ul class="scopes-list"> | ||
${this._scopesListTemplate()} | ||
</ul> | ||
</div> | ||
<paper-toast missing-scope="" text="Enter scope value to add a scope."></paper-toast> | ||
<paper-toast dissalowed="" text="You can't enter this scope. Use one of the provided scopes."></paper-toast> | ||
<paper-toast missing-scope text="Enter scope value to add a scope."></paper-toast> | ||
<paper-toast dissalowed text="You can't enter this scope. Use one of the provided scopes."></paper-toast> | ||
`; | ||
} | ||
static get is() { | ||
return 'oauth2-scope-selector'; | ||
} | ||
static get properties() { | ||
@@ -248,13 +273,7 @@ return { | ||
*/ | ||
value: { | ||
type: Array, | ||
value: function() { | ||
return []; | ||
}, | ||
notify: true | ||
}, | ||
value: { type: Array }, | ||
/** | ||
* Form input name | ||
*/ | ||
name: String, | ||
name: { type: String }, | ||
/** | ||
@@ -265,8 +284,5 @@ * Current value entered by the user. This is not a scope and it is not | ||
*/ | ||
currentValue: String, | ||
// Target for `paper-autocomplete` | ||
inputTarget: { | ||
type: HTMLElement, | ||
readOnly: true | ||
}, | ||
currentValue: { type: String }, | ||
// Target for `anypoint-autocomplete` | ||
_inputTarget: { type: Object }, | ||
/** | ||
@@ -288,33 +304,17 @@ * List of available scopes. | ||
*/ | ||
allowedScopes: Array, | ||
allowedScopes: { type: Array }, | ||
// If true then scopes that are in the `allowedScopes` list will be | ||
// allowed to be add. | ||
preventCustomScopes: Boolean, | ||
preventCustomScopes: { type: Boolean }, | ||
// Computed value, true if the `allowedScopes` is a list of objects | ||
_allowedIsObject: { | ||
type: Boolean, | ||
value: false, | ||
computed: '_computeAllowedIsObject(allowedScopes)' | ||
}, | ||
_allowedIsObject: { type: Boolean }, | ||
/** | ||
* Set to true to auto-validate the input value when it changes. | ||
*/ | ||
autoValidate: Boolean, | ||
autoValidate: { type: Boolean }, | ||
/** | ||
* List of scopes to be set as autocomplete source. | ||
*/ | ||
_autocompleteScopes: { | ||
type: Array, | ||
computed: '_normalizeScopes(allowedScopes)' | ||
}, | ||
_autocompleteScopes: { type: Array }, | ||
/** | ||
* True if the element has attached autocomplete element. | ||
* | ||
* @type {Object} | ||
*/ | ||
hasAutocomplete: { | ||
type: Boolean, | ||
computed: '_computeHasAutocomplete(_autocompleteScopes)' | ||
}, | ||
/** | ||
* Returns true if the value is invalid. | ||
@@ -325,31 +325,97 @@ * | ||
*/ | ||
invalid: { | ||
type: Boolean, | ||
value: false, | ||
notify: true, | ||
reflectToAttribute: true, | ||
observer: '_invalidChanged' | ||
}, | ||
invalid: { type: Boolean, reflect: true }, | ||
/** | ||
* Set to true to mark the input as required. | ||
*/ | ||
required: { | ||
type: Boolean, | ||
value: false | ||
} | ||
required: { type: Boolean }, | ||
/** | ||
* When set the editor is in read only mode. | ||
*/ | ||
readOnly: { type: Boolean }, | ||
/** | ||
* Enables Anypoint legacy styling | ||
*/ | ||
legacy: { type: Boolean }, | ||
/** | ||
* Enables Material Design outlined style | ||
*/ | ||
outlined: { type: Boolean } | ||
}; | ||
} | ||
static get observers() { | ||
return [ | ||
'_handleAutoValidate(autoValidate, value.*)' | ||
]; | ||
get _invalidMessage() { | ||
let message; | ||
if (this.allowedScopes) { | ||
message = 'Entered value is not allowed'; | ||
} else if (this.required) { | ||
message = 'Scope value is required'; | ||
} | ||
return message; | ||
} | ||
ready() { | ||
super.ready(); | ||
this._ensureAttribute('tabindex', -1); | ||
this._setInputTarget(this.shadowRoot.querySelector('.scope-input')); | ||
get value() { | ||
return this._value; | ||
} | ||
set value(value) { | ||
const old = this._value; | ||
/* istanbul ignore if */ | ||
if (old === value) { | ||
return; | ||
} | ||
this._value = value; | ||
this.requestUpdate('value', old); | ||
this._handleAutoValidate(this.autoValidate, value); | ||
this.dispatchEvent(new CustomEvent('value-changed', { | ||
detail: { | ||
value | ||
} | ||
})); | ||
} | ||
get allowedScopes() { | ||
return this._allowedScopes; | ||
} | ||
set allowedScopes(value) { | ||
const old = this._allowedScopes; | ||
/* istanbul ignore if */ | ||
if (old === value) { | ||
return; | ||
} | ||
this._allowedScopes = value; | ||
this._allowedIsObject = this._computeAllowedIsObject(value); | ||
this._autocompleteScopes = this._normalizeScopes(value); | ||
} | ||
get invalid() { | ||
return this._invalid; | ||
} | ||
set invalid(value) { | ||
const old = this._invalid; | ||
/* istanbul ignore if */ | ||
if (old === value) { | ||
return; | ||
} | ||
this._invalid = value; | ||
this.requestUpdate('invalid', old); | ||
this._invalidChanged(value); | ||
this.dispatchEvent(new CustomEvent('invalid-changed', { | ||
detail: { | ||
value | ||
} | ||
})); | ||
} | ||
constructor() { | ||
super(); | ||
this.value = []; | ||
} | ||
firstUpdated() { | ||
this._inputTarget = this.shadowRoot.querySelector('.scope-input'); | ||
} | ||
_invalidChanged(invalid) { | ||
@@ -371,17 +437,11 @@ this.setAttribute('aria-invalid', invalid); | ||
_removeScope(e) { | ||
const repeater = this.shadowRoot | ||
.querySelector('.scopes-list > dom-repeat, template[is="dom-repeat"]'); | ||
const item = repeater.itemForElement(e.target); | ||
if (!item) { | ||
const index = Number(e.currentTarget.dataset.index); | ||
if (index !== index || !this.value) { | ||
return; | ||
} | ||
const all = this.value; | ||
const index = all.indexOf(item); | ||
if (index === -1) { | ||
return; | ||
} | ||
this.splice('value', index, 1); | ||
this.value.splice(index, 1); | ||
this.value = [...this.value]; | ||
} | ||
/** | ||
* Handler for the `paper-autocomplete` selected event. | ||
* Handler for the `anypoint-autocomplete` selected event. | ||
* | ||
@@ -397,3 +457,3 @@ * @param {Event} e | ||
this.currentValue = ''; | ||
}, 1); | ||
}); | ||
} | ||
@@ -408,3 +468,6 @@ /** | ||
const scopeValue = typeof scope === 'string' ? scope : scope.value; | ||
const all = this.value; | ||
if (!scopeValue) { | ||
return; | ||
} | ||
const all = this.value || []; | ||
let index = all.indexOf(scopeValue); | ||
@@ -414,6 +477,6 @@ if (index !== -1) { | ||
} | ||
if (this.preventCustomScopes && this.allowedScopes && | ||
this.allowedScopes.length) { | ||
const as = this.allowedScopes; | ||
if (as && as.length) { | ||
index = this._findAllowedScopeIndex(scopeValue); | ||
if (index === -1) { | ||
if (index === -1 && this.preventCustomScopes) { | ||
this.shadowRoot.querySelector('paper-toast[dissalowed]').opened = true; | ||
@@ -423,3 +486,4 @@ return; | ||
} | ||
this.push('value', scopeValue); | ||
all.push(scopeValue); | ||
this.value = [...all]; | ||
} | ||
@@ -447,6 +511,6 @@ /** | ||
_keyDown(e) { | ||
if (e.keyCode !== 13) { | ||
if (e.key !== 'Enter') { | ||
return; | ||
} | ||
const ac = this.shadowRoot.querySelector('paper-autocomplete'); | ||
const ac = this.shadowRoot.querySelector('anypoint-autocomplete'); | ||
if (ac && ac.opened) { | ||
@@ -480,11 +544,2 @@ return; | ||
/** | ||
* Computes value for `hasAutocomplete`. | ||
* | ||
* @param {?Array} scopes List of scopes | ||
* @return {Boolean} True if scopes are set | ||
*/ | ||
_computeHasAutocomplete(scopes) { | ||
return !!(scopes && scopes.length); | ||
} | ||
/** | ||
* Compute function for the _allowedIsObject. Check first item of the | ||
@@ -521,3 +576,2 @@ * `allowedScopes` array if it is an object (return `true`) or | ||
} | ||
/** | ||
@@ -531,4 +585,21 @@ * Returns false if the element is required and does not have a selection, | ||
_getValidity() { | ||
return this.disabled || !this.required || (this.required && | ||
!!(this.value && this.value.length)); | ||
const { | ||
value, | ||
disabled, | ||
required, | ||
allowedScopes | ||
} = this; | ||
const hasValue = !!(value && value.length); | ||
const valid = disabled || !required || (required && hasValue); | ||
if (!valid || !hasValue || !allowedScopes) { | ||
return valid; | ||
} | ||
for (let i = 0, len = value.length; i < len; i++) { | ||
const scope = value[i]; | ||
const index = this._findAllowedScopeIndex(scope); | ||
if (index === -1) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
@@ -541,3 +612,7 @@ | ||
} | ||
_currentValueHandler(e) { | ||
this.currentValue = e.detail.value; | ||
} | ||
} | ||
window.customElements.define(OAuth2ScopeSelector.is, OAuth2ScopeSelector); | ||
window.customElements.define('oauth2-scope-selector', OAuth2ScopeSelector); |
101
package.json
{ | ||
"name": "@advanced-rest-client/oauth2-scope-selector", | ||
"description": "A selector for the OAuth scope. It provides an UI to enter a scope for the AOuth settings", | ||
"version": "3.0.0", | ||
"license": "Apache-2.0", | ||
"main": "oauth2-scope-selector.js", | ||
"keywords": [ | ||
"web-components", | ||
"polymer", | ||
"oauth2", | ||
"scope" | ||
], | ||
"authors": [ | ||
"Pawel Psztyc" | ||
], | ||
"contributors": [ | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"repository": { | ||
@@ -13,29 +22,2 @@ "type": "git", | ||
}, | ||
"name": "@advanced-rest-client/oauth2-scope-selector", | ||
"license": "Apache-2.0", | ||
"version": "3.0.0-preview.3", | ||
"authors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"devDependencies": { | ||
"@polymer/gen-typescript-declarations": "^1.6.1", | ||
"@polymer/iron-demo-helpers": "^3.0.0", | ||
"@webcomponents/webcomponentsjs": "^2.0.0", | ||
"@polymer/iron-component-page": "^4.0.0", | ||
"@polymer/iron-form": "^3.0.0", | ||
"@polymer/iron-test-helpers": "^3.0.0", | ||
"@polymer/test-fixture": "^4.0.2", | ||
"chai": "^4.2.0", | ||
"mocha": "^5.2.0", | ||
"sinon": "^7.2.3", | ||
"wct-mocha": "^1.0.0" | ||
}, | ||
"main": "oauth2-scope-selector.js", | ||
"scripts": { | ||
"lint": "polymer lint oauth2-scope-selector.html", | ||
"test-sauce": "polymer test --plugin sauce --job-name \"oauth2-scope-selector:local-test\"", | ||
"test": "polymer test --plugin local --job-name \"oauth2-scope-selector:local-test\"", | ||
"update-types": "gen-typescript-declarations --deleteExisting --outDir ." | ||
}, | ||
"bugs": { | ||
@@ -45,17 +27,56 @@ "url": "https://github.com/advanced-rest-client/oauth2-scope-selector/issues", | ||
}, | ||
"contributors": [ | ||
"Pawel Psztyc", | ||
"The Advanced REST client authors <arc@mulesoft.com>" | ||
], | ||
"dependencies": { | ||
"@advanced-rest-client/arc-icons": "^3.0.0-preview.1", | ||
"@advanced-rest-client/paper-autocomplete": "^3.0.0-preview.2", | ||
"@polymer/iron-behaviors": "^3.0.0", | ||
"@polymer/iron-flex-layout": "^3.0.0", | ||
"@polymer/iron-validatable-behavior": "^3.0.0", | ||
"@polymer/paper-icon-button": "^3.0.0", | ||
"@polymer/paper-input": "^3.0.0", | ||
"@advanced-rest-client/arc-icons": "^3.0.0", | ||
"@anypoint-web-components/anypoint-autocomplete": "^0.1.1", | ||
"@anypoint-web-components/anypoint-button": "^1.0.4", | ||
"@anypoint-web-components/anypoint-control-mixins": "^1.0.1", | ||
"@anypoint-web-components/anypoint-input": "^0.1.5", | ||
"@anypoint-web-components/validatable-mixin": "^1.0.1", | ||
"@polymer/iron-icon": "^3.0.1", | ||
"@polymer/paper-toast": "^3.0.0", | ||
"@polymer/polymer": "^3.0.0" | ||
"lit-element": "^2.0.1", | ||
"lit-html": "^1.1.2" | ||
}, | ||
"devDependencies": { | ||
"@advanced-rest-client/arc-demo-helper": "^1.0.14", | ||
"@advanced-rest-client/eslint-config": "^1.0.6", | ||
"@advanced-rest-client/prettier-config": "^0.1.0", | ||
"@advanced-rest-client/testing-karma-sl": "^1.0.3", | ||
"@anypoint-web-components/anypoint-checkbox": "^1.0.1", | ||
"@commitlint/cli": "^8.1.0", | ||
"@commitlint/config-conventional": "^7.0.0", | ||
"@open-wc/testing": "^2.2.8", | ||
"@open-wc/testing-karma": "^3.1.18", | ||
"@polymer/gen-typescript-declarations": "^1.6.2", | ||
"@polymer/iron-test-helpers": "^3.0.0", | ||
"deepmerge": "^4.0.0", | ||
"es-dev-server": "^1.12.0", | ||
"husky": "^1.0.0", | ||
"karma": "^4.2.0", | ||
"lint-staged": "^9.2.1", | ||
"sinon": "^7.4.1" | ||
}, | ||
"scripts": { | ||
"test": "karma start --coverage", | ||
"update-types": "gen-typescript-declarations --deleteExisting --outDir .", | ||
"start": "es-dev-server --app-index demo/index.html --node-resolve --open --watch", | ||
"start:compatibility": "es-dev-server --app-index demo/index.html --compatibility all --node-resolve --open --watch", | ||
"lint:eslint": "eslint --ext .js,.html .", | ||
"format:eslint": "eslint --ext .js,.html . --fix", | ||
"lint:prettier": "prettier \"**/*.js\" --list-different || (echo '↑↑ these files are not prettier formatted ↑↑' && exit 1)", | ||
"format:prettier": "prettier \"**/*.js\" --write", | ||
"lint": "npm run lint:eslint && npm run lint:prettier", | ||
"format": "npm run format:eslint && npm run format:prettier", | ||
"test:watch": "karma start --auto-watch=true --single-run=false", | ||
"test:legacy": "karma start --legacy --coverage", | ||
"test:legacy:watch": "karma start --legacy --auto-watch=true --single-run=false", | ||
"test:sl": "karma start karma.sl.config.js --legacy --coverage", | ||
"generate-model": "node demo/model.js" | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"eslint --fix", | ||
"git add" | ||
] | ||
} | ||
} |
@@ -5,4 +5,2 @@ [![Published on NPM](https://img.shields.io/npm/v/@advanced-rest-client/oauth2-scope-selector.svg)](https://www.npmjs.com/package/@advanced-rest-client/oauth2-scope-selector) | ||
[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/advanced-rest-client/oauth2-scope-selector) | ||
## <oauth2-scope-selector> | ||
@@ -13,9 +11,5 @@ | ||
```html | ||
<oauth2-scope-selector name="scope" allowed-scopes='["email", "profile"]'></oauth2-scope-selector> | ||
<oauth2-scope-selector name="scope" allowedscopes='["email", "profile"]'></oauth2-scope-selector> | ||
``` | ||
### API components | ||
This components is a part of [API components ecosystem](https://elements.advancedrestclient.com/) | ||
## Usage | ||
@@ -43,25 +37,8 @@ | ||
### In a Polymer 3 element | ||
### Deveopment | ||
```js | ||
import {PolymerElement, html} from '@polymer/polymer'; | ||
import '@advanced-rest-client/oauth2-scope-selector/oauth2-scope-selector.js'; | ||
class SampleElement extends PolymerElement { | ||
static get template() { | ||
return html` | ||
<oauth2-scope-selector></oauth2-scope-selector> | ||
`; | ||
} | ||
} | ||
customElements.define('sample-element', SampleElement); | ||
``` | ||
### Installation | ||
```sh | ||
git clone https://github.com/advanced-rest-client/oauth2-scope-selector | ||
cd api-url-editor | ||
cd oauth2-scope-selector | ||
npm install | ||
npm install -g polymer-cli | ||
``` | ||
@@ -72,4 +49,3 @@ | ||
```sh | ||
polymer serve --npm | ||
open http://127.0.0.1:<port>/demo/ | ||
npm start | ||
``` | ||
@@ -79,3 +55,7 @@ | ||
```sh | ||
polymer test --npm | ||
npm test | ||
``` | ||
### API components | ||
This components is a part of [API components ecosystem](https://elements.advancedrestclient.com/) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
791
1
57553
10
17
1
57
+ Added@anypoint-web-components/anypoint-autocomplete@^0.1.1
+ Added@anypoint-web-components/anypoint-control-mixins@^1.0.1
+ Added@polymer/iron-icon@^3.0.1
+ Addedlit-element@^2.0.1
+ Addedlit-html@^1.1.2
+ Added@anypoint-web-components/anypoint-autocomplete@0.1.5(transitive)
+ Added@anypoint-web-components/anypoint-button@1.2.4(transitive)
+ Added@anypoint-web-components/anypoint-control-mixins@1.2.0(transitive)
+ Added@anypoint-web-components/anypoint-dropdown@1.1.7(transitive)
+ Added@anypoint-web-components/anypoint-input@0.1.7(transitive)
+ Added@anypoint-web-components/anypoint-item@1.1.3(transitive)
+ Added@anypoint-web-components/anypoint-listbox@1.1.7(transitive)
+ Added@anypoint-web-components/anypoint-menu-mixin@1.1.9(transitive)
+ Added@anypoint-web-components/anypoint-selector@1.1.8(transitive)
+ Added@anypoint-web-components/anypoint-styles@1.0.4(transitive)
+ Added@anypoint-web-components/material-ripple@1.0.3(transitive)
+ Added@anypoint-web-components/validatable-mixin@1.1.3(transitive)
+ Added@anypoint-web-components/validator-mixin@1.1.2(transitive)
- Removed@advanced-rest-client/paper-autocomplete@^3.0.0-preview.2
- Removed@polymer/iron-behaviors@^3.0.0
- Removed@polymer/iron-flex-layout@^3.0.0
- Removed@polymer/paper-icon-button@^3.0.0
- Removed@polymer/paper-input@^3.0.0
- Removed@polymer/polymer@^3.0.0
- Removed@advanced-rest-client/arc-scroll-target-mixin@1.1.3(transitive)
- Removed@advanced-rest-client/paper-autocomplete@3.1.1(transitive)
- Removed@polymer/iron-a11y-keys@3.0.1(transitive)
- Removed@polymer/iron-autogrow-textarea@3.0.3(transitive)
- Removed@polymer/iron-behaviors@3.0.1(transitive)
- Removed@polymer/iron-checked-element-behavior@3.0.1(transitive)
- Removed@polymer/iron-form-element-behavior@3.0.1(transitive)
- Removed@polymer/iron-input@3.0.1(transitive)
- Removed@polymer/iron-selector@3.0.1(transitive)
- Removed@polymer/iron-validatable-behavior@3.0.1(transitive)
- Removed@polymer/paper-behaviors@3.0.1(transitive)
- Removed@polymer/paper-icon-button@3.0.2(transitive)
- Removed@polymer/paper-input@3.2.1(transitive)
- Removed@polymer/paper-item@3.0.1(transitive)