@neovici/cosmoz-autocomplete
Advanced tools
Comparing version 8.0.0 to 8.1.0
import '@neovici/cosmoz-input'; | ||
import { Props as Base, RProps } from './use-autocomplete'; | ||
import style from './styles.css'; | ||
export interface Props<I> extends Base<I> { | ||
@@ -18,2 +19,2 @@ invalid?: boolean; | ||
declare const autocomplete: <I>(props: AProps<I>) => import("lit-html").TemplateResult<1>, Autocomplete: <I>(props: Props<I>) => import("lit-html").TemplateResult<1>, observedAttributes: string[]; | ||
export { autocomplete, Autocomplete, observedAttributes }; | ||
export { autocomplete, Autocomplete, observedAttributes, style }; |
@@ -19,3 +19,3 @@ import { html, nothing } from 'lit-html'; // eslint-disable-line object-curly-newline | ||
const autocomplete = (props) => { | ||
const { invalid, errorMessage, label, placeholder, disabled, noLabelFloat, alwaysFloatLabel, textual, text, onText, onFocus, onClick, onDeselect, value, limit, showSingle, items$, values$, } = props, host = useHost(), isOne = limit == 1, // eslint-disable-line eqeqeq | ||
const { invalid, errorMessage, label, placeholder, disabled, noLabelFloat, alwaysFloatLabel, textual, text, onText, onFocus, onClick, onDeselect, value, limit, min, showSingle, items$, values$, } = props, host = useHost(), isOne = limit == 1, // eslint-disable-line eqeqeq | ||
isSingle = isOne && value?.[0] != null, | ||
@@ -32,5 +32,3 @@ // TODO: Refactor with ref or a state callback | ||
}, []); | ||
return html ` <style> | ||
${style} | ||
</style> | ||
return html ` | ||
<cosmoz-input | ||
@@ -61,2 +59,3 @@ id="input" | ||
value, | ||
min, | ||
isOne, | ||
@@ -86,3 +85,5 @@ onDeselect, | ||
'limit', | ||
'min', | ||
'show-single', | ||
'preserve-order', | ||
'keep-opened', | ||
@@ -96,2 +97,2 @@ 'keep-query', | ||
]; | ||
export { autocomplete, Autocomplete, observedAttributes }; | ||
export { autocomplete, Autocomplete, observedAttributes, style }; |
@@ -15,2 +15,3 @@ import { tagged as css } from '@neovici/cosmoz-utils'; | ||
gap: 4px; | ||
cursor: pointer; | ||
} | ||
@@ -17,0 +18,0 @@ .content { |
interface Props { | ||
onClear?: () => void; | ||
onClear?: false | (() => void); | ||
disabled?: boolean; | ||
@@ -4,0 +4,0 @@ } |
@@ -1,4 +0,5 @@ | ||
import { html, component } from '@pionjs/pion'; | ||
import { sheet } from '@neovici/cosmoz-utils'; | ||
import { component, html } from '@pionjs/pion'; | ||
import { ifDefined } from 'lit-html/directives/if-defined.js'; | ||
import { when } from 'lit-html/directives/when.js'; | ||
import { ifDefined } from 'lit-html/directives/if-defined.js'; | ||
import styles from './chip.css'; | ||
@@ -30,11 +31,11 @@ const clear = html ` | ||
export const Chip = ({ onClear, disabled }) => html ` | ||
<style> | ||
${styles} | ||
</style> | ||
<div class="content" part="content chip-text"><slot></slot></div> | ||
${when(!disabled, () => html ` <span class="clear" part="clear chip-clear" @click=${onClear}> | ||
${when(onClear && !disabled, () => html ` <span class="clear" part="clear chip-clear" @click=${onClear}> | ||
${clear} | ||
</span>`)} | ||
`; | ||
customElements.define('cosmoz-autocomplete-chip', component(Chip, { observedAttributes: ['disabled'] })); | ||
customElements.define('cosmoz-autocomplete-chip', component(Chip, { | ||
observedAttributes: ['disabled'], | ||
styleSheets: [sheet(styles)], | ||
})); | ||
export const chip = ({ content, onClear, disabled, hidden, className = 'chip', slot, }) => html `<cosmoz-autocomplete-chip | ||
@@ -41,0 +42,0 @@ class=${ifDefined(className)} |
import { component, useCallback } from '@pionjs/pion'; | ||
import { Autocomplete, observedAttributes as atts, } from './autocomplete'; | ||
import { Autocomplete, observedAttributes as atts, style, } from './autocomplete'; | ||
import { sheet } from '@neovici/cosmoz-utils'; | ||
const Standalone = (host) => { | ||
@@ -17,4 +18,4 @@ const { onChange, onText, ...props } = host; | ||
}; | ||
const observedAttributes = atts; | ||
customElements.define('cosmoz-autocomplete-ui', component(Autocomplete, { observedAttributes })); | ||
customElements.define('cosmoz-autocomplete', component(Standalone, { observedAttributes })); | ||
const observedAttributes = atts, styleSheets = [sheet(style)]; | ||
customElements.define('cosmoz-autocomplete-ui', component(Autocomplete, { observedAttributes, styleSheets })); | ||
customElements.define('cosmoz-autocomplete', component(Standalone, { observedAttributes, styleSheets })); |
@@ -5,2 +5,3 @@ import type { RProps } from './use-autocomplete'; | ||
value: I[]; | ||
min?: number; | ||
isOne: boolean; | ||
@@ -11,3 +12,3 @@ onDeselect: Deselect<I>; | ||
} | ||
export declare const selection: <I>({ value: values, onDeselect, textual, disabled, }: Props<I>) => import("lit-html").TemplateResult<1>[]; | ||
export declare const selection: <I>({ value: values, min, onDeselect, textual, disabled, }: Props<I>) => import("lit-html").TemplateResult<1>[]; | ||
export {}; |
import { html } from 'lit-html'; | ||
import { chip } from './chip'; | ||
export const selection = ({ value: values, onDeselect, textual, disabled, }) => [ | ||
export const selection = ({ value: values, min = 0, onDeselect, textual, disabled, }) => [ | ||
...values.filter(Boolean).map((value) => chip({ | ||
content: textual(value), | ||
onClear: () => onDeselect(value), | ||
onClear: values.length > min && (() => onDeselect(value)), | ||
disabled, | ||
@@ -8,0 +8,0 @@ slot: 'control', |
@@ -8,2 +8,3 @@ type Source<I> = (opts: { | ||
limit?: number; | ||
min?: number; | ||
keepOpened?: boolean; | ||
@@ -29,4 +30,5 @@ keepQuery?: boolean; | ||
onFocus?: (focused?: boolean) => void; | ||
preserveOrder?: boolean; | ||
} | ||
export declare const useAutocomplete: <I>({ value: _value, text, onChange: _onChange, onText: _onText, onSelect, limit, source, textProperty, textual: _textual, valueProperty, external, hideEmpty, keepOpened, keepQuery, ...thru }: Props<I>) => { | ||
export declare const useAutocomplete: <I>({ value: _value, text, onChange: _onChange, onText: _onText, onSelect, limit, min, source, textProperty, textual: _textual, valueProperty, external, hideEmpty, keepOpened, keepQuery, preserveOrder, ...thru }: Props<I>) => { | ||
active: boolean | undefined; | ||
@@ -33,0 +35,0 @@ query: string; |
@@ -9,12 +9,12 @@ import { useCallback, useMemo, useEffect } from '@pionjs/pion'; | ||
import { search, normalize, notify, useNotify, EMPTY$ } from './util'; | ||
export const useAutocomplete = ({ value: _value, text, onChange: _onChange, onText: _onText, onSelect, limit, source, textProperty, textual: _textual, valueProperty, external, hideEmpty, keepOpened, keepQuery, ...thru }) => { | ||
export const useAutocomplete = ({ value: _value, text, onChange: _onChange, onText: _onText, onSelect, limit, min, source, textProperty, textual: _textual, valueProperty, external, hideEmpty, keepOpened, keepQuery, preserveOrder, ...thru }) => { | ||
const textual = useMemo(() => (_textual ?? strProp)(textProperty), [_textual, textProperty]), { active, focused, onFocus, setClosed } = useFocus(thru), empty = !text, query = useMemo(() => text?.trim(), [text]), host = useHost(), onText = useNotify(host, _onText, 'text'), onChange = useCallback((val) => { | ||
_onChange?.(val, () => setClosed(true)); | ||
notify(host, 'value', val); | ||
}, [_onChange]), source$ = useMemo(() => Promise.resolve(typeof source === 'function' ? source({ query, active }) : source), [source, active, query]), value = useMemo(() => array(_value), [_value]), values$ = useMemo(() => source$.then((source) => { | ||
return [ | ||
}, [_onChange]), source$ = useMemo(() => Promise.resolve(typeof source === 'function' ? source({ query, active }) : source), [source, active, query]), value = useMemo(() => array(_value), [_value]), values$ = useMemo(() => source$.then((source) => preserveOrder | ||
? normalize(source) | ||
: [ | ||
...value, | ||
...without(value, prop(valueProperty))(normalize(source)), | ||
]; | ||
}), [source$, value, valueProperty]); | ||
]), [source$, value, valueProperty]); | ||
useKeys({ | ||
@@ -38,2 +38,3 @@ focused, | ||
limit, | ||
min, | ||
keepQuery, | ||
@@ -66,3 +67,3 @@ keepOpened, | ||
meta.onSelect?.(newVal, meta); | ||
const { onChange, onText, limit, value: val, keepQuery, keepOpened, setClosed, } = meta; | ||
const { onChange, onText, limit, min, value: val, keepQuery, keepOpened, setClosed, } = meta; | ||
if (!keepQuery) | ||
@@ -72,4 +73,6 @@ onText(''); | ||
setClosed(true); | ||
const value = array(val); | ||
onChange((value.includes(newVal) | ||
const value = array(val), deselect = value.includes(newVal); | ||
if (deselect && value.length === min) | ||
return; | ||
onChange((deselect | ||
? without(newVal)(value) | ||
@@ -76,0 +79,0 @@ : [...value, newVal]).slice(-limit)); |
@@ -1,9 +0,11 @@ | ||
import { html, component, useEffect, useRef, useMemo } from '@pionjs/pion'; | ||
import { ref } from 'lit-html/directives/ref.js'; | ||
import { virtualize, virtualizerRef, } from '@lit-labs/virtualizer/virtualize.js'; | ||
import { sheet } from '@neovici/cosmoz-utils'; | ||
import { portal } from '@neovici/cosmoz-utils/directives/portal'; | ||
import { spreadProps } from '@neovici/cosmoz-utils/directives/spread-props'; | ||
import { useStyleSheet } from '@neovici/cosmoz-utils/hooks/use-stylesheet'; | ||
import { props } from '@neovici/cosmoz-utils/object'; | ||
import { useListbox, properties } from './use-listbox'; | ||
import { styles } from './style.css'; | ||
import { component, html, useEffect, useMemo, useRef } from '@pionjs/pion'; | ||
import { ref } from 'lit-html/directives/ref.js'; | ||
import style, { styles } from './style.css'; | ||
import { properties, useListbox } from './use-listbox'; | ||
const Listbox = (props) => { | ||
@@ -20,11 +22,9 @@ const listRef = useRef(undefined); | ||
}, [position]); | ||
useStyleSheet(styles({ ...position, height, itemHeight })); | ||
const layout = useMemo(() => ({ | ||
_itemSize: { height: itemHeight - 0.00001 }, | ||
}), [itemHeight]); | ||
return html ` <style> | ||
${styles({ ...position, height, itemHeight })} | ||
</style> | ||
<div class="items" ${ref((el) => (listRef.current = el))}> | ||
<div virtualizer-sizer></div> | ||
${virtualize({ | ||
return html `<div class="items" ${ref((el) => (listRef.current = el))}> | ||
<div virtualizer-sizer></div> | ||
${virtualize({ | ||
items, | ||
@@ -35,5 +35,5 @@ renderItem, | ||
})} | ||
</div>`; | ||
</div>`; | ||
}; | ||
customElements.define('cosmoz-listbox', component(Listbox)); | ||
customElements.define('cosmoz-listbox', component(Listbox, { styleSheets: [sheet(style)] })); | ||
export const listbox = ({ multi, ...thru }) => portal(html `<cosmoz-listbox | ||
@@ -40,0 +40,0 @@ part="listbox" |
@@ -87,4 +87,2 @@ import { tagged as css } from '@neovici/cosmoz-utils'; | ||
export const styles = ({ index, height, itemHeight, }) => css ` | ||
${style} | ||
:host { | ||
@@ -91,0 +89,0 @@ min-height: ${itemHeight}px; |
{ | ||
"name": "@neovici/cosmoz-autocomplete", | ||
"version": "8.0.0", | ||
"version": "8.1.0", | ||
"description": "A autocomplete input web component", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
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
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
37865
1025