@neovici/cosmoz-input
Advanced tools
Comparing version 1.3.0 to 1.4.0
@@ -1,189 +0,30 @@ | ||
import { html, nothing } from 'lit-html'; // eslint-disable-line object-curly-newline | ||
import { html } from 'lit-html'; // eslint-disable-line object-curly-newline | ||
import { live } from 'lit-html/directives/live'; | ||
import { ifDefined } from 'lit-html/directives/if-defined'; | ||
import { useImperativeApi } from '@neovici/cosmoz-utils/lib/hooks/use-imperative-api'; | ||
import { notifyProperty } from '@neovici/cosmoz-utils/lib/hooks/use-notify-property'; | ||
import { | ||
component, useCallback, useEffect, useMemo | ||
} from 'haunted'; | ||
import { component } from 'haunted'; | ||
import { useInput, useAllowedPattern } from './use-input'; | ||
import { render, attributes } from './render'; | ||
const styles = ` | ||
:host { | ||
display: block; | ||
padding: 8px 0; | ||
padding-top: var(--paper-input-container_-_padding-top, 8px); | ||
} | ||
:host, label, input { | ||
font-family: var(--cosmoz-subhead-font-family, var(--paper-font-subhead_-_font-family, 'Roboto', 'Noto', sans-serif)); | ||
font-size: var(--cosmoz-subhead-font-size, var(--paper-font-subhead_-_font-size, 16px)); | ||
line-height: var(--cosmoz-subhead-line-height, var(--paper-font-subhead_-_line-height, 24px)); | ||
display: block; | ||
} | ||
:host([disabled]) { | ||
opacity: var(--cosmoz-input-disabled-opacity, var(--paper-input-container-disabled_-_opacity, 0.33)); | ||
pointer-events: none; | ||
} | ||
.wrap { | ||
display: flex; | ||
align-items: center; | ||
position: relative; | ||
} | ||
.control { | ||
flex: 1; | ||
position: relative; | ||
} | ||
input { | ||
padding: 0; | ||
margin: 0; | ||
outline: none; | ||
border: none; | ||
width: 100%; | ||
max-width: 100%; | ||
background: var(--cosmoz-input-background, initial); | ||
} | ||
:host(:focus-within) input { | ||
background: var(--cosmoz-input-focused-background, var(--cosmoz-input-background, initial)); | ||
} | ||
label { | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
transition: transform 0.25s, width 0.25s; | ||
transform-origin: left top; | ||
color: var(--secondary-text-color, #737373); | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
} | ||
:host([always-float-label]) label, | ||
input:not(:placeholder-shown) + label { | ||
transform: translateY(-75%) scale(0.75); | ||
} | ||
input:not(:placeholder-shown):focus + label { | ||
color: var(--primary-color, #3f51b5); | ||
} | ||
.line { | ||
border-bottom: 2px solid var(--secondary-text-color, #737373); | ||
} | ||
:host(:focus-within) .line { | ||
border-bottom-color: var(--primary-color, #3f51b5); | ||
} | ||
:host([disabled]) .line { | ||
border-bottom-style: dashed; | ||
opacity: var(--cosmoz-input-disabled-line-opacity, var(--paper-input-container-underline-disabled_-_opacity, 1)); | ||
} | ||
:host([no-label-float]) .float, | ||
:host([no-label-float]) input:not(:placeholder-shown) + label { | ||
display: none; | ||
} | ||
.error { | ||
font-size: 12px; | ||
line-height: 20px; | ||
overflow: hidden; | ||
text-overflow: clip; | ||
position: absolute; | ||
max-width: 100%; | ||
} | ||
:host([invalid]) label, .error { | ||
color: var(--paper-input-container-invalid-color, var(--error-color, #fc5c5b)); | ||
} | ||
:host([invalid]) .line { | ||
border-bottom-color: var(--paper-input-container-invalid-color, var(--error-color, #fc5c5b)); | ||
} | ||
`, | ||
Input = host => { | ||
export const Input = host => { | ||
const { | ||
type = 'text', | ||
autocomplete, | ||
pattern, | ||
allowedPattern, | ||
autocomplete, | ||
value, | ||
label, | ||
placeholder, | ||
readonly, | ||
disabled, | ||
invalid, | ||
errorMessage | ||
disabled | ||
} = host, | ||
root = host.shadowRoot, | ||
onChange = useCallback(e => host.dispatchEvent(new Event(e.type, { bubbles: e.bubbles })), []), | ||
onInput = useCallback(e => notifyProperty(host, 'value', e.target.value), []), | ||
onBeforeInput = useMemo(() => { | ||
if (allowedPattern == null) { | ||
return; | ||
} | ||
const regexp = new RegExp(allowedPattern, 'u'); | ||
return e => { | ||
if (!e.defaultPrevent && e.data && !regexp.test(e.data)) { | ||
e.preventDefault(); | ||
} | ||
}; | ||
}, [allowedPattern]), | ||
onFocus = useCallback(e => notifyProperty(host, 'focused', e.type === 'focus'), []), | ||
focus = useCallback(() => root.querySelector('input')?.focus(), []), | ||
validate = useCallback(() => { | ||
const valid = root.querySelector('input')?.checkValidity(); | ||
host.toggleAttribute('invalid', !valid); | ||
return valid; | ||
}, []); | ||
useImperativeApi({ | ||
focus, | ||
validate | ||
}, [focus, validate]); | ||
useEffect(() => { | ||
const onMouseDown = e => { | ||
if (e.target.matches('input, label')) { | ||
return; | ||
} | ||
e.preventDefault(); // don't blur | ||
if (!host.matches(':focus-within')) { // if input not focused | ||
focus(); // focus input | ||
} | ||
}; | ||
root.addEventListener('mousedown', onMouseDown); | ||
return () => { | ||
root.removeEventListener('mousedown', onMouseDown); | ||
}; | ||
}, [focus]); | ||
return html` | ||
<style>${ styles }</style> | ||
<div class="float" part="float"> </div> | ||
<div class="wrap" part="wrap"> | ||
<slot name="prefix"></slot> | ||
<div class="control" part="control"> | ||
<input id="input" part="input" | ||
type=${ type } placeholder=${ placeholder || ' ' } pattern=${ ifDefined(pattern) } | ||
?readonly=${ readonly } ?aria-disabled=${ disabled } ?disabled=${ disabled } | ||
.value=${ live(value ?? '') } autocomplete=${ ifDefined(autocomplete) } | ||
@beforeinput=${ onBeforeInput } @input=${ onInput } | ||
@change=${ onChange } @focus=${ onFocus } @blur=${ onFocus } | ||
> | ||
${ label ? html`<label for="input" part="label">${ label }</label>` : nothing } | ||
</div> | ||
<slot name="suffix"></slot> | ||
</div> | ||
<div class="line" part="line"></div> | ||
${ invalid && errorMessage ? html`<div class="error" part="error">${ errorMessage }</div>` : nothing } | ||
`; | ||
{ onChange, onFocus, onInput } = useInput(host), | ||
onBeforeInput = useAllowedPattern(allowedPattern); | ||
return render(html`<input id="input" part="input" | ||
type=${ type } pattern=${ ifDefined(pattern) } | ||
autocomplete=${ ifDefined(autocomplete) } placeholder=${ placeholder || ' ' } | ||
?readonly=${ readonly } ?aria-disabled=${ disabled } ?disabled=${ disabled } | ||
.value=${ live(value ?? '') } | ||
@beforeinput=${ onBeforeInput } @input=${ onInput } | ||
@change=${ onChange } @focus=${ onFocus } @blur=${ onFocus }>` | ||
, host); | ||
}, | ||
@@ -193,20 +34,7 @@ | ||
'type', | ||
'autocomplete', | ||
'pattern', | ||
'allowed-pattern', | ||
'readonly', | ||
'disabled', | ||
'invalid', | ||
'no-label-float', | ||
'always-float-label' | ||
...attributes | ||
]; | ||
customElements.define( | ||
'cosmoz-input', | ||
component(Input, { observedAttributes }) | ||
); | ||
export { | ||
Input, | ||
observedAttributes | ||
}; | ||
customElements.define('cosmoz-input', component(Input, { observedAttributes })); |
{ | ||
"name": "@neovici/cosmoz-input", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "A input web component", | ||
@@ -27,7 +27,5 @@ "keywords": [ | ||
"start": "npm run storybook", | ||
"test": "karma start --coverage", | ||
"test:watch": "karma start --auto-watch=true --single-run=false", | ||
"test:update-snapshots": "karma start --update-snapshots", | ||
"test:prune-snapshots": "karma start --prune-snapshots", | ||
"test:compatibility": "karma start --compatibility all --auto-watch=true --single-run=false", | ||
"test": "wtr --coverage", | ||
"test:watch": "wtr --watch", | ||
"prepare": "husky install", | ||
"storybook": "start-storybook --node-resolve --watch --open", | ||
@@ -61,34 +59,24 @@ "storybook:build": "build-storybook", | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS" | ||
} | ||
}, | ||
"dependencies": { | ||
"@neovici/cosmoz-utils": "^3.15.0", | ||
"haunted": "^4.7.0", | ||
"lit-html": "^1.2.1" | ||
"@neovici/cosmoz-utils": "^3.19.0", | ||
"haunted": "^4.8.0", | ||
"lit-html": "^1.4.1" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^11.0.0", | ||
"@commitlint/config-conventional": "^11.0.0", | ||
"@commitlint/cli": "^12.0.0", | ||
"@commitlint/config-conventional": "^12.0.0", | ||
"@neovici/eslint-config": "^1.2.0", | ||
"@open-wc/demoing-storybook": "^2.1.0", | ||
"@open-wc/testing": "^2.5.0", | ||
"@open-wc/testing-karma": "^3.3.10", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@storybook/storybook-deployer": "^2.8.5", | ||
"@webcomponents/webcomponentsjs": "^2.4.0", | ||
"chai": "^4.2.0", | ||
"deepmerge": "^4.2.0", | ||
"@web/test-runner": "^0.13.0", | ||
"@web/test-runner-selenium": "^0.5.0", | ||
"eslint": "^7.0.0", | ||
"husky": "^4.2.0", | ||
"karma": "^5.0.0", | ||
"karma-firefox-launcher": "^2.1.0", | ||
"karma-sauce-launcher": "^4.3.0", | ||
"semantic-release": "^17.0.0", | ||
"sinon": "^9.0.0", | ||
"typescript": "^4.0.0" | ||
"husky": "^6.0.0", | ||
"semantic-release": "^17.4.0", | ||
"sinon": "^11.0.0", | ||
"typescript": "^4.3.0" | ||
} | ||
} |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
15
8
0
11428
255
1
Updatedhaunted@^4.8.0
Updatedlit-html@^1.4.1