@snack-uikit/list
Advanced tools
Comparing version 0.1.2 to 0.1.3-preview-3a43a07a.0
@@ -1,3 +0,3 @@ | ||
import { BaseItemPrivateProps, BaseItemProps, SwitchProps } from '../types'; | ||
type AllBaseItemProps = BaseItemProps & BaseItemPrivateProps & SwitchProps & { | ||
import { BaseItemPrivateProps, BaseItemProps } from '../types'; | ||
type AllBaseItemProps = BaseItemProps & BaseItemPrivateProps & { | ||
indeterminate?: boolean; | ||
@@ -7,3 +7,3 @@ onSelect?(): void; | ||
}; | ||
export declare function BaseItem({ beforeContent, afterContent, content, onClick, id, expandIcon, disabled, open, itemRef, switch: switchProp, onKeyDown, onFocus, indeterminate, onSelect, isParentNode, ...rest }: AllBaseItemProps): import("react/jsx-runtime").JSX.Element; | ||
export declare function BaseItem({ beforeContent, afterContent, content, onClick, id, expandIcon, disabled, open, itemRef, switch: switchProp, onKeyDown, onFocus, indeterminate, onSelect, isParentNode, className, inactive, ...rest }: AllBaseItemProps): import("react/jsx-runtime").JSX.Element; | ||
export {}; |
@@ -22,3 +22,3 @@ var __rest = (this && this.__rest) || function (s, e) { | ||
export function BaseItem(_a) { | ||
var { beforeContent, afterContent, content, onClick, id, expandIcon, disabled, open, itemRef, switch: switchProp, onKeyDown, onFocus, indeterminate, onSelect, isParentNode } = _a, rest = __rest(_a, ["beforeContent", "afterContent", "content", "onClick", "id", "expandIcon", "disabled", "open", "itemRef", "switch", "onKeyDown", "onFocus", "indeterminate", "onSelect", "isParentNode"]); | ||
var { beforeContent, afterContent, content, onClick, id, expandIcon, disabled, open, itemRef, switch: switchProp, onKeyDown, onFocus, indeterminate, onSelect, isParentNode, className, inactive } = _a, rest = __rest(_a, ["beforeContent", "afterContent", "content", "onClick", "id", "expandIcon", "disabled", "open", "itemRef", "switch", "onKeyDown", "onFocus", "indeterminate", "onSelect", "isParentNode", "className", "inactive"]); | ||
const { option, caption, description } = content || {}; | ||
@@ -34,5 +34,7 @@ const { parentResetActiveFocusIndex } = useParentListContext(); | ||
const handleItemClick = (e) => { | ||
parentResetActiveFocusIndex === null || parentResetActiveFocusIndex === void 0 ? void 0 : parentResetActiveFocusIndex(); | ||
if (!isParentNode) { | ||
handleChange(); | ||
if (!inactive) { | ||
parentResetActiveFocusIndex === null || parentResetActiveFocusIndex === void 0 ? void 0 : parentResetActiveFocusIndex(); | ||
if (!isParentNode) { | ||
handleChange(); | ||
} | ||
} | ||
@@ -70,3 +72,3 @@ onClick === null || onClick === void 0 ? void 0 : onClick(e); | ||
const props = extractSupportProps(rest); | ||
return (_jsx("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, children: _jsxs("button", { ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": selection || undefined, "data-open": open || undefined, disabled: disabled, onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && _jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' }), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }) })); | ||
return (_jsx("li", { role: 'menuitem', "data-test-id": props['data-test-id'] || 'list__base-item_' + id, children: _jsxs("button", { ref: itemRef, className: cn(commonStyles.listItem, styles.droplistItem, className), "data-size": size, onClick: handleItemClick, tabIndex: -1, "data-non-pointer": inactive && !onClick, "data-inactive": inactive || undefined, "data-checked": (isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined, "data-variant": selection || undefined, "data-open": open || undefined, disabled: disabled, onKeyDown: handleItemKeyDown, onFocus: handleItemFocus, style: { '--level': level }, children: [!switchProp && isSelectionSingle && marker && !isParentNode && !inactive && (_jsx("div", { className: styles.markerContainer, "data-test-id": 'list__base-item-marker' })), !switchProp && isSelectionMultiple && !inactive && (_jsx("div", { className: styles.checkbox, children: _jsx(Checkbox, { size: CHECKBOX_SIZE_MAP[size !== null && size !== void 0 ? size : 's'], disabled: disabled, tabIndex: -1, onChange: handleCheckboxChange, checked: isChecked, "data-test-id": 'list__base-item-checkbox', onClick: handleCheckboxClick, indeterminate: indeterminate }) })), beforeContent && _jsx("div", { className: styles.beforeContent, children: beforeContent }), _jsxs("div", { className: styles.content, children: [_jsxs("div", { className: styles.headline, children: [_jsx("span", { className: styles.option, children: _jsx(TruncateString, { text: option, maxLines: 1 }) }), caption && _jsx("span", { className: styles.caption, children: caption })] }), description && (_jsx("div", { className: styles.description, children: _jsx(TruncateString, { text: description, maxLines: 2 }) }))] }), afterContent, switchProp && !inactive && (_jsx(Switch, { disabled: disabled, checked: isChecked, "data-test-id": 'list__base-item-switch' })), !switchProp && expandIcon && _jsx("span", { className: styles.expandableIcon, children: expandIcon })] }) })); | ||
} |
@@ -25,12 +25,13 @@ import { FocusEvent, KeyboardEvent, MouseEvent, ReactNode, RefObject } from 'react'; | ||
itemRef?: RefObject<HTMLButtonElement>; | ||
className?: string; | ||
inactive?: boolean; | ||
switch?: boolean; | ||
}>; | ||
export type SwitchProps = { | ||
switch?: boolean; | ||
}; | ||
export type ItemProps = (BaseItemProps & SwitchProps) | AccordionItemProps | NextListItemProps | GroupItemProps; | ||
export type AccordionItemProps = BaseItemProps & { | ||
type BaseItemsWithoutNonGroupProps = Omit<BaseItemProps, 'switch' | 'inactive'>; | ||
export type ItemProps = BaseItemProps | AccordionItemProps | NextListItemProps | GroupItemProps; | ||
export type AccordionItemProps = BaseItemsWithoutNonGroupProps & { | ||
items: ItemProps[]; | ||
type: 'collapse'; | ||
}; | ||
export type NextListItemProps = BaseItemProps & { | ||
export type NextListItemProps = BaseItemsWithoutNonGroupProps & { | ||
items: ItemProps[]; | ||
@@ -41,5 +42,6 @@ type: 'next-list'; | ||
} & ScrollProps; | ||
export type GroupItemProps = SeparatorProps & { | ||
export type GroupItemProps = Omit<SeparatorProps, 'size'> & { | ||
items: ItemProps[]; | ||
id?: string | number; | ||
}; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
/// <reference types="react" /> | ||
import { KeyboardEvent } from 'react'; | ||
export declare const List: import("react").ForwardRefExoticComponent<{ | ||
@@ -14,2 +14,4 @@ 'data-test-id'?: string | undefined; | ||
noResults?: string | undefined; | ||
tabIndex?: number | undefined; | ||
onKeyDown?(e: KeyboardEvent<HTMLElement>): void; | ||
} & Pick<import("../contexts").SelectionProviderProps, "value" | "defaultValue" | "selection" | "onChange"> & import("../contexts").ListContextType & import("../../../types").ScrollProps & import("react").RefAttributes<HTMLElement>>; |
@@ -13,2 +13,3 @@ var __rest = (this && this.__rest) || function (s, e) { | ||
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; | ||
import mergeRefs from 'merge-refs'; | ||
import { forwardRef, useMemo, useRef, useState } from 'react'; | ||
@@ -22,4 +23,4 @@ import { HiddenTabButton } from '../../../helperComponents'; | ||
import styles from '../styles.module.css'; | ||
export const List = forwardRef((_a) => { | ||
var { items: itemsProp, search, pinBottom, pinTop, footerActiveElementsRefs } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs"]); | ||
export const List = forwardRef((_a, ref) => { | ||
var { items: itemsProp, search, pinBottom, pinTop, footerActiveElementsRefs, onKeyDown, tabIndex = 0 } = _a, props = __rest(_a, ["items", "search", "pinBottom", "pinTop", "footerActiveElementsRefs", "onKeyDown", "tabIndex"]); | ||
const hasSearch = useMemo(() => Boolean(search), [search]); | ||
@@ -57,2 +58,12 @@ const memorizedItems = useMemo(() => addItemsIds((pinTop !== null && pinTop !== void 0 ? pinTop : []).concat(itemsProp).concat(pinBottom !== null && pinBottom !== void 0 ? pinBottom : [])), [itemsProp, pinBottom, pinTop]); | ||
const isActive = listRef.current === document.activeElement && activeFocusIndex === -1 && openNestedIndex === -1; | ||
const mergedHandlerKeyDown = (e) => { | ||
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e); | ||
handleListKeyDown === null || handleListKeyDown === void 0 ? void 0 : handleListKeyDown(e); | ||
}; | ||
const handleOnFocus = (e) => { | ||
if (e.relatedTarget === null || | ||
(e.relatedTarget && itemRefs.every(({ current }) => current !== e.relatedTarget))) { | ||
resetActiveFocusIndex(); | ||
} | ||
}; | ||
return ( | ||
@@ -74,8 +85,3 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
toggleOpenCollapsedItems: id => setOpenCollapsedItems(items => items.includes(id) ? items.filter(item => item !== id) : items.concat([id])), | ||
}, children: _jsxs("div", { className: styles.wrapper, "data-active": isActive || undefined, children: [_jsx(ListPrivate, Object.assign({}, props, slicedItems, { ref: listRef, onFocus: e => { | ||
if (e.relatedTarget === null || | ||
(e.relatedTarget && itemRefs.every(({ current }) => current !== e.relatedTarget))) { | ||
resetActiveFocusIndex(); | ||
} | ||
}, onKeyDown: handleListKeyDown, tabIndex: 0, search: search, nested: false })), _jsx(HiddenTabButton, { ref: btnRef, listRef: listRef })] }) }) }))); | ||
}, children: _jsxs("div", { className: styles.wrapper, "data-active": isActive || undefined, children: [_jsx(ListPrivate, Object.assign({}, props, slicedItems, { ref: mergeRefs(ref, listRef), onFocus: handleOnFocus, onKeyDown: mergedHandlerKeyDown, tabIndex: tabIndex, search: search, nested: false })), _jsx(HiddenTabButton, { ref: btnRef, listRef: listRef, tabIndex: tabIndex })] }) }) }))); | ||
}); |
@@ -14,2 +14,4 @@ import { RefObject } from 'react'; | ||
noResults?: string | undefined; | ||
tabIndex?: number | undefined; | ||
onKeyDown?(e: import("react").KeyboardEvent<HTMLElement>): void; | ||
} & Pick<import("../contexts").SelectionProviderProps, "value" | "defaultValue" | "selection" | "onChange"> & import("../contexts").ListContextType & import("../../../types").ScrollProps & { | ||
@@ -16,0 +18,0 @@ nested?: boolean | undefined; |
@@ -26,2 +26,4 @@ import { FocusEvent, KeyboardEvent, ReactNode, RefObject } from 'react'; | ||
noResults?: string; | ||
tabIndex?: number; | ||
onKeyDown?(e: KeyboardEvent<HTMLElement>): void; | ||
} & Pick<SelectionProviderProps, 'value' | 'defaultValue' | 'onChange' | 'selection'> & ListContextType & ScrollProps>; | ||
@@ -33,3 +35,3 @@ export type DroplistProps = { | ||
children?: ReactNode; | ||
} & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> & ListProps; | ||
} & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> & Omit<ListProps, 'tabIndex' | 'onKeyDown'>; | ||
export type ListPrivateProps = ListProps & { | ||
@@ -36,0 +38,0 @@ nested?: boolean; |
import { RefObject } from 'react'; | ||
type HiddenTabButtonProps = { | ||
listRef: RefObject<HTMLElement>; | ||
tabIndex?: number; | ||
}; | ||
export declare const HiddenTabButton: import("react").ForwardRefExoticComponent<HiddenTabButtonProps & import("react").RefAttributes<HTMLButtonElement>>; | ||
export {}; |
import { jsx as _jsx } from "react/jsx-runtime"; | ||
import { forwardRef, useCallback } from 'react'; | ||
import styles from './styles.module.css'; | ||
export const HiddenTabButton = forwardRef(({ listRef }, ref) => { | ||
export const HiddenTabButton = forwardRef(({ listRef, tabIndex }, ref) => { | ||
const handleFocus = useCallback((e) => { | ||
@@ -16,3 +16,3 @@ var _a; | ||
}, []); | ||
return _jsx("button", { "aria-hidden": true, ref: ref, onKeyDown: handleKeyDown, onFocus: handleFocus, className: styles.hiddenBtn }); | ||
return (_jsx("button", { "aria-hidden": true, ref: ref, onKeyDown: handleKeyDown, onFocus: handleFocus, className: styles.hiddenBtn, tabIndex: tabIndex })); | ||
}); |
@@ -9,3 +9,4 @@ import { isAccordionItemProps, isBaseItemProps, isGroupItemProps, isNextListItemProps, } from './components/Items'; | ||
var _a; | ||
if ((isBaseItemProps(item) || isNextListItemProps(item) || isAccordionItemProps(item)) && !item.disabled) { | ||
if (((isBaseItemProps(item) && !item.inactive) || isNextListItemProps(item) || isAccordionItemProps(item)) && | ||
!item.disabled) { | ||
newItems = newItems.concat([item]); | ||
@@ -59,3 +60,6 @@ ids = ids.concat([(_a = item.id) !== null && _a !== void 0 ? _a : '']); | ||
return items | ||
.filter(item => isAccordionItemProps(item) || isNextListItemProps(item) || isGroupItemProps(item) || !item.disabled) | ||
.filter(item => isAccordionItemProps(item) || | ||
isNextListItemProps(item) || | ||
isGroupItemProps(item) || | ||
(isBaseItemProps(item) && !item.disabled && !item.inactive)) | ||
.reduce((prev, item) => { | ||
@@ -62,0 +66,0 @@ var _a; |
@@ -7,3 +7,3 @@ { | ||
"title": "List", | ||
"version": "0.1.2", | ||
"version": "0.1.3-preview-3a43a07a.0", | ||
"sideEffects": [ | ||
@@ -46,5 +46,6 @@ "*.css", | ||
"classnames": "2.5.1", | ||
"merge-refs": "1.2.2", | ||
"uncontrollable": "8.0.4" | ||
}, | ||
"gitHead": "029bc819dd13f9006b9ad584fb56454517a2077d" | ||
"gitHead": "cd354254d1d434829a3d3235ac4b46723a853636" | ||
} |
@@ -31,2 +31,6 @@ # List | ||
| placement | enum Placement: `"left"`, `"left-start"`, `"left-end"`, `"right"`, `"right-start"`, `"right-end"`, `"top"`, `"top-start"`, `"top-end"`, `"bottom"`, `"bottom-start"`, `"bottom-end"` | top | Положение поповера относительно своего триггера (children). | | ||
| value | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Controlled состояние | | ||
| defaultValue | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Начальное состояние | | ||
| onChange | `((value: any) => void) \| ((value: any) => void)` | - | Controlled обработчик измения состояния | | ||
| selection | "single" \| "multiple" | - | Режим выбора | | ||
| pinTop | `ItemProps[]` | - | Элементы списка, закрепленные сверху | | ||
@@ -40,6 +44,2 @@ | pinBottom | `ItemProps[]` | - | Элементы списка, закрепленные снизу | | ||
| noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске | | ||
| value | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Controlled состояние | | ||
| defaultValue | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Начальное состояние | | ||
| onChange | `((value: any) => void) \| ((value: any) => void)` | - | Controlled обработчик измения состояния | | ||
| selection | "single" \| "multiple" | - | Режим выбора | | ||
| size | "s" \| "m" \| "l" | - | Размер списка | | ||
@@ -63,2 +63,4 @@ | marker | `boolean` | - | Отображать ли маркер у выбранного жлемента списка | | ||
| noResults | `string` | - | Текст для состояния "Отсутсвие результата" при поиске | | ||
| tabIndex | `number` | - | | | ||
| onKeyDown | `(e: KeyboardEvent<HTMLElement>) => void` | - | | | ||
| value | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Controlled состояние | | ||
@@ -65,0 +67,0 @@ | defaultValue | `SelectionSingleValueType \| SelectionSingleValueType[]` | - | Начальное состояние | |
@@ -35,12 +35,14 @@ import { FocusEvent, KeyboardEvent, MouseEvent, ReactNode, RefObject } from 'react'; | ||
itemRef?: RefObject<HTMLButtonElement>; | ||
}>; | ||
className?: string; | ||
export type SwitchProps = { | ||
inactive?: boolean; | ||
switch?: boolean; | ||
}; | ||
}>; | ||
type BaseItemsWithoutNonGroupProps = Omit<BaseItemProps, 'switch' | 'inactive'>; | ||
// eslint-disable-next-line no-use-before-define | ||
export type ItemProps = (BaseItemProps & SwitchProps) | AccordionItemProps | NextListItemProps | GroupItemProps; | ||
export type ItemProps = BaseItemProps | AccordionItemProps | NextListItemProps | GroupItemProps; | ||
export type AccordionItemProps = BaseItemProps & { | ||
export type AccordionItemProps = BaseItemsWithoutNonGroupProps & { | ||
items: ItemProps[]; | ||
@@ -52,3 +54,3 @@ // TODO: add later | ||
export type NextListItemProps = BaseItemProps & { | ||
export type NextListItemProps = BaseItemsWithoutNonGroupProps & { | ||
items: ItemProps[]; | ||
@@ -60,5 +62,5 @@ type: 'next-list'; | ||
export type GroupItemProps = SeparatorProps & { | ||
export type GroupItemProps = Omit<SeparatorProps, 'size'> & { | ||
items: ItemProps[]; | ||
id?: string | number; | ||
}; |
@@ -32,2 +32,4 @@ import { FocusEvent, KeyboardEvent, ReactNode, RefObject } from 'react'; | ||
noResults?: string; | ||
tabIndex?: number; | ||
onKeyDown?(e: KeyboardEvent<HTMLElement>): void; | ||
} & Pick<SelectionProviderProps, 'value' | 'defaultValue' | 'onChange' | 'selection'> & | ||
@@ -44,3 +46,3 @@ ListContextType & | ||
} & Pick<DropdownProps, 'trigger' | 'placement' | 'widthStrategy' | 'open' | 'onOpenChange'> & | ||
ListProps; | ||
Omit<ListProps, 'tabIndex' | 'onKeyDown'>; | ||
@@ -47,0 +49,0 @@ export type ListPrivateProps = ListProps & { |
@@ -23,3 +23,6 @@ import { RefObject } from 'react'; | ||
items.forEach(item => { | ||
if ((isBaseItemProps(item) || isNextListItemProps(item) || isAccordionItemProps(item)) && !item.disabled) { | ||
if ( | ||
((isBaseItemProps(item) && !item.inactive) || isNextListItemProps(item) || isAccordionItemProps(item)) && | ||
!item.disabled | ||
) { | ||
newItems = newItems.concat([item]); | ||
@@ -92,3 +95,9 @@ ids = ids.concat([item.id ?? '']); | ||
return items | ||
.filter(item => isAccordionItemProps(item) || isNextListItemProps(item) || isGroupItemProps(item) || !item.disabled) | ||
.filter( | ||
item => | ||
isAccordionItemProps(item) || | ||
isNextListItemProps(item) || | ||
isGroupItemProps(item) || | ||
(isBaseItemProps(item) && !item.disabled && !item.inactive), | ||
) | ||
.reduce( | ||
@@ -95,0 +104,0 @@ (prev: Array<string | number>, item: ItemProps) => { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
182850
3609
77
12
+ Addedmerge-refs@1.2.2
+ Added@babel/runtime@7.26.9(transitive)
- Removed@babel/runtime@7.26.7(transitive)