芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/app.optimyar.com/backend/node_modules/react-select/src/utils.js
// @flow import { type ElementRef } from 'react'; import type { ClassNamesState, CommonProps, InputActionMeta, OptionsType, ValueType, } from './types'; // ============================== // NO OP // ============================== export const noop = () => {}; export const emptyString = () => ''; // ============================== // Class Name Prefixer // ============================== /** String representation of component state for styling with class names. Expects an array of strings OR a string/object pair: - className(['comp', 'comp-arg', 'comp-arg-2']) @returns 'react-select__comp react-select__comp-arg react-select__comp-arg-2' - className('comp', { some: true, state: false }) @returns 'react-select__comp react-select__comp--some' */ function applyPrefixToName(prefix, name) { if (!name) { return prefix; } else if (name[0] === '-') { return prefix + name; } else { return prefix + '__' + name; } } export function classNames( prefix?: string | null, state?: ClassNamesState, className?: string ) { const arr = [className]; if (state && prefix) { for (let key in state) { if (state.hasOwnProperty(key) && state[key]) { arr.push(`${applyPrefixToName(prefix, key)}`); } } } return arr .filter(i => i) .map(i => String(i).trim()) .join(' '); } // ============================== // Clean Value // ============================== export const cleanValue = (value: ValueType): OptionsType => { if (Array.isArray(value)) return value.filter(Boolean); if (typeof value === 'object' && value !== null) return [value]; return []; }; // ============================== // Clean Common Props // ============================== export const cleanCommonProps = (props: CommonProps): any => { //className const { className, // not listed in commonProps documentation, needs to be removed to allow Emotion to generate classNames clearValue, cx, getStyles, getValue, hasValue, isMulti, isRtl, options, // not listed in commonProps documentation selectOption, selectProps, setValue, theme, // not listed in commonProps documentation ...innerProps } = props; return { ...innerProps }; }; // ============================== // Handle Input Change // ============================== export function handleInputChange( inputValue: string, actionMeta: InputActionMeta, onInputChange?: (string, InputActionMeta) => string | void ) { if (onInputChange) { const newValue = onInputChange(inputValue, actionMeta); if (typeof newValue === 'string') return newValue; } return inputValue; } // ============================== // Scroll Helpers // ============================== export function isDocumentElement(el: Element) { return [document.documentElement, document.body, window].indexOf(el) > -1; } // Normalized Scroll Top // ------------------------------ export function normalizedHeight(el: Element): number { if (isDocumentElement(el)) { return window.innerHeight; } return el.clientHeight; } // Normalized scrollTo & scrollTop // ------------------------------ export function getScrollTop(el: Element): number { if (isDocumentElement(el)) { return window.pageYOffset; } return el.scrollTop; } export function scrollTo(el: Element, top: number): void { // with a scroll distance, we perform scroll on the element if (isDocumentElement(el)) { window.scrollTo(0, top); return; } el.scrollTop = top; } // Get Scroll Parent // ------------------------------ export function getScrollParent(element: ElementRef<*>): Element { let style = getComputedStyle(element); const excludeStaticParent = style.position === 'absolute'; const overflowRx = /(auto|scroll)/; const docEl = ((document.documentElement: any): Element); // suck it, flow... if (style.position === 'fixed') return docEl; for (let parent = element; (parent = parent.parentElement); ) { style = getComputedStyle(parent); if (excludeStaticParent && style.position === 'static') { continue; } if (overflowRx.test(style.overflow + style.overflowY + style.overflowX)) { return parent; } } return docEl; } // Animated Scroll To // ------------------------------ /** @param t: time (elapsed) @param b: initial value @param c: amount of change @param d: duration */ function easeOutCubic(t: number, b: number, c: number, d: number): number { return c * ((t = t / d - 1) * t * t + 1) + b; } export function animatedScrollTo( element: Element, to: number, duration: number = 200, callback: Element => void = noop ) { const start = getScrollTop(element); const change = to - start; const increment = 10; let currentTime = 0; function animateScroll() { currentTime += increment; const val = easeOutCubic(currentTime, start, change, duration); scrollTo(element, val); if (currentTime < duration) { window.requestAnimationFrame(animateScroll); } else { callback(element); } } animateScroll(); } // Scroll Into View // ------------------------------ export function scrollIntoView( menuEl: HTMLElement, focusedEl: HTMLElement ): void { const menuRect = menuEl.getBoundingClientRect(); const focusedRect = focusedEl.getBoundingClientRect(); const overScroll = focusedEl.offsetHeight / 3; if (focusedRect.bottom + overScroll > menuRect.bottom) { scrollTo( menuEl, Math.min( focusedEl.offsetTop + focusedEl.clientHeight - menuEl.offsetHeight + overScroll, menuEl.scrollHeight ) ); } else if (focusedRect.top - overScroll < menuRect.top) { scrollTo(menuEl, Math.max(focusedEl.offsetTop - overScroll, 0)); } } // ============================== // Get bounding client object // ============================== // cannot get keys using array notation with DOMRect export function getBoundingClientObj(element: HTMLElement) { const rect = element.getBoundingClientRect(); return { bottom: rect.bottom, height: rect.height, left: rect.left, right: rect.right, top: rect.top, width: rect.width, }; } export type RectType = { left: number, right: number, bottom: number, height: number, width: number, }; // ============================== // String to Key (kebabify) // ============================== export function toKey(str: string): string { return str.replace(/\W/g, '-'); } // ============================== // Touch Capability Detector // ============================== export function isTouchCapable() { try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; } } // ============================== // Mobile Device Detector // ============================== export function isMobileDevice() { try { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ); } catch (e) { return false; } } // ============================== // Passive Event Detector // ============================== // https://github.com/rafgraph/detect-it/blob/main/src/index.ts#L19-L36 let passiveOptionAccessed = false; const options = { get passive() { return (passiveOptionAccessed = true); }, }; // check for SSR const w = typeof window !== 'undefined' ? window : {}; if (w.addEventListener && w.removeEventListener) { w.addEventListener('p', noop, options); w.removeEventListener('p', noop, false); } export const supportsPassiveEvents: boolean = passiveOptionAccessed;