@smwb/ui-react 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"selectField.js","sources":["../../../../../src/components/inputs/selectField/selectField.tsx"],"sourcesContent":["import type { HTMLAttributes, SyntheticEvent } from \"react\";\nimport React, { useState, useRef, useEffect, useMemo, forwardRef } from \"react\";\nimport cn from \"clsx\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { DropdownMenu, DropdownItem, DropdownItemProps } from \"./dropdownMenu\";\nimport Chip from \"../../dataDisplay/chip/chip\";\nimport { TextFieldWrapper } from \"../textField\";\nimport Icon from \"../../base/icon/icon\";\nimport { MenuItemProps } from \"../../navigation/menu\";\n\nconst SelectArrowIcon = (props: HTMLAttributes<HTMLSpanElement>) => <Icon name=\"arrow_drop_down\" {...props} />;\n\nconst ClearIcon = (props: HTMLAttributes<HTMLSpanElement>) => <Icon name=\"close\" size={20} {...props} />;\n\nfunction stopEvent(event: React.SyntheticEvent) {\n event.preventDefault();\n event.stopPropagation();\n}\n\nexport type OnSelectChange = (e: SyntheticEvent, data: SelectFieldProps) => void;\n\nexport interface SelectFieldProps {\n className?: string;\n value?: null | string | number | (string | number | undefined | null)[];\n defaultValue?: null | string | number | (string | number)[];\n onChange?: OnSelectChange;\n disabled?: boolean;\n readOnly?: boolean;\n name?: string;\n multiple?: boolean;\n menuMaxHeight?: number;\n menuMiddleware?: DropdownItemProps[\"menuMiddleware\"];\n menuNoItemsMessage?: React.ReactNode;\n menuContainer?: HTMLElement;\n search?: true | false | \"menu\";\n chips?: boolean;\n isFocused?: boolean;\n error?: boolean;\n items: DropdownItem[];\n label?: string;\n variant?: \"outlined\" | \"filled\";\n fullWidth?: boolean;\n helperText?: React.ReactNode;\n onSearch?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n isLoading?: boolean;\n resetSearch?: () => void;\n inline?: boolean;\n endAdornment?: React.ReactNode;\n hideSelectArrowIcon?: boolean;\n optionRenderer?: (args: MenuItemProps) => React.ReactNode;\n /** Shows a clear button to reset the selection. */\n clearable?: boolean;\n /** Allows creating a new option from the current search text. */\n creatable?: boolean;\n /** Invoked with the typed text when the user creates a new option. */\n onCreate?: (inputValue: string, event: React.SyntheticEvent) => void;\n /** Windows long option lists for performance (fixed row height). */\n virtualized?: boolean;\n /** Row height (px) used when `virtualized`. */\n itemHeight?: number;\n /** Accessible label for the combobox control. */\n \"aria-label\"?: string;\n id?: string;\n}\n\nexport const SelectField = forwardRef<HTMLSpanElement, SelectFieldProps>(function SelectField(props, ref) {\n const {\n className,\n value: valueProp,\n defaultValue,\n onChange,\n disabled,\n readOnly,\n name,\n multiple,\n menuMaxHeight,\n menuMiddleware,\n menuNoItemsMessage,\n menuContainer,\n search,\n chips,\n isFocused: isFocusedProp,\n error,\n items,\n label,\n variant = \"outlined\",\n fullWidth,\n helperText,\n onSearch,\n resetSearch,\n isLoading,\n inline,\n endAdornment,\n hideSelectArrowIcon,\n optionRenderer,\n clearable,\n creatable,\n onCreate,\n virtualized,\n itemHeight,\n \"aria-label\": ariaLabel,\n id,\n ...rest\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [valueState, setValueState] = useState<typeof valueProp>(defaultValue);\n const [selectedItems, setSelectedItems] = useState<typeof items>(() => {\n if (Array.isArray(valueProp)) {\n return items.filter((item) => valueProp.includes(item.value));\n }\n\n const item = items.find((i) => i.value === valueProp);\n\n return item ? [item] : [];\n });\n const [searchValue, setSearchValue] = useState(\"\");\n const { current: isControlled } = useRef(valueProp != null);\n const anchorElementRef = useRef<HTMLSpanElement>(null);\n const forkedAnchorRef = useForkRef<HTMLSpanElement>(ref, anchorElementRef);\n const searchWrapperRef = useRef<HTMLSpanElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const value = isControlled ? valueProp : valueState;\n\n const isFocused = useMemo(() => isFocusedProp || isOpen, [isFocusedProp, isOpen]);\n\n const onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n // Только для левой клавиши мышки.\n if (event.button !== 0) {\n return;\n }\n event.preventDefault();\n anchorElementRef.current?.focus();\n setIsOpen(!isOpen);\n };\n\n const onClose = () => {\n setIsOpen(false);\n anchorElementRef.current?.focus();\n };\n\n const onFocus = () => {\n if (search === true) {\n searchInputRef.current?.focus();\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!readOnly) {\n const validKeys = [\" \", \"ArrowUp\", \"ArrowDown\", \"Enter\"];\n\n if (validKeys.includes(event.key)) {\n event.preventDefault();\n setIsOpen(!isOpen);\n }\n }\n };\n\n useEffect(() => {\n if (!isFocused || (search === \"menu\" && !isOpen)) {\n setSearchValue(\"\");\n resetSearch?.();\n }\n }, [isFocused, search, isOpen, resetSearch]);\n\n useEffect(() => {\n if (!value || (Array.isArray(value) && !value.length)) {\n setSelectedItems([]);\n }\n }, [value]);\n\n useEffect(() => {\n if (Array.isArray(valueProp)) {\n setSelectedItems(items.filter((item) => valueProp.includes(item.value)));\n } else {\n const item = valueProp == undefined ? undefined : items.find((item) => item.value === valueProp);\n\n if (item === undefined) {\n setSelectedItems([]);\n } else {\n setSelectedItems([item]);\n }\n }\n }, [valueProp, items]);\n\n useSafeLayoutEffect(() => {\n if (searchWrapperRef.current) {\n searchWrapperRef.current.scrollLeft = searchWrapperRef.current.scrollWidth;\n }\n }, [value]);\n\n const updateValue = (event: React.SyntheticEvent, value: typeof valueProp) => {\n onChange?.(event, { ...props, value, name: name || undefined });\n setValueState(value);\n };\n\n const onItemClick = (event: React.SyntheticEvent, item: DropdownItem) => {\n let newValue: typeof valueProp;\n let newSelectedItem: typeof selectedItems;\n if (multiple) {\n const valueArray = Array.isArray(value) ? value : [value].filter(Boolean);\n newValue = valueArray.slice();\n newSelectedItem = selectedItems.slice();\n const itemIndex = valueArray.findIndex((el) => el === item.value);\n\n if (itemIndex === -1) {\n newValue.push(item.value);\n newSelectedItem.push(item);\n } else {\n newValue.splice(itemIndex, 1);\n newSelectedItem.splice(itemIndex, 1);\n }\n } else {\n newValue = value === item.value ? \"\" : item.value;\n newSelectedItem = [item];\n }\n\n if (searchValue) {\n setSearchValue(\"\");\n }\n\n if (!multiple) {\n setIsOpen(false);\n anchorElementRef.current?.focus();\n }\n setSelectedItems(newSelectedItem);\n updateValue(event, newValue);\n };\n\n const onSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchValue(event.target.value);\n onSearch?.(event);\n if (!isOpen) {\n setIsOpen(true);\n }\n };\n\n const onDeleteChip = (currentValue: typeof valueProp) => (event: React.SyntheticEvent) => {\n if (Array.isArray(value)) {\n const newValue = value.filter((value) => currentValue !== value);\n updateValue(event, newValue);\n const newSelectedItems = selectedItems.filter((el) => el.value !== currentValue);\n setSelectedItems(newSelectedItems);\n }\n };\n\n const onResetSelected = (event: React.MouseEvent) => {\n updateValue(event, []);\n setSelectedItems([]);\n };\n\n let displayValues: string | React.ReactNode[];\n\n const classes = cn(\"smwb-select-field\", className, {\n \"smwb-select-field--filled\": variant === \"filled\" && label,\n \"smwb-select-field--disabled\": disabled,\n \"smwb-select-field--search\": search,\n \"smwb-select-field--inline\": inline,\n });\n\n if (chips) {\n displayValues = selectedItems.map(({ key, value, text }) => (\n <Chip key={key || value} label={text} onDelete={onDeleteChip(value)} onDeleteMouseDown={stopEvent} />\n ));\n } else {\n displayValues = selectedItems.map((el) => el.text).join(\", \");\n }\n\n return (\n <>\n <TextFieldWrapper\n label={label}\n helperText={helperText}\n variant={variant}\n disabled={disabled}\n className={className}\n error={error}\n fullWidth={fullWidth}\n isFilledState={!!selectedItems.length || !!searchValue}\n isFocused={isFocused}\n inline={inline}\n {...rest}\n >\n <span\n ref={forkedAnchorRef}\n id={id}\n className={classes}\n tabIndex={disabled ? undefined : 0}\n role=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-disabled={disabled || undefined}\n aria-label={ariaLabel}\n onMouseDown={disabled || readOnly ? undefined : onMouseDown}\n onFocus={onFocus}\n onKeyDown={onKeyDown}\n data-testid=\"select-field\"\n >\n <span className=\"smwb-select-field__search-wrapper\" ref={searchWrapperRef}>\n {displayValues && <span className=\"smwb-select-field__values\">{displayValues}</span>}\n {search && typeof search === \"boolean\" && !readOnly && (\n <span className=\"smwb-select-field__search\">\n <span className=\"smwb-select-field__search-text\">{searchValue}</span>\n <input\n className=\"smwb-select-field__search-input\"\n ref={searchInputRef}\n type=\"text\"\n value={searchValue}\n onChange={onSearchInputChange}\n onMouseDown={(event: React.MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n setIsOpen(true);\n }}\n onKeyDown={(event) => {\n event.stopPropagation();\n }}\n data-testid=\"search-input\"\n />\n </span>\n )}\n </span>\n <span className=\"smwb-select-field__actions\">\n {((Array.isArray(value) && value.length > 0) || (clearable && selectedItems.length > 0)) && !disabled && (\n <ClearIcon\n onClick={onResetSelected}\n onMouseDown={stopEvent}\n className={cn(\"smwb-select-field__icon\", \"smwb-select-field__icon--close\")}\n aria-label=\"Clear selection\"\n role=\"button\"\n />\n )}\n {endAdornment}\n {!hideSelectArrowIcon && (\n <SelectArrowIcon\n className={cn(\"smwb-select-field__icon\", \"smwb-select-field__icon--arrow\", {\n \"smwb-select-field__icon--opened\": isOpen,\n \"smwb-select-field__icon--focused\": isFocused,\n \"smwb-select-field__icon--error\": error,\n })}\n />\n )}\n </span>\n </span>\n </TextFieldWrapper>\n <DropdownMenu\n anchorElementRef={anchorElementRef}\n menuMaxHeight={menuMaxHeight}\n menuMiddleware={menuMiddleware}\n search={search === \"menu\"}\n onSearchInputChange={onSearchInputChange}\n optionRenderer={optionRenderer}\n items={\n onSearch\n ? items\n : searchValue\n ? items.filter((el) => el.text.search(new RegExp(searchValue, \"i\")) !== -1)\n : items\n }\n searchValue={searchValue}\n isOpen={isOpen}\n onClose={onClose}\n onItemClick={onItemClick}\n value={value}\n isLoading={isLoading}\n menuNoItemsMessage={menuNoItemsMessage}\n container={menuContainer}\n virtualized={virtualized}\n itemHeight={itemHeight}\n createOption={\n creatable && searchValue && !items.some((i) => i.text.toLowerCase() === String(searchValue).toLowerCase())\n ? {\n text: `Создать \"${searchValue}\"`,\n onCreate: (event: React.SyntheticEvent) => {\n onCreate?.(String(searchValue), event);\n setSearchValue(\"\");\n setIsOpen(false);\n },\n }\n : undefined\n }\n />\n </>\n );\n});\n\nexport default SelectField;\n"],"names":["SelectArrowIcon","props","jsx","Icon","ClearIcon","stopEvent","event","SelectField","forwardRef","ref","className","valueProp","defaultValue","onChange","disabled","readOnly","name","multiple","menuMaxHeight","menuMiddleware","menuNoItemsMessage","menuContainer","search","chips","isFocusedProp","error","items","label","variant","fullWidth","helperText","onSearch","resetSearch","isLoading","inline","endAdornment","hideSelectArrowIcon","optionRenderer","clearable","creatable","onCreate","virtualized","itemHeight","ariaLabel","id","rest","isOpen","setIsOpen","useState","valueState","setValueState","selectedItems","setSelectedItems","item","i","searchValue","setSearchValue","isControlled","useRef","anchorElementRef","forkedAnchorRef","useForkRef","searchWrapperRef","searchInputRef","value","isFocused","useMemo","onMouseDown","_a","onClose","onFocus","onKeyDown","useEffect","useSafeLayoutEffect","updateValue","onItemClick","newValue","newSelectedItem","valueArray","itemIndex","el","onSearchInputChange","onDeleteChip","currentValue","newSelectedItems","onResetSelected","displayValues","classes","cn","key","text","Chip","jsxs","Fragment","TextFieldWrapper","DropdownMenu"],"mappings":";;;;;;;;;AAWA,MAAMA,KAAkB,CAACC,MAA2C,gBAAAC,EAACC,KAAK,MAAK,mBAAmB,GAAGF,GAAO,GAEtGG,KAAY,CAACH,MAA2C,gBAAAC,EAACC,GAAA,EAAK,MAAK,SAAQ,MAAM,IAAK,GAAGF,EAAA,CAAO;AAEtG,SAASI,EAAUC,GAA6B;AAC9C,EAAAA,EAAM,eAAA,GACNA,EAAM,gBAAA;AACR;AAgDO,MAAMC,KAAcC,GAA8C,SAAqBP,GAAOQ,GAAK;AACxG,QAAM;AAAA,IACJ,WAAAC;AAAA,IACA,OAAOC;AAAA,IACP,cAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC;AAAA,IACA,UAAAC;AAAA,IACA,eAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,oBAAAC;AAAA,IACA,eAAAC;AAAA,IACA,QAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAWC;AAAA,IACX,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,SAAAC,IAAU;AAAA,IACV,WAAAC;AAAA,IACA,YAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAAC;AAAA,IACA,WAAAC;AAAA,IACA,QAAAC;AAAA,IACA,cAAAC;AAAA,IACA,qBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,aAAAC;AAAA,IACA,YAAAC;AAAA,IACA,cAAcC;AAAA,IACd,IAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACD5C,GACE,CAAC6C,GAAQC,CAAS,IAAIC,EAAkB,EAAK,GAC7C,CAACC,IAAYC,EAAa,IAAIF,EAA2BpC,CAAY,GACrE,CAACuC,GAAeC,CAAgB,IAAIJ,EAAuB,MAAM;AACrE,QAAI,MAAM,QAAQrC,CAAS;AACzB,aAAOe,EAAM,OAAO,CAAC2B,MAAS1C,EAAU,SAAS0C,EAAK,KAAK,CAAC;AAG9D,UAAMA,IAAO3B,EAAM,KAAK,CAAC4B,MAAMA,EAAE,UAAU3C,CAAS;AAEpD,WAAO0C,IAAO,CAACA,CAAI,IAAI,CAAA;AAAA,EACzB,CAAC,GACK,CAACE,GAAaC,CAAc,IAAIR,EAAS,EAAE,GAC3C,EAAE,SAASS,GAAA,IAAiBC,EAAO/C,KAAa,IAAI,GACpDgD,IAAmBD,EAAwB,IAAI,GAC/CE,KAAkBC,GAA4BpD,GAAKkD,CAAgB,GACnEG,IAAmBJ,EAAwB,IAAI,GAC/CK,IAAiBL,EAAyB,IAAI,GAC9CM,IAAQP,KAAe9C,IAAYsC,IAEnCgB,IAAYC,GAAQ,MAAM1C,KAAiBsB,GAAQ,CAACtB,GAAesB,CAAM,CAAC,GAE1EqB,KAAc,CAAC7D,MAA4C;;AAE/D,IAAIA,EAAM,WAAW,MAGrBA,EAAM,eAAA,IACN8D,IAAAT,EAAiB,YAAjB,QAAAS,EAA0B,SAC1BrB,EAAU,CAACD,CAAM;AAAA,EACnB,GAEMuB,KAAU,MAAM;;AACpB,IAAAtB,EAAU,EAAK,IACfqB,IAAAT,EAAiB,YAAjB,QAAAS,EAA0B;AAAA,EAC5B,GAEME,KAAU,MAAM;;AACpB,IAAIhD,MAAW,QACb8C,IAAAL,EAAe,YAAf,QAAAK,EAAwB;AAAA,EAE5B,GAEMG,KAAY,CAACjE,MAA+C;AAChE,IAAKS,KACe,CAAC,KAAK,WAAW,aAAa,OAAO,EAEzC,SAAST,EAAM,GAAG,MAC9BA,EAAM,eAAA,GACNyC,EAAU,CAACD,CAAM;AAAA,EAGvB;AAEA,EAAA0B,EAAU,MAAM;AACd,KAAI,CAACP,KAAc3C,MAAW,UAAU,CAACwB,OACvCU,EAAe,EAAE,GACjBxB,KAAA,QAAAA;AAAA,EAEJ,GAAG,CAACiC,GAAW3C,GAAQwB,GAAQd,CAAW,CAAC,GAE3CwC,EAAU,MAAM;AACd,KAAI,CAACR,KAAU,MAAM,QAAQA,CAAK,KAAK,CAACA,EAAM,WAC5CZ,EAAiB,CAAA,CAAE;AAAA,EAEvB,GAAG,CAACY,CAAK,CAAC,GAEVQ,EAAU,MAAM;AACd,QAAI,MAAM,QAAQ7D,CAAS;AACzB,MAAAyC,EAAiB1B,EAAM,OAAO,CAAC2B,MAAS1C,EAAU,SAAS0C,EAAK,KAAK,CAAC,CAAC;AAAA,SAClE;AACL,YAAMA,IAAO1C,KAAa,OAAY,SAAYe,EAAM,KAAK,CAAC2B,MAASA,EAAK,UAAU1C,CAAS;AAE/F,MACEyC,EADEC,MAAS,SACM,CAAA,IAEA,CAACA,CAAI,CAFH;AAAA,IAIvB;AAAA,EACF,GAAG,CAAC1C,GAAWe,CAAK,CAAC,GAErB+C,GAAoB,MAAM;AACxB,IAAIX,EAAiB,YACnBA,EAAiB,QAAQ,aAAaA,EAAiB,QAAQ;AAAA,EAEnE,GAAG,CAACE,CAAK,CAAC;AAEV,QAAMU,IAAc,CAACpE,GAA6B0D,MAA4B;AAC5E,IAAAnD,KAAA,QAAAA,EAAWP,GAAO,EAAE,GAAGL,GAAO,OAAA+D,GAAO,MAAMhD,KAAQ,WACnDkC,GAAcc,CAAK;AAAA,EACrB,GAEMW,KAAc,CAACrE,GAA6B+C,MAAuB;;AACvE,QAAIuB,GACAC;AACJ,QAAI5D,GAAU;AACZ,YAAM6D,IAAa,MAAM,QAAQd,CAAK,IAAIA,IAAQ,CAACA,CAAK,EAAE,OAAO,OAAO;AACxE,MAAAY,IAAWE,EAAW,MAAA,GACtBD,IAAkB1B,EAAc,MAAA;AAChC,YAAM4B,IAAYD,EAAW,UAAU,CAACE,OAAOA,OAAO3B,EAAK,KAAK;AAEhE,MAAI0B,MAAc,MAChBH,EAAS,KAAKvB,EAAK,KAAK,GACxBwB,EAAgB,KAAKxB,CAAI,MAEzBuB,EAAS,OAAOG,GAAW,CAAC,GAC5BF,EAAgB,OAAOE,GAAW,CAAC;AAAA,IAEvC;AACE,MAAAH,IAAWZ,MAAUX,EAAK,QAAQ,KAAKA,EAAK,OAC5CwB,IAAkB,CAACxB,CAAI;AAGzB,IAAIE,KACFC,EAAe,EAAE,GAGdvC,MACH8B,EAAU,EAAK,IACfqB,IAAAT,EAAiB,YAAjB,QAAAS,EAA0B,UAE5BhB,EAAiByB,CAAe,GAChCH,EAAYpE,GAAOsE,CAAQ;AAAA,EAC7B,GAEMK,IAAsB,CAAC3E,MAA+C;AAC1E,IAAAkD,EAAelD,EAAM,OAAO,KAAK,GACjCyB,KAAA,QAAAA,EAAWzB,IACNwC,KACHC,EAAU,EAAI;AAAA,EAElB,GAEMmC,KAAe,CAACC,MAAmC,CAAC7E,MAAgC;AACxF,QAAI,MAAM,QAAQ0D,CAAK,GAAG;AACxB,YAAMY,IAAWZ,EAAM,OAAO,CAACA,MAAUmB,MAAiBnB,CAAK;AAC/D,MAAAU,EAAYpE,GAAOsE,CAAQ;AAC3B,YAAMQ,IAAmBjC,EAAc,OAAO,CAAC6B,MAAOA,EAAG,UAAUG,CAAY;AAC/E,MAAA/B,EAAiBgC,CAAgB;AAAA,IACnC;AAAA,EACF,GAEMC,KAAkB,CAAC/E,MAA4B;AACnD,IAAAoE,EAAYpE,GAAO,EAAE,GACrB8C,EAAiB,CAAA,CAAE;AAAA,EACrB;AAEA,MAAIkC;AAEJ,QAAMC,KAAUC,EAAG,qBAAqB9E,GAAW;AAAA,IACjD,6BAA6BkB,MAAY,YAAYD;AAAA,IACrD,+BAA+Bb;AAAA,IAC/B,6BAA6BQ;AAAA,IAC7B,6BAA6BY;AAAA,EAAA,CAC9B;AAED,SAAIX,KACF+D,IAAgBnC,EAAc,IAAI,CAAC,EAAE,KAAAsC,GAAK,OAAAzB,GAAO,MAAA0B,QAC/C,gBAAAxF,EAACyF,MAAwB,OAAOD,GAAM,UAAUR,GAAalB,CAAK,GAAG,mBAAmB3D,EAAA,GAA7EoF,KAAOzB,CAAiF,CACpG,IAEDsB,IAAgBnC,EAAc,IAAI,CAAC6B,MAAOA,EAAG,IAAI,EAAE,KAAK,IAAI,GAI5D,gBAAAY,EAAAC,IAAA,EACE,UAAA;AAAA,IAAA,gBAAA3F;AAAA,MAAC4F;AAAA,MAAA;AAAA,QACC,OAAAnE;AAAA,QACA,YAAAG;AAAA,QACA,SAAAF;AAAA,QACA,UAAAd;AAAA,QACA,WAAAJ;AAAA,QACA,OAAAe;AAAA,QACA,WAAAI;AAAA,QACA,eAAe,CAAC,CAACsB,EAAc,UAAU,CAAC,CAACI;AAAA,QAC3C,WAAAU;AAAA,QACA,QAAA/B;AAAA,QACC,GAAGW;AAAA,QAEJ,UAAA,gBAAA+C;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAKhC;AAAA,YACL,IAAAhB;AAAA,YACA,WAAW2C;AAAA,YACX,UAAUzE,IAAW,SAAY;AAAA,YACjC,MAAK;AAAA,YACL,iBAAc;AAAA,YACd,iBAAegC;AAAA,YACf,iBAAehC,KAAY;AAAA,YAC3B,cAAY6B;AAAA,YACZ,aAAa7B,KAAYC,IAAW,SAAYoD;AAAA,YAChD,SAAAG;AAAA,YACA,WAAAC;AAAA,YACA,eAAY;AAAA,YAEZ,UAAA;AAAA,cAAA,gBAAAqB,EAAC,QAAA,EAAK,WAAU,qCAAoC,KAAK9B,GACtD,UAAA;AAAA,gBAAAwB,KAAiB,gBAAApF,EAAC,QAAA,EAAK,WAAU,6BAA6B,UAAAoF,GAAc;AAAA,gBAC5EhE,KAAU,OAAOA,KAAW,aAAa,CAACP,KACzC,gBAAA6E,EAAC,QAAA,EAAK,WAAU,6BACd,UAAA;AAAA,kBAAA,gBAAA1F,EAAC,QAAA,EAAK,WAAU,kCAAkC,UAAAqD,GAAY;AAAA,kBAC9D,gBAAArD;AAAA,oBAAC;AAAA,oBAAA;AAAA,sBACC,WAAU;AAAA,sBACV,KAAK6D;AAAA,sBACL,MAAK;AAAA,sBACL,OAAOR;AAAA,sBACP,UAAU0B;AAAA,sBACV,aAAa,CAAC3E,MAA8C;AAC1D,wBAAAA,EAAM,gBAAA,GACNyC,EAAU,EAAI;AAAA,sBAChB;AAAA,sBACA,WAAW,CAACzC,MAAU;AACpB,wBAAAA,EAAM,gBAAA;AAAA,sBACR;AAAA,sBACA,eAAY;AAAA,oBAAA;AAAA,kBAAA;AAAA,gBACd,EAAA,CACF;AAAA,cAAA,GAEJ;AAAA,cACA,gBAAAsF,EAAC,QAAA,EAAK,WAAU,8BACX,UAAA;AAAA,iBAAA,MAAM,QAAQ5B,CAAK,KAAKA,EAAM,SAAS,KAAO1B,MAAaa,EAAc,SAAS,MAAO,CAACrC,KAC3F,gBAAAZ;AAAA,kBAACE;AAAA,kBAAA;AAAA,oBACC,SAASiF;AAAA,oBACT,aAAahF;AAAA,oBACb,WAAWmF,EAAG,2BAA2B,gCAAgC;AAAA,oBACzE,cAAW;AAAA,oBACX,MAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAGRrD;AAAA,gBACA,CAACC,MACA,gBAAAlC;AAAA,kBAACF;AAAA,kBAAA;AAAA,oBACC,WAAWwF,EAAG,2BAA2B,kCAAkC;AAAA,sBACzE,mCAAmC1C;AAAA,sBACnC,oCAAoCmB;AAAA,sBACpC,kCAAkCxC;AAAA,oBAAA,CACnC;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACH,EAAA,CAEJ;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,IAEF,gBAAAvB;AAAA,MAAC6F;AAAA,MAAA;AAAA,QACC,kBAAApC;AAAA,QACA,eAAAzC;AAAA,QACA,gBAAAC;AAAA,QACA,QAAQG,MAAW;AAAA,QACnB,qBAAA2D;AAAA,QACA,gBAAA5C;AAAA,QACA,OACEN,IACIL,IACA6B,IACE7B,EAAM,OAAO,CAACsD,MAAOA,EAAG,KAAK,OAAO,IAAI,OAAOzB,GAAa,GAAG,CAAC,MAAM,EAAE,IACxE7B;AAAA,QAER,aAAA6B;AAAA,QACA,QAAAT;AAAA,QACA,SAAAuB;AAAA,QACA,aAAAM;AAAA,QACA,OAAAX;AAAA,QACA,WAAA/B;AAAA,QACA,oBAAAb;AAAA,QACA,WAAWC;AAAA,QACX,aAAAoB;AAAA,QACA,YAAAC;AAAA,QACA,cACEH,MAAagB,KAAe,CAAC7B,EAAM,KAAK,CAAC4B,MAAMA,EAAE,KAAK,kBAAkB,OAAOC,CAAW,EAAE,YAAA,CAAa,IACrG;AAAA,UACE,MAAM,YAAYA,CAAW;AAAA,UAC7B,UAAU,CAACjD,MAAgC;AACzC,YAAAkC,KAAA,QAAAA,EAAW,OAAOe,CAAW,GAAGjD,IAChCkD,EAAe,EAAE,GACjBT,EAAU,EAAK;AAAA,UACjB;AAAA,QAAA,IAEF;AAAA,MAAA;AAAA,IAAA;AAAA,EAER,GACF;AAEJ,CAAC;"}
1
+ {"version":3,"file":"selectField.js","sources":["../../../../../src/components/inputs/selectField/selectField.tsx"],"sourcesContent":["import type { HTMLAttributes, SyntheticEvent } from \"react\";\nimport React, { useState, useRef, useEffect, useMemo, forwardRef } from \"react\";\nimport cn from \"clsx\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport { DropdownMenu, DropdownItem, DropdownItemProps } from \"./dropdownMenu\";\nimport Chip from \"../../dataDisplay/chip/chip\";\nimport { TextFieldWrapper } from \"../textField\";\nimport Icon from \"../../base/icon/icon\";\nimport { MenuItemProps } from \"../../navigation/menu\";\n\nconst SelectArrowIcon = (props: HTMLAttributes<HTMLSpanElement>) => <Icon name=\"arrow_drop_down\" {...props} />;\n\nconst ClearIcon = (props: HTMLAttributes<HTMLSpanElement>) => <Icon name=\"close\" size={20} {...props} />;\n\nfunction stopEvent(event: React.SyntheticEvent) {\n event.preventDefault();\n event.stopPropagation();\n}\n\nexport type OnSelectChange = (e: SyntheticEvent, data: SelectFieldProps) => void;\n\nexport interface SelectFieldProps {\n className?: string;\n value?: null | string | number | (string | number | undefined | null)[];\n defaultValue?: null | string | number | (string | number)[];\n onChange?: OnSelectChange;\n disabled?: boolean;\n readOnly?: boolean;\n name?: string;\n multiple?: boolean;\n menuMaxHeight?: number;\n menuMiddleware?: DropdownItemProps[\"menuMiddleware\"];\n menuNoItemsMessage?: React.ReactNode;\n menuContainer?: HTMLElement;\n search?: true | false | \"menu\";\n chips?: boolean;\n isFocused?: boolean;\n error?: boolean;\n items: DropdownItem[];\n label?: string;\n variant?: \"outlined\" | \"filled\";\n fullWidth?: boolean;\n helperText?: React.ReactNode;\n onSearch?: (e: React.ChangeEvent<HTMLInputElement>) => void;\n isLoading?: boolean;\n resetSearch?: () => void;\n inline?: boolean;\n endAdornment?: React.ReactNode;\n hideSelectArrowIcon?: boolean;\n optionRenderer?: (args: MenuItemProps) => React.ReactNode;\n /** Shows a clear button to reset the selection. */\n clearable?: boolean;\n /** Allows creating a new option from the current search text. */\n creatable?: boolean;\n /** Invoked with the typed text when the user creates a new option. */\n onCreate?: (inputValue: string, event: React.SyntheticEvent) => void;\n /** Windows long option lists for performance (fixed row height). */\n virtualized?: boolean;\n /** Row height (px) used when `virtualized`. */\n itemHeight?: number;\n /** Accessible label for the combobox control. */\n \"aria-label\"?: string;\n id?: string;\n}\n\nexport const SelectField = forwardRef<HTMLSpanElement, SelectFieldProps>(function SelectField(props, ref) {\n const {\n className,\n value: valueProp,\n defaultValue,\n onChange,\n disabled,\n readOnly,\n name,\n multiple,\n menuMaxHeight,\n menuMiddleware,\n menuNoItemsMessage,\n menuContainer,\n search,\n chips,\n isFocused: isFocusedProp,\n error,\n items,\n label,\n variant = \"outlined\",\n fullWidth,\n helperText,\n onSearch,\n resetSearch,\n isLoading,\n inline,\n endAdornment,\n hideSelectArrowIcon,\n optionRenderer,\n clearable,\n creatable,\n onCreate,\n virtualized,\n itemHeight,\n \"aria-label\": ariaLabel,\n id,\n ...rest\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(false);\n const [valueState, setValueState] = useState<typeof valueProp>(defaultValue);\n const [selectedItems, setSelectedItems] = useState<typeof items>(() => {\n // Seed from the effective initial value so an uncontrolled `defaultValue`\n // shows its selection (and floats the label) before any interaction.\n const initialValue = valueProp != null ? valueProp : defaultValue;\n\n if (Array.isArray(initialValue)) {\n return items.filter((item) => initialValue.includes(item.value));\n }\n\n const item = initialValue == null ? undefined : items.find((i) => i.value === initialValue);\n\n return item ? [item] : [];\n });\n const [searchValue, setSearchValue] = useState(\"\");\n const { current: isControlled } = useRef(valueProp != null);\n const anchorElementRef = useRef<HTMLSpanElement>(null);\n const forkedAnchorRef = useForkRef<HTMLSpanElement>(ref, anchorElementRef);\n const searchWrapperRef = useRef<HTMLSpanElement>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const value = isControlled ? valueProp : valueState;\n\n const isFocused = useMemo(() => isFocusedProp || isOpen, [isFocusedProp, isOpen]);\n\n const onMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n // Только для левой клавиши мышки.\n if (event.button !== 0) {\n return;\n }\n event.preventDefault();\n anchorElementRef.current?.focus();\n setIsOpen(!isOpen);\n };\n\n const onClose = () => {\n setIsOpen(false);\n anchorElementRef.current?.focus();\n };\n\n const onFocus = () => {\n if (search === true) {\n searchInputRef.current?.focus();\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (!readOnly) {\n const validKeys = [\" \", \"ArrowUp\", \"ArrowDown\", \"Enter\"];\n\n if (validKeys.includes(event.key)) {\n event.preventDefault();\n setIsOpen(!isOpen);\n }\n }\n };\n\n useEffect(() => {\n if (!isFocused || (search === \"menu\" && !isOpen)) {\n setSearchValue(\"\");\n resetSearch?.();\n }\n }, [isFocused, search, isOpen, resetSearch]);\n\n // Keep the displayed selection in sync with the effective value (controlled\n // `value` or uncontrolled `defaultValue`/internal state), so the label floats\n // whenever there is a value — including the initial default, without focus.\n useEffect(() => {\n if (Array.isArray(value)) {\n setSelectedItems(items.filter((item) => value.includes(item.value)));\n } else if (value == null || value === \"\") {\n setSelectedItems([]);\n } else {\n const item = items.find((item) => item.value === value);\n setSelectedItems(item ? [item] : []);\n }\n }, [value, items]);\n\n useSafeLayoutEffect(() => {\n if (searchWrapperRef.current) {\n searchWrapperRef.current.scrollLeft = searchWrapperRef.current.scrollWidth;\n }\n }, [value]);\n\n const updateValue = (event: React.SyntheticEvent, value: typeof valueProp) => {\n onChange?.(event, { ...props, value, name: name || undefined });\n setValueState(value);\n };\n\n const onItemClick = (event: React.SyntheticEvent, item: DropdownItem) => {\n let newValue: typeof valueProp;\n let newSelectedItem: typeof selectedItems;\n if (multiple) {\n const valueArray = Array.isArray(value) ? value : [value].filter(Boolean);\n newValue = valueArray.slice();\n newSelectedItem = selectedItems.slice();\n const itemIndex = valueArray.findIndex((el) => el === item.value);\n\n if (itemIndex === -1) {\n newValue.push(item.value);\n newSelectedItem.push(item);\n } else {\n newValue.splice(itemIndex, 1);\n newSelectedItem.splice(itemIndex, 1);\n }\n } else {\n newValue = value === item.value ? \"\" : item.value;\n newSelectedItem = [item];\n }\n\n if (searchValue) {\n setSearchValue(\"\");\n }\n\n if (!multiple) {\n setIsOpen(false);\n anchorElementRef.current?.focus();\n }\n setSelectedItems(newSelectedItem);\n updateValue(event, newValue);\n };\n\n const onSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n setSearchValue(event.target.value);\n onSearch?.(event);\n if (!isOpen) {\n setIsOpen(true);\n }\n };\n\n const onDeleteChip = (currentValue: typeof valueProp) => (event: React.SyntheticEvent) => {\n if (Array.isArray(value)) {\n const newValue = value.filter((value) => currentValue !== value);\n updateValue(event, newValue);\n const newSelectedItems = selectedItems.filter((el) => el.value !== currentValue);\n setSelectedItems(newSelectedItems);\n }\n };\n\n const onResetSelected = (event: React.MouseEvent) => {\n updateValue(event, []);\n setSelectedItems([]);\n };\n\n let displayValues: string | React.ReactNode[];\n\n const classes = cn(\"smwb-select-field\", className, {\n \"smwb-select-field--filled\": variant === \"filled\" && label,\n \"smwb-select-field--disabled\": disabled,\n \"smwb-select-field--search\": search,\n \"smwb-select-field--inline\": inline,\n });\n\n if (chips) {\n displayValues = selectedItems.map(({ key, value, text }) => (\n <Chip key={key || value} label={text} onDelete={onDeleteChip(value)} onDeleteMouseDown={stopEvent} />\n ));\n } else {\n displayValues = selectedItems.map((el) => el.text).join(\", \");\n }\n\n return (\n <>\n <TextFieldWrapper\n label={label}\n helperText={helperText}\n variant={variant}\n disabled={disabled}\n className={className}\n error={error}\n fullWidth={fullWidth}\n isFilledState={!!selectedItems.length || !!searchValue}\n isFocused={isFocused}\n inline={inline}\n {...rest}\n >\n <span\n ref={forkedAnchorRef}\n id={id}\n className={classes}\n tabIndex={disabled ? undefined : 0}\n role=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-disabled={disabled || undefined}\n aria-label={ariaLabel}\n onMouseDown={disabled || readOnly ? undefined : onMouseDown}\n onFocus={onFocus}\n onKeyDown={onKeyDown}\n data-testid=\"select-field\"\n >\n <span className=\"smwb-select-field__search-wrapper\" ref={searchWrapperRef}>\n {displayValues && <span className=\"smwb-select-field__values\">{displayValues}</span>}\n {search && typeof search === \"boolean\" && !readOnly && (\n <span className=\"smwb-select-field__search\">\n <span className=\"smwb-select-field__search-text\">{searchValue}</span>\n <input\n className=\"smwb-select-field__search-input\"\n ref={searchInputRef}\n type=\"text\"\n value={searchValue}\n onChange={onSearchInputChange}\n onMouseDown={(event: React.MouseEvent<HTMLInputElement>) => {\n event.stopPropagation();\n setIsOpen(true);\n }}\n onKeyDown={(event) => {\n event.stopPropagation();\n }}\n data-testid=\"search-input\"\n />\n </span>\n )}\n </span>\n <span className=\"smwb-select-field__actions\">\n {((Array.isArray(value) && value.length > 0) || (clearable && selectedItems.length > 0)) && !disabled && (\n <ClearIcon\n onClick={onResetSelected}\n onMouseDown={stopEvent}\n className={cn(\"smwb-select-field__icon\", \"smwb-select-field__icon--close\")}\n aria-label=\"Clear selection\"\n role=\"button\"\n />\n )}\n {endAdornment}\n {!hideSelectArrowIcon && (\n <SelectArrowIcon\n className={cn(\"smwb-select-field__icon\", \"smwb-select-field__icon--arrow\", {\n \"smwb-select-field__icon--opened\": isOpen,\n \"smwb-select-field__icon--focused\": isFocused,\n \"smwb-select-field__icon--error\": error,\n })}\n />\n )}\n </span>\n </span>\n </TextFieldWrapper>\n <DropdownMenu\n anchorElementRef={anchorElementRef}\n menuMaxHeight={menuMaxHeight}\n menuMiddleware={menuMiddleware}\n search={search === \"menu\"}\n onSearchInputChange={onSearchInputChange}\n optionRenderer={optionRenderer}\n items={\n onSearch\n ? items\n : searchValue\n ? items.filter((el) => el.text.search(new RegExp(searchValue, \"i\")) !== -1)\n : items\n }\n searchValue={searchValue}\n isOpen={isOpen}\n onClose={onClose}\n onItemClick={onItemClick}\n value={value}\n isLoading={isLoading}\n menuNoItemsMessage={menuNoItemsMessage}\n container={menuContainer}\n virtualized={virtualized}\n itemHeight={itemHeight}\n createOption={\n creatable && searchValue && !items.some((i) => i.text.toLowerCase() === String(searchValue).toLowerCase())\n ? {\n text: `Создать \"${searchValue}\"`,\n onCreate: (event: React.SyntheticEvent) => {\n onCreate?.(String(searchValue), event);\n setSearchValue(\"\");\n setIsOpen(false);\n },\n }\n : undefined\n }\n />\n </>\n );\n});\n\nexport default SelectField;\n"],"names":["SelectArrowIcon","props","jsx","Icon","ClearIcon","stopEvent","event","SelectField","forwardRef","ref","className","valueProp","defaultValue","onChange","disabled","readOnly","name","multiple","menuMaxHeight","menuMiddleware","menuNoItemsMessage","menuContainer","search","chips","isFocusedProp","error","items","label","variant","fullWidth","helperText","onSearch","resetSearch","isLoading","inline","endAdornment","hideSelectArrowIcon","optionRenderer","clearable","creatable","onCreate","virtualized","itemHeight","ariaLabel","id","rest","isOpen","setIsOpen","useState","valueState","setValueState","selectedItems","setSelectedItems","initialValue","item","i","searchValue","setSearchValue","isControlled","useRef","anchorElementRef","forkedAnchorRef","useForkRef","searchWrapperRef","searchInputRef","value","isFocused","useMemo","onMouseDown","_a","onClose","onFocus","onKeyDown","useEffect","useSafeLayoutEffect","updateValue","onItemClick","newValue","newSelectedItem","valueArray","itemIndex","el","onSearchInputChange","onDeleteChip","currentValue","newSelectedItems","onResetSelected","displayValues","classes","cn","key","text","Chip","jsxs","Fragment","TextFieldWrapper","DropdownMenu"],"mappings":"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"}
@@ -1,88 +1,79 @@
1
- import { jsxs as I, jsx as h } from "react/jsx-runtime";
2
- import { forwardRef as j, useRef as P, useState as y, useEffect as b, Children as X, useMemo as Y, useCallback as O } from "react";
1
+ import { jsxs as B, jsx as w } from "react/jsx-runtime";
2
+ import { forwardRef as C, useRef as O, useState as y, useEffect as b, Children as P, useMemo as U, useCallback as W } from "react";
3
3
  import D from "clsx";
4
- import { throttle as T } from "../../../utils/throttle.js";
5
- import { useForkRef as U } from "../../../hooks/useForkRef.js";
6
- const _ = (o, d) => d * (o / 100), x = (o, d) => !o && d ? 100 - d : o || 50, Q = j(function({
4
+ import { throttle as X } from "../../../utils/throttle.js";
5
+ import { useForkRef as Y } from "../../../hooks/useForkRef.js";
6
+ const x = (c, d) => !c && d ? 100 - d : c || 50, V = C(function({
7
7
  className: d,
8
8
  orientation: e = "horizontal",
9
- sizeFirst: m,
9
+ sizeFirst: f,
10
10
  sizeSecond: v,
11
- children: $,
12
- onSizeChange: a,
11
+ children: L,
12
+ onSizeChange: i,
13
13
  keyboardStep: g = 5,
14
- resizerAriaLabel: k = "Resize panels"
15
- }, A) {
16
- const p = P(null), M = U(A, p), [i, l] = y(x(m, v)), [E, L] = y(null), [f, R] = y(!1);
14
+ resizerAriaLabel: $ = "Resize panels"
15
+ }, k) {
16
+ const p = O(null), A = Y(k, p), [t, n] = y(x(f, v)), [E, R] = y(null), [m, _] = y(!1);
17
17
  b(() => {
18
- l(x(m, v));
19
- }, [m, v]);
20
- const w = X.toArray($);
21
- if (w.length > 2)
18
+ n(x(f, v));
19
+ }, [f, v]);
20
+ const h = P.toArray(L);
21
+ if (h.length > 2)
22
22
  throw new Error("Allowed not more than 2 children");
23
- const K = () => {
24
- L(p.current), R(!0);
25
- }, c = Y(
26
- () => T((r) => {
27
- if (!f) return;
28
- const n = p.current;
29
- if (!(!n || n !== E))
30
- if (e === "vertical") {
31
- let s = r.clientY - n.offsetTop;
32
- s < 0 && (s = 0);
33
- const t = s / n.clientHeight * 100;
34
- _(t, n.clientWidth) > 5 && t < 101 && l(t - 7);
35
- } else {
36
- let s = r.clientX - n.offsetLeft;
37
- s < 0 && (s = 0);
38
- const t = s / n.clientWidth * 100;
39
- _(t, n.clientWidth) > 5 && t < 101 && l(t);
40
- }
23
+ const M = () => {
24
+ R(p.current), _(!0);
25
+ }, o = U(
26
+ () => X((r) => {
27
+ if (!m) return;
28
+ const a = p.current;
29
+ if (!a || a !== E) return;
30
+ const s = a.getBoundingClientRect(), l = e === "vertical" ? s.height : s.width, j = e === "vertical" ? r.clientY - s.top : r.clientX - s.left, H = Math.max(5, Math.min(l - 5, j));
31
+ n(H / l * 100);
41
32
  }, 1e3 / 60),
42
- [f, E, e]
43
- ), u = O(() => {
44
- L(null), R(!1), document.body.removeEventListener("pointerup", u), document.body.removeEventListener("pointermove", c);
45
- }, [c]);
33
+ [m, E, e]
34
+ ), u = W(() => {
35
+ R(null), _(!1), document.body.removeEventListener("pointerup", u), document.body.removeEventListener("pointermove", o);
36
+ }, [o]);
46
37
  b(() => {
47
- a == null || a(i);
48
- }, [i, a]);
49
- const N = (r) => {
50
- const n = e === "vertical" ? "ArrowUp" : "ArrowLeft", s = e === "vertical" ? "ArrowDown" : "ArrowRight";
51
- r.key === n ? (r.preventDefault(), l((t) => Math.max(0, t - g))) : r.key === s ? (r.preventDefault(), l((t) => Math.min(100, t + g))) : r.key === "Home" ? (r.preventDefault(), l(0)) : r.key === "End" && (r.preventDefault(), l(100));
52
- }, W = e === "vertical" ? { height: `${100 - i}%` } : { width: `${100 - i}%` }, H = e === "vertical" ? { height: `${i}%` } : { width: `${i}%` };
53
- return b(() => (f ? (document.body.addEventListener("pointerup", u), document.body.addEventListener("pointermove", c), document.body.style.cursor = e === "horizontal" ? "e-resize" : "n-resize") : document.body.style.cursor = "default", () => {
54
- document.body.removeEventListener("pointerup", u), document.body.removeEventListener("pointermove", c);
55
- }), [c, u, f, e]), /* @__PURE__ */ I(
38
+ i == null || i(t);
39
+ }, [t, i]);
40
+ const K = (r) => {
41
+ const a = e === "vertical" ? "ArrowUp" : "ArrowLeft", s = e === "vertical" ? "ArrowDown" : "ArrowRight";
42
+ r.key === a ? (r.preventDefault(), n((l) => Math.max(0, l - g))) : r.key === s ? (r.preventDefault(), n((l) => Math.min(100, l + g))) : r.key === "Home" ? (r.preventDefault(), n(0)) : r.key === "End" && (r.preventDefault(), n(100));
43
+ }, N = e === "vertical" ? { height: `${100 - t}%` } : { width: `${100 - t}%` }, I = e === "vertical" ? { height: `${t}%` } : { width: `${t}%` };
44
+ return b(() => (m ? (document.body.addEventListener("pointerup", u), document.body.addEventListener("pointermove", o), document.body.style.cursor = e === "horizontal" ? "e-resize" : "n-resize") : document.body.style.cursor = "default", () => {
45
+ document.body.removeEventListener("pointerup", u), document.body.removeEventListener("pointermove", o);
46
+ }), [o, u, m, e]), /* @__PURE__ */ B(
56
47
  "div",
57
48
  {
58
49
  className: D("smwb-screen-divider__wrapper", `smwb-${e}`, d),
59
- ref: M,
50
+ ref: A,
60
51
  "data-testid": "screen-divider",
61
52
  children: [
62
- /* @__PURE__ */ h("div", { className: D("smwb-screen-divider__first", `smwb-${e}`), style: H, children: w[0] || "" }),
63
- /* @__PURE__ */ h(
53
+ /* @__PURE__ */ w("div", { className: D("smwb-screen-divider__first", `smwb-${e}`), style: I, children: h[0] || "" }),
54
+ /* @__PURE__ */ w(
64
55
  "span",
65
56
  {
66
57
  className: "smwb-screen-divider__resizer",
67
- onPointerDown: K,
58
+ onPointerDown: M,
68
59
  draggable: !1,
69
60
  role: "separator",
70
61
  "aria-orientation": e === "vertical" ? "horizontal" : "vertical",
71
- "aria-valuenow": Math.round(i),
62
+ "aria-valuenow": Math.round(t),
72
63
  "aria-valuemin": 0,
73
64
  "aria-valuemax": 100,
74
- "aria-label": k,
65
+ "aria-label": $,
75
66
  tabIndex: 0,
76
- onKeyDown: N
67
+ onKeyDown: K
77
68
  }
78
69
  ),
79
- /* @__PURE__ */ h("div", { className: D("smwb-screen-divider__second", `smwb-${e}`), style: W, children: w[1] || "" })
70
+ /* @__PURE__ */ w("div", { className: D("smwb-screen-divider__second", `smwb-${e}`), style: N, children: h[1] || "" })
80
71
  ]
81
72
  }
82
73
  );
83
74
  });
84
75
  export {
85
- Q as ScreenDivider,
86
- Q as default
76
+ V as ScreenDivider,
77
+ V as default
87
78
  };
88
79
  //# sourceMappingURL=screenDivider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenDivider.js","sources":["../../../../../src/components/layout/screenDivider/screenDivider.tsx"],"sourcesContent":["import React, {\n Children,\n forwardRef,\n KeyboardEvent,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport cn from \"clsx\";\nimport { throttle } from \"../../../utils/throttle\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\n\nexport interface ScreenDividerProps {\n sizeFirst?: number;\n sizeSecond?: number;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n /** Called with the first pane size (percent) whenever it changes. */\n onSizeChange?: (sizeFirst: number) => void;\n /** Step (in percent) applied on arrow-key resize. */\n keyboardStep?: number;\n /** Accessible label for the resizer handle. */\n resizerAriaLabel?: string;\n}\n\nconst toPixels = (percent: number, parentSize: number) => {\n return parentSize * (percent / 100);\n};\n\nconst getInitialDivider = (sizeFirst?: number | null, sizeSecond?: number | null) => {\n if (!sizeFirst && sizeSecond) {\n return 100 - sizeSecond;\n }\n if (sizeFirst) {\n return sizeFirst;\n }\n return 50;\n};\n\nexport const ScreenDivider = forwardRef<HTMLDivElement, PropsWithChildren<ScreenDividerProps>>(function ScreenDivider(\n {\n className,\n orientation = \"horizontal\",\n sizeFirst,\n sizeSecond,\n children,\n onSizeChange,\n keyboardStep = 5,\n resizerAriaLabel = \"Resize panels\",\n },\n ref\n) {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const forkedWrapperRef = useForkRef<HTMLDivElement>(ref, wrapperRef);\n const [divider, setDivider] = useState<number>(getInitialDivider(sizeFirst, sizeSecond));\n const [currentElement, setCurrentElement] = useState<HTMLDivElement | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n useEffect(() => {\n setDivider(getInitialDivider(sizeFirst, sizeSecond));\n }, [sizeFirst, sizeSecond]);\n\n const child = Children.toArray(children);\n if (child.length > 2) {\n throw new Error(\"Allowed not more than 2 children\");\n }\n\n const handleDragStart = () => {\n setCurrentElement(wrapperRef.current);\n setIsDragging(true);\n };\n\n const dragOverHandler = useMemo(\n () =>\n throttle((e: PointerEvent) => {\n if (!isDragging) return;\n\n const wrapper = wrapperRef.current;\n if (!wrapper || wrapper !== currentElement) return;\n if (orientation === \"vertical\") {\n let relativeMouseY = e.clientY - wrapper.offsetTop;\n if (relativeMouseY < 0) {\n relativeMouseY = 0;\n }\n const newDivider = (relativeMouseY / wrapper.clientHeight) * 100;\n if (toPixels(newDivider, wrapper.clientWidth) > 5 && newDivider < 101) {\n setDivider(newDivider - 7);\n }\n } else {\n let relativeMouseX = e.clientX - wrapper.offsetLeft;\n if (relativeMouseX < 0) {\n relativeMouseX = 0;\n }\n const newDivider = (relativeMouseX / wrapper.clientWidth) * 100;\n if (toPixels(newDivider, wrapper.clientWidth) > 5 && newDivider < 101) {\n setDivider(newDivider);\n }\n }\n }, 1000 / 60),\n [isDragging, currentElement, orientation]\n );\n\n const handleDragEnd = useCallback(() => {\n setCurrentElement(null);\n setIsDragging(false);\n document.body.removeEventListener(\"pointerup\", handleDragEnd);\n document.body.removeEventListener(\"pointermove\", dragOverHandler);\n }, [dragOverHandler]);\n\n useEffect(() => {\n onSizeChange?.(divider);\n }, [divider, onSizeChange]);\n\n const onResizerKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n const decreaseKey = orientation === \"vertical\" ? \"ArrowUp\" : \"ArrowLeft\";\n const increaseKey = orientation === \"vertical\" ? \"ArrowDown\" : \"ArrowRight\";\n\n if (event.key === decreaseKey) {\n event.preventDefault();\n setDivider((prev) => Math.max(0, prev - keyboardStep));\n } else if (event.key === increaseKey) {\n event.preventDefault();\n setDivider((prev) => Math.min(100, prev + keyboardStep));\n } else if (event.key === \"Home\") {\n event.preventDefault();\n setDivider(0);\n } else if (event.key === \"End\") {\n event.preventDefault();\n setDivider(100);\n }\n };\n\n const secondChildStyle =\n orientation === \"vertical\" ? { height: `${100 - divider}%` } : { width: `${100 - divider}%` };\n\n const firstChildStyle = orientation === \"vertical\" ? { height: `${divider}%` } : { width: `${divider}%` };\n\n useEffect(() => {\n if (isDragging) {\n document.body.addEventListener(\"pointerup\", handleDragEnd);\n document.body.addEventListener(\"pointermove\", dragOverHandler);\n document.body.style.cursor = orientation === \"horizontal\" ? \"e-resize\" : \"n-resize\";\n } else {\n document.body.style.cursor = \"default\";\n }\n\n return () => {\n document.body.removeEventListener(\"pointerup\", handleDragEnd);\n document.body.removeEventListener(\"pointermove\", dragOverHandler);\n };\n }, [dragOverHandler, handleDragEnd, isDragging, orientation]);\n\n return (\n <div\n className={cn(\"smwb-screen-divider__wrapper\", `smwb-${orientation}`, className)}\n ref={forkedWrapperRef}\n data-testid=\"screen-divider\"\n >\n <div className={cn(\"smwb-screen-divider__first\", `smwb-${orientation}`)} style={firstChildStyle}>\n {child[0] || \"\"}\n </div>\n <span\n className=\"smwb-screen-divider__resizer\"\n onPointerDown={handleDragStart}\n draggable={false}\n role=\"separator\"\n aria-orientation={orientation === \"vertical\" ? \"horizontal\" : \"vertical\"}\n aria-valuenow={Math.round(divider)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={resizerAriaLabel}\n tabIndex={0}\n onKeyDown={onResizerKeyDown}\n />\n <div className={cn(\"smwb-screen-divider__second\", `smwb-${orientation}`)} style={secondChildStyle}>\n {child[1] || \"\"}\n </div>\n </div>\n );\n});\n\nexport default ScreenDivider;\n"],"names":["toPixels","percent","parentSize","getInitialDivider","sizeFirst","sizeSecond","ScreenDivider","forwardRef","className","orientation","children","onSizeChange","keyboardStep","resizerAriaLabel","ref","wrapperRef","useRef","forkedWrapperRef","useForkRef","divider","setDivider","useState","currentElement","setCurrentElement","isDragging","setIsDragging","useEffect","child","Children","handleDragStart","dragOverHandler","useMemo","throttle","e","wrapper","relativeMouseY","newDivider","relativeMouseX","handleDragEnd","useCallback","onResizerKeyDown","event","decreaseKey","increaseKey","prev","secondChildStyle","firstChildStyle","jsxs","cn","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"screenDivider.js","sources":["../../../../../src/components/layout/screenDivider/screenDivider.tsx"],"sourcesContent":["import React, {\n Children,\n forwardRef,\n KeyboardEvent,\n PropsWithChildren,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport cn from \"clsx\";\nimport { throttle } from \"../../../utils/throttle\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\n\nexport interface ScreenDividerProps {\n sizeFirst?: number;\n sizeSecond?: number;\n className?: string;\n orientation?: \"horizontal\" | \"vertical\";\n /** Called with the first pane size (percent) whenever it changes. */\n onSizeChange?: (sizeFirst: number) => void;\n /** Step (in percent) applied on arrow-key resize. */\n keyboardStep?: number;\n /** Accessible label for the resizer handle. */\n resizerAriaLabel?: string;\n}\n\nconst getInitialDivider = (sizeFirst?: number | null, sizeSecond?: number | null) => {\n if (!sizeFirst && sizeSecond) {\n return 100 - sizeSecond;\n }\n if (sizeFirst) {\n return sizeFirst;\n }\n return 50;\n};\n\nexport const ScreenDivider = forwardRef<HTMLDivElement, PropsWithChildren<ScreenDividerProps>>(function ScreenDivider(\n {\n className,\n orientation = \"horizontal\",\n sizeFirst,\n sizeSecond,\n children,\n onSizeChange,\n keyboardStep = 5,\n resizerAriaLabel = \"Resize panels\",\n },\n ref\n) {\n const wrapperRef = useRef<HTMLDivElement>(null);\n const forkedWrapperRef = useForkRef<HTMLDivElement>(ref, wrapperRef);\n const [divider, setDivider] = useState<number>(getInitialDivider(sizeFirst, sizeSecond));\n const [currentElement, setCurrentElement] = useState<HTMLDivElement | null>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n useEffect(() => {\n setDivider(getInitialDivider(sizeFirst, sizeSecond));\n }, [sizeFirst, sizeSecond]);\n\n const child = Children.toArray(children);\n if (child.length > 2) {\n throw new Error(\"Allowed not more than 2 children\");\n }\n\n const handleDragStart = () => {\n setCurrentElement(wrapperRef.current);\n setIsDragging(true);\n };\n\n const dragOverHandler = useMemo(\n () =>\n throttle((e: PointerEvent) => {\n if (!isDragging) return;\n const wrapper = wrapperRef.current;\n if (!wrapper || wrapper !== currentElement) return;\n // Viewport-relative rect — using offsetLeft/offsetTop here is wrong\n // because they are relative to the nearest positioned ancestor, not\n // the viewport that clientX/clientY live in (this is what made the\n // divider drift away from the cursor when the wrapper was nested).\n const rect = wrapper.getBoundingClientRect();\n const total = orientation === \"vertical\" ? rect.height : rect.width;\n const cursor = orientation === \"vertical\" ? e.clientY - rect.top : e.clientX - rect.left;\n // 5px margin on each side so neither pane fully collapses.\n const clamped = Math.max(5, Math.min(total - 5, cursor));\n setDivider((clamped / total) * 100);\n }, 1000 / 60),\n [isDragging, currentElement, orientation]\n );\n\n const handleDragEnd = useCallback(() => {\n setCurrentElement(null);\n setIsDragging(false);\n document.body.removeEventListener(\"pointerup\", handleDragEnd);\n document.body.removeEventListener(\"pointermove\", dragOverHandler);\n }, [dragOverHandler]);\n\n useEffect(() => {\n onSizeChange?.(divider);\n }, [divider, onSizeChange]);\n\n const onResizerKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {\n const decreaseKey = orientation === \"vertical\" ? \"ArrowUp\" : \"ArrowLeft\";\n const increaseKey = orientation === \"vertical\" ? \"ArrowDown\" : \"ArrowRight\";\n\n if (event.key === decreaseKey) {\n event.preventDefault();\n setDivider((prev) => Math.max(0, prev - keyboardStep));\n } else if (event.key === increaseKey) {\n event.preventDefault();\n setDivider((prev) => Math.min(100, prev + keyboardStep));\n } else if (event.key === \"Home\") {\n event.preventDefault();\n setDivider(0);\n } else if (event.key === \"End\") {\n event.preventDefault();\n setDivider(100);\n }\n };\n\n const secondChildStyle =\n orientation === \"vertical\" ? { height: `${100 - divider}%` } : { width: `${100 - divider}%` };\n\n const firstChildStyle = orientation === \"vertical\" ? { height: `${divider}%` } : { width: `${divider}%` };\n\n useEffect(() => {\n if (isDragging) {\n document.body.addEventListener(\"pointerup\", handleDragEnd);\n document.body.addEventListener(\"pointermove\", dragOverHandler);\n document.body.style.cursor = orientation === \"horizontal\" ? \"e-resize\" : \"n-resize\";\n } else {\n document.body.style.cursor = \"default\";\n }\n\n return () => {\n document.body.removeEventListener(\"pointerup\", handleDragEnd);\n document.body.removeEventListener(\"pointermove\", dragOverHandler);\n };\n }, [dragOverHandler, handleDragEnd, isDragging, orientation]);\n\n return (\n <div\n className={cn(\"smwb-screen-divider__wrapper\", `smwb-${orientation}`, className)}\n ref={forkedWrapperRef}\n data-testid=\"screen-divider\"\n >\n <div className={cn(\"smwb-screen-divider__first\", `smwb-${orientation}`)} style={firstChildStyle}>\n {child[0] || \"\"}\n </div>\n <span\n className=\"smwb-screen-divider__resizer\"\n onPointerDown={handleDragStart}\n draggable={false}\n role=\"separator\"\n aria-orientation={orientation === \"vertical\" ? \"horizontal\" : \"vertical\"}\n aria-valuenow={Math.round(divider)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={resizerAriaLabel}\n tabIndex={0}\n onKeyDown={onResizerKeyDown}\n />\n <div className={cn(\"smwb-screen-divider__second\", `smwb-${orientation}`)} style={secondChildStyle}>\n {child[1] || \"\"}\n </div>\n </div>\n );\n});\n\nexport default ScreenDivider;\n"],"names":["getInitialDivider","sizeFirst","sizeSecond","ScreenDivider","forwardRef","className","orientation","children","onSizeChange","keyboardStep","resizerAriaLabel","ref","wrapperRef","useRef","forkedWrapperRef","useForkRef","divider","setDivider","useState","currentElement","setCurrentElement","isDragging","setIsDragging","useEffect","child","Children","handleDragStart","dragOverHandler","useMemo","throttle","e","wrapper","rect","total","cursor","clamped","handleDragEnd","useCallback","onResizerKeyDown","event","decreaseKey","increaseKey","prev","secondChildStyle","firstChildStyle","jsxs","cn","jsx"],"mappings":"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"}