@stories-js/core
Version:
Stories web components to build stories
249 lines (244 loc) • 11.7 kB
JavaScript
/*!
* (C) StoriesJS https://storiesjs.org - GPL-2.0 License
*/
import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
import { d as debounceEvent, i as inheritAttributes, f as findItemLabel } from './helpers.js';
import { c as createColorClasses } from './utils.js';
const inputCss = ":host{--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:.5;--padding-top:0;--padding-end:0;--padding-bottom:0;--padding-start:0;--background:transparent;--color:initial;display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-align:center;align-items:center;width:100%;padding:0 !important;background:var(--background);color:var(--color);font-family:var(--stories-font-family, inherit);z-index:2}:host-context(stories-item:not(.item-label)){--padding-start:0}:host(.stories-color){color:var(--stories-color-base)}.native-input{border-radius:var(--border-radius);padding-left:var(--padding-start);padding-right:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:inline-block;-ms-flex:1;flex:1;width:100%;max-width:100%;max-height:100%;border:0;outline:none;background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}@supports ((-webkit-margin-start: 0) or (margin-inline-start: 0)) or (-webkit-margin-start: 0){.native-input{padding-left:unset;padding-right:unset;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end)}}.native-input::-webkit-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input::-moz-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input:-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input::-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input::placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input:-webkit-autofill{background-color:transparent}.native-input:invalid{-webkit-box-shadow:none;box-shadow:none}.native-input::-ms-clear{display:none}.native-input[disabled]{opacity:0.4}.cloned-input{left:0;top:0;position:absolute;pointer-events:none}[dir=rtl] .cloned-input,:host-context([dir=rtl]) .cloned-input{left:unset;right:unset;right:0}.input-clear-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;background-position:center;border:0;outline:none;background-color:transparent;background-repeat:no-repeat;visibility:hidden;-webkit-appearance:none;-moz-appearance:none;appearance:none}.input-clear-icon:focus{opacity:0.5}:host(.has-value) .input-clear-icon{visibility:visible}:host(.has-focus){pointer-events:none}:host(.has-focus) input,:host(.has-focus) a,:host(.has-focus) button{pointer-events:auto}:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value)){opacity:0}:host-context(.item-label-floating.item-has-placeholder:not(.item-has-value).item-has-focus){-webkit-transition:opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 0.15s cubic-bezier(0.4, 0, 0.2, 1);opacity:1}";
let inputIds = 0;
const Input = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.storiesInput = createEvent(this, "storiesInput", 7);
this.storiesChange = createEvent(this, "storiesChange", 7);
this.storiesBlur = createEvent(this, "storiesBlur", 7);
this.storiesFocus = createEvent(this, "storiesFocus", 7);
this.storiesStyle = createEvent(this, "storiesStyle", 7);
this.inputId = `stories-input-${inputIds++}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.inheritedAttributes = {};
/**
* This is required for a WebKit bug which requires us to
* blur and focus an input to properly focus the input in
* an item with delegatesFocus. It will no longer be needed
* with iOS 14.
*
* @internal
*/
this.fireFocusEvents = true;
this.hasFocus = false;
/**
* This Boolean attribute lets you specify that a form control should have input focus when the page loads.
*/
this.autofocus = false;
/**
* If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
*/
this.clearInput = false;
/**
* Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. This also impacts form bindings such as `ngModel` or `v-model`.
*/
this.debounce = 0;
/**
* If `true`, the user cannot interact with the input.
*/
this.disabled = false;
/**
* The name of the control, which is submitted with the form data.
*/
this.name = this.inputId;
/**
* If `true`, the user cannot modify the value.
*/
this.readonly = false;
/**
* If `true`, the user must fill in a value before submitting a form.
*/
this.required = false;
/**
* The type of control to display. The default type is text.
*/
this.type = 'text';
/**
* The value of the input.
*/
this.value = '';
this.onInput = (ev) => {
const input = ev.target;
if (input) {
this.value = input.value || '';
}
this.storiesInput.emit(ev);
};
this.onBlur = (ev) => {
this.hasFocus = false;
this.emitStyle();
if (this.fireFocusEvents) {
this.storiesBlur.emit(ev);
}
};
this.onFocus = (ev) => {
this.hasFocus = true;
this.emitStyle();
if (this.fireFocusEvents) {
this.storiesFocus.emit(ev);
}
};
this.clearTextOnEnter = (ev) => {
if (ev.key === 'Enter') {
this.clearTextInput(ev);
}
};
this.clearTextInput = (ev) => {
if (this.clearInput && !this.readonly && !this.disabled && ev) {
ev.preventDefault();
ev.stopPropagation();
// Attempt to focus input again after pressing clear button
this.setFocus();
}
this.value = '';
/**
* This is needed for clearOnEdit
* Otherwise the value will not be cleared
* if user is inside the input
*/
if (this.nativeInput) {
this.nativeInput.value = '';
}
};
}
debounceChanged() {
this.storiesChange = debounceEvent(this.storiesChange, this.debounce);
}
disabledChanged() {
this.emitStyle();
}
/**
* Update the item classes when the placeholder changes
*/
placeholderChanged() {
this.emitStyle();
}
/**
* Update the native input element when the value changes
*/
valueChanged() {
this.emitStyle();
this.storiesChange.emit({ value: this.value === null ? this.value : this.value.toString() });
}
componentWillLoad() {
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label', 'tabindex', 'title']);
}
connectedCallback() {
this.emitStyle();
this.debounceChanged();
}
/**
* Sets focus on the native `input` in `stories-input`. Use this method instead of the global
* `input.focus()`.
*/
async setFocus() {
if (this.nativeInput) {
this.nativeInput.focus();
}
}
/**
* Sets blur on the native `input` in `stories-input`. Use this method instead of the global
* `input.blur()`.
* @internal
*/
async setBlur() {
if (this.nativeInput) {
this.nativeInput.blur();
}
}
/**
* Returns the native `<input>` element used under the hood.
*/
getInputElement() {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return Promise.resolve(this.nativeInput);
}
getValue() {
return typeof this.value === 'number' ? this.value.toString() :
(this.value || '').toString();
}
emitStyle() {
this.storiesStyle.emit({
'interactive': true,
'input': true,
'has-placeholder': this.placeholder !== undefined,
'has-value': this.hasValue(),
'has-focus': this.hasFocus,
'interactive-disabled': this.disabled,
});
}
hasValue() {
return this.getValue().length > 0;
}
render() {
const value = this.getValue();
const labelId = this.inputId + '-lbl';
const label = findItemLabel(this.el);
if (label) {
label.id = labelId;
}
return (h(Host, { "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses(this.color, {
'has-value': this.hasValue(),
'has-focus': this.hasFocus
}) }, h("input", Object.assign({ ref: input => this.nativeInput = input, "aria-labelledby": label ? labelId : null, autoFocus: this.autofocus, class: "native-input", disabled: this.disabled, inputMode: this.inputmode, max: this.max, maxLength: this.maxlength, min: this.min, minLength: this.minlength, name: this.name, onBlur: this.onBlur, onFocus: this.onFocus, onInput: this.onInput, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, size: this.size, step: this.step, type: this.type, value: value }, this.inheritedAttributes)), (this.clearInput && !this.readonly && !this.disabled) && h("button", { "aria-label": "reset", class: "input-clear-icon", onKeyDown: this.clearTextOnEnter, onMouseDown: this.clearTextInput, onTouchStart: this.clearTextInput, type: "button" })));
}
get el() { return this; }
static get watchers() { return {
"debounce": ["debounceChanged"],
"disabled": ["disabledChanged"],
"placeholder": ["placeholderChanged"],
"value": ["valueChanged"]
}; }
static get style() { return inputCss; }
}, [1, "stories-input", {
"fireFocusEvents": [4, "fire-focus-events"],
"color": [513],
"autofocus": [4],
"clearInput": [4, "clear-input"],
"debounce": [2],
"disabled": [4],
"inputmode": [1],
"max": [1],
"maxlength": [2],
"min": [1],
"minlength": [2],
"name": [1],
"pattern": [1],
"placeholder": [1],
"readonly": [4],
"required": [4],
"step": [1],
"size": [2],
"type": [1],
"value": [1032],
"hasFocus": [32],
"setFocus": [64],
"setBlur": [64],
"getInputElement": [64]
}]);
function defineCustomElement$1() {
if (typeof customElements === "undefined") {
return;
}
const components = ["stories-input"];
components.forEach(tagName => { switch (tagName) {
case "stories-input":
if (!customElements.get(tagName)) {
customElements.define(tagName, Input);
}
break;
} });
}
defineCustomElement$1();
const StoriesInput = Input;
const defineCustomElement = defineCustomElement$1;
export { StoriesInput, defineCustomElement };
//# sourceMappingURL=stories-input.js.map