feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,147 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { flattenArray } from './utils';
import { makeViewDescriptorsSet } from '../reanimated2/ViewDescriptorsSet';
import { adaptViewConfig } from '../ConfigHelper';
import updateProps from '../reanimated2/UpdateProps';
import { stopMapper, startMapper } from '../reanimated2/mappers';
import { isSharedValue } from '../reanimated2/isSharedValue';
import { shouldBeUseWeb } from '../reanimated2/PlatformChecker';
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
function isInlineStyleTransform(transform) {
if (!Array.isArray(transform)) {
return false;
}
return transform.some(t => hasInlineStyles(t));
}
function inlinePropsHasChanged(styles1, styles2) {
if (Object.keys(styles1).length !== Object.keys(styles2).length) {
return true;
}
for (const key of Object.keys(styles1)) {
if (styles1[key] !== styles2[key]) return true;
}
return false;
}
function getInlinePropsUpdate(inlineProps) {
'worklet';
const update = {};
for (const [key, styleValue] of Object.entries(inlineProps)) {
if (isSharedValue(styleValue)) {
update[key] = styleValue.value;
} else if (Array.isArray(styleValue)) {
update[key] = styleValue.map(item => {
return getInlinePropsUpdate(item);
});
} else if (typeof styleValue === 'object') {
update[key] = getInlinePropsUpdate(styleValue);
} else {
update[key] = styleValue;
}
}
return update;
}
function extractSharedValuesMapFromProps(props) {
const inlineProps = {};
for (const key in props) {
const value = props[key];
if (key === 'style') {
const styles = flattenArray(props.style ?? []);
styles.forEach(style => {
if (!style) {
return;
}
for (const [styleKey, styleValue] of Object.entries(style)) {
if (isSharedValue(styleValue)) {
inlineProps[styleKey] = styleValue;
} else if (styleKey === 'transform' && isInlineStyleTransform(styleValue)) {
inlineProps[styleKey] = styleValue;
}
}
});
} else if (isSharedValue(value)) {
inlineProps[key] = value;
}
}
return inlineProps;
}
export function hasInlineStyles(style) {
if (!style) {
return false;
}
return Object.keys(style).some(key => {
const styleValue = style[key];
return isSharedValue(styleValue) || key === 'transform' && isInlineStyleTransform(styleValue);
});
}
export function getInlineStyle(style, shouldGetInitialStyle) {
if (shouldGetInitialStyle) {
return getInlinePropsUpdate(style);
}
const newStyle = {};
for (const [key, styleValue] of Object.entries(style)) {
if (!isSharedValue(styleValue) && !(key === 'transform' && isInlineStyleTransform(styleValue))) {
newStyle[key] = styleValue;
}
}
return newStyle;
}
export class InlinePropManager {
constructor() {
_defineProperty(this, "_inlinePropsViewDescriptors", null);
_defineProperty(this, "_inlinePropsMapperId", null);
_defineProperty(this, "_inlineProps", {});
}
attachInlineProps(animatedComponent, viewInfo) {
const newInlineProps = extractSharedValuesMapFromProps(animatedComponent.props);
const hasChanged = inlinePropsHasChanged(newInlineProps, this._inlineProps);
if (hasChanged) {
if (!this._inlinePropsViewDescriptors) {
this._inlinePropsViewDescriptors = makeViewDescriptorsSet();
const {
viewTag,
viewName,
shadowNodeWrapper,
viewConfig
} = viewInfo;
if (Object.keys(newInlineProps).length && viewConfig) {
adaptViewConfig(viewConfig);
}
this._inlinePropsViewDescriptors.add({
tag: viewTag,
name: viewName,
shadowNodeWrapper: shadowNodeWrapper
});
}
const shareableViewDescriptors = this._inlinePropsViewDescriptors.shareableViewDescriptors;
const maybeViewRef = SHOULD_BE_USE_WEB ? {
items: new Set([animatedComponent])
} // see makeViewsRefSet
: undefined;
const updaterFunction = () => {
'worklet';
const update = getInlinePropsUpdate(newInlineProps);
updateProps(shareableViewDescriptors, update, maybeViewRef);
};
this._inlineProps = newInlineProps;
if (this._inlinePropsMapperId) {
stopMapper(this._inlinePropsMapperId);
}
this._inlinePropsMapperId = null;
if (Object.keys(newInlineProps).length) {
this._inlinePropsMapperId = startMapper(updaterFunction, Object.values(newInlineProps));
}
}
}
detachInlineProps() {
if (this._inlinePropsMapperId) {
stopMapper(this._inlinePropsMapperId);
}
}
}
//# sourceMappingURL=InlinePropManager.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,89 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { NativeEventEmitter, Platform, findNodeHandle } from 'react-native';
import { shouldBeUseWeb } from '../reanimated2/PlatformChecker';
import { runOnJS, runOnUIImmediately } from '../reanimated2/threads';
import NativeReanimatedModule from '../specs/NativeReanimatedModule';
const SHOULD_BE_USE_WEB = shouldBeUseWeb();
class JSPropsUpdaterPaper {
constructor() {
_defineProperty(this, "_reanimatedEventEmitter", void 0);
this._reanimatedEventEmitter = new NativeEventEmitter(
// NativeEventEmitter only uses this parameter on iOS.
Platform.OS === 'ios' ? NativeReanimatedModule : undefined);
}
addOnJSPropsChangeListener(animatedComponent) {
const viewTag = findNodeHandle(animatedComponent);
JSPropsUpdaterPaper._tagToComponentMapping.set(viewTag, animatedComponent);
if (JSPropsUpdaterPaper._tagToComponentMapping.size === 1) {
const listener = data => {
const component = JSPropsUpdaterPaper._tagToComponentMapping.get(data.viewTag);
component === null || component === void 0 || component._updateFromNative(data.props);
};
this._reanimatedEventEmitter.addListener('onReanimatedPropsChange', listener);
}
}
removeOnJSPropsChangeListener(animatedComponent) {
const viewTag = findNodeHandle(animatedComponent);
JSPropsUpdaterPaper._tagToComponentMapping.delete(viewTag);
if (JSPropsUpdaterPaper._tagToComponentMapping.size === 0) {
this._reanimatedEventEmitter.removeAllListeners('onReanimatedPropsChange');
}
}
}
_defineProperty(JSPropsUpdaterPaper, "_tagToComponentMapping", new Map());
class JSPropsUpdaterFabric {
constructor() {
if (!JSPropsUpdaterFabric.isInitialized) {
const updater = (viewTag, props) => {
const component = JSPropsUpdaterFabric._tagToComponentMapping.get(viewTag);
component === null || component === void 0 || component._updateFromNative(props);
};
runOnUIImmediately(() => {
'worklet';
global.updateJSProps = (viewTag, props) => {
runOnJS(updater)(viewTag, props);
};
})();
JSPropsUpdaterFabric.isInitialized = true;
}
}
addOnJSPropsChangeListener(animatedComponent) {
if (!JSPropsUpdaterFabric.isInitialized) {
return;
}
const viewTag = findNodeHandle(animatedComponent);
JSPropsUpdaterFabric._tagToComponentMapping.set(viewTag, animatedComponent);
}
removeOnJSPropsChangeListener(animatedComponent) {
if (!JSPropsUpdaterFabric.isInitialized) {
return;
}
const viewTag = findNodeHandle(animatedComponent);
JSPropsUpdaterFabric._tagToComponentMapping.delete(viewTag);
}
}
_defineProperty(JSPropsUpdaterFabric, "_tagToComponentMapping", new Map());
_defineProperty(JSPropsUpdaterFabric, "isInitialized", false);
class JSPropsUpdaterWeb {
addOnJSPropsChangeListener(_animatedComponent) {
// noop
}
removeOnJSPropsChangeListener(_animatedComponent) {
// noop
}
}
let JSPropsUpdater;
if (SHOULD_BE_USE_WEB) {
JSPropsUpdater = JSPropsUpdaterWeb;
} else if (global._IS_FABRIC) {
JSPropsUpdater = JSPropsUpdaterFabric;
} else {
JSPropsUpdater = JSPropsUpdaterPaper;
}
export default JSPropsUpdater;
//# sourceMappingURL=JSPropsUpdater.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,11 @@
'use strict';
export default class JSPropsUpdaterWeb {
addOnJSPropsChangeListener(_animatedComponent) {
// noop
}
removeOnJSPropsChangeListener(_animatedComponent) {
// noop
}
}
//# sourceMappingURL=JSPropsUpdater.web.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["JSPropsUpdaterWeb","addOnJSPropsChangeListener","_animatedComponent","removeOnJSPropsChangeListener"],"sources":["JSPropsUpdater.web.ts"],"sourcesContent":["'use strict';\nimport type {\n AnimatedComponentProps,\n IAnimatedComponentInternal,\n InitialComponentProps,\n} from './commonTypes';\n\nexport default class JSPropsUpdaterWeb {\n public addOnJSPropsChangeListener(\n _animatedComponent: React.Component<\n AnimatedComponentProps<InitialComponentProps>\n > &\n IAnimatedComponentInternal\n ) {\n // noop\n }\n\n public removeOnJSPropsChangeListener(\n _animatedComponent: React.Component<\n AnimatedComponentProps<InitialComponentProps>\n > &\n IAnimatedComponentInternal\n ) {\n // noop\n }\n}\n"],"mappings":"AAAA,YAAY;;AAOZ,eAAe,MAAMA,iBAAiB,CAAC;EAC9BC,0BAA0BA,CAC/BC,kBAG4B,EAC5B;IACA;EAAA;EAGKC,6BAA6BA,CAClCD,kBAG4B,EAC5B;IACA;EAAA;AAEJ","ignoreList":[]}

View File

@@ -0,0 +1,93 @@
'use strict';
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import { shallowEqual } from '../reanimated2/hook/utils';
import { isSharedValue } from '../reanimated2/isSharedValue';
import { isChromeDebugger } from '../reanimated2/PlatformChecker';
import { WorkletEventHandler } from '../reanimated2/WorkletEventHandler';
import { initialUpdaterRun } from '../reanimated2/animation';
import { hasInlineStyles, getInlineStyle } from './InlinePropManager';
import { flattenArray, has } from './utils';
import { StyleSheet } from 'react-native';
function dummyListener() {
// empty listener we use to assign to listener properties for which animated
// event is used.
}
export class PropsFilter {
constructor() {
_defineProperty(this, "_initialStyle", {});
_defineProperty(this, "_previousProps", null);
_defineProperty(this, "_requiresNewInitials", true);
}
filterNonAnimatedProps(component) {
const inputProps = component.props;
this._maybePrepareForNewInitials(inputProps);
const props = {};
for (const key in inputProps) {
const value = inputProps[key];
if (key === 'style') {
const styleProp = inputProps.style;
const styles = flattenArray(styleProp ?? []);
if (this._requiresNewInitials) {
this._initialStyle = {};
}
const processedStyle = styles.map(style => {
if (style && style.viewDescriptors) {
var _style$viewsRef;
// this is how we recognize styles returned by useAnimatedStyle
// TODO - refactor, since `viewsRef` is only present on Web
(_style$viewsRef = style.viewsRef) === null || _style$viewsRef === void 0 || _style$viewsRef.add(component);
if (this._requiresNewInitials) {
this._initialStyle = {
...style.initial.value,
...this._initialStyle,
...initialUpdaterRun(style.initial.updater)
};
}
return this._initialStyle;
} else if (hasInlineStyles(style)) {
return getInlineStyle(style, this._requiresNewInitials);
} else {
return style;
}
});
props[key] = StyleSheet.flatten(processedStyle);
} else if (key === 'animatedProps') {
const animatedProp = inputProps.animatedProps;
if (animatedProp.initial !== undefined) {
Object.keys(animatedProp.initial.value).forEach(initialValueKey => {
var _animatedProp$initial, _animatedProp$viewsRe;
props[initialValueKey] = (_animatedProp$initial = animatedProp.initial) === null || _animatedProp$initial === void 0 ? void 0 : _animatedProp$initial.value[initialValueKey];
// TODO - refacotr, since `viewsRef` is only present on Web
(_animatedProp$viewsRe = animatedProp.viewsRef) === null || _animatedProp$viewsRe === void 0 || _animatedProp$viewsRe.add(component);
});
}
} else if (has('workletEventHandler', value) && value.workletEventHandler instanceof WorkletEventHandler) {
if (value.workletEventHandler.eventNames.length > 0) {
value.workletEventHandler.eventNames.forEach(eventName => {
props[eventName] = has('listeners', value.workletEventHandler) ? value.workletEventHandler.listeners[eventName] : dummyListener;
});
} else {
props[key] = dummyListener;
}
} else if (isSharedValue(value)) {
if (this._requiresNewInitials) {
props[key] = value.value;
}
} else if (key !== 'onGestureHandlerStateChange' || !isChromeDebugger()) {
props[key] = value;
}
}
this._requiresNewInitials = false;
return props;
}
_maybePrepareForNewInitials(inputProps) {
if (this._previousProps && inputProps.style) {
this._requiresNewInitials = !shallowEqual(this._previousProps, inputProps);
}
this._previousProps = inputProps;
}
}
//# sourceMappingURL=PropsFilter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
'use strict';
export {};
//# sourceMappingURL=commonTypes.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":[],"sources":["commonTypes.ts"],"sourcesContent":["'use strict';\nimport type { Ref, Component } from 'react';\nimport type {\n StyleProps,\n BaseAnimationBuilder,\n ILayoutAnimationBuilder,\n EntryExitAnimationFunction,\n SharedTransition,\n SharedValue,\n} from '../reanimated2';\nimport type {\n ViewDescriptorsSet,\n ViewRefSet,\n} from '../reanimated2/ViewDescriptorsSet';\nimport type { SkipEnteringContext } from '../reanimated2/component/LayoutAnimationConfig';\nimport type { ShadowNodeWrapper } from '../reanimated2/commonTypes';\nimport type { ViewConfig } from '../ConfigHelper';\n\nexport interface AnimatedProps extends Record<string, unknown> {\n viewDescriptors?: ViewDescriptorsSet;\n viewsRef?: ViewRefSet<unknown>;\n initial?: SharedValue<StyleProps>;\n}\n\nexport interface ViewInfo {\n viewTag: number | HTMLElement | null;\n viewName: string | null;\n shadowNodeWrapper: ShadowNodeWrapper | null;\n viewConfig: ViewConfig;\n}\n\nexport interface IInlinePropManager {\n attachInlineProps(\n animatedComponent: React.Component<unknown, unknown>,\n viewInfo: ViewInfo\n ): void;\n detachInlineProps(): void;\n}\n\nexport interface IPropsFilter {\n filterNonAnimatedProps: (\n component: React.Component<unknown, unknown> & IAnimatedComponentInternal\n ) => Record<string, unknown>;\n}\n\nexport interface IJSPropsUpdater {\n addOnJSPropsChangeListener(\n animatedComponent: React.Component<unknown, unknown> &\n IAnimatedComponentInternal\n ): void;\n removeOnJSPropsChangeListener(\n animatedComponent: React.Component<unknown, unknown> &\n IAnimatedComponentInternal\n ): void;\n}\n\nexport type LayoutAnimationStaticContext = {\n presetName: string;\n};\n\nexport type AnimatedComponentProps<P extends Record<string, unknown>> = P & {\n forwardedRef?: Ref<Component>;\n style?: NestedArray<StyleProps>;\n animatedProps?: Partial<AnimatedComponentProps<AnimatedProps>>;\n animatedStyle?: StyleProps;\n layout?: (\n | BaseAnimationBuilder\n | ILayoutAnimationBuilder\n | typeof BaseAnimationBuilder\n ) &\n LayoutAnimationStaticContext;\n entering?: (\n | BaseAnimationBuilder\n | typeof BaseAnimationBuilder\n | EntryExitAnimationFunction\n | Keyframe\n ) &\n LayoutAnimationStaticContext;\n exiting?: (\n | BaseAnimationBuilder\n | typeof BaseAnimationBuilder\n | EntryExitAnimationFunction\n | Keyframe\n ) &\n LayoutAnimationStaticContext;\n sharedTransitionTag?: string;\n sharedTransitionStyle?: SharedTransition;\n};\n\nexport interface AnimatedComponentRef extends Component {\n setNativeProps?: (props: Record<string, unknown>) => void;\n getScrollableNode?: () => AnimatedComponentRef;\n getAnimatableRef?: () => AnimatedComponentRef;\n}\n\nexport interface IAnimatedComponentInternal {\n _styles: StyleProps[] | null;\n _animatedProps?: Partial<AnimatedComponentProps<AnimatedProps>>;\n _viewTag: number;\n _isFirstRender: boolean;\n jestAnimatedStyle: { value: StyleProps };\n _component: AnimatedComponentRef | HTMLElement | null;\n _sharedElementTransition: SharedTransition | null;\n _jsPropsUpdater: IJSPropsUpdater;\n _InlinePropManager: IInlinePropManager;\n _PropsFilter: IPropsFilter;\n _viewInfo?: ViewInfo;\n context: React.ContextType<typeof SkipEnteringContext>;\n}\n\nexport type NestedArray<T> = T | NestedArray<T>[];\n\nexport interface InitialComponentProps extends Record<string, unknown> {\n ref?: Ref<Component>;\n collapsable?: boolean;\n}\n"],"mappings":"AAAA,YAAY;;AAAC","ignoreList":[]}

View File

@@ -0,0 +1,428 @@
'use strict';
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
import React from 'react';
import { findNodeHandle, Platform } from 'react-native';
import { WorkletEventHandler } from '../reanimated2/WorkletEventHandler';
import '../reanimated2/layoutReanimation/animationsManager';
import invariant from 'invariant';
import { adaptViewConfig } from '../ConfigHelper';
import { RNRenderer } from '../reanimated2/platform-specific/RNRenderer';
import { enableLayoutAnimations } from '../reanimated2/core';
import { SharedTransition, LayoutAnimationType } from '../reanimated2/layoutReanimation';
import { getShadowNodeWrapperFromRef } from '../reanimated2/fabricUtils';
import { removeFromPropsRegistry } from '../reanimated2/PropsRegistry';
import { getReduceMotionFromConfig } from '../reanimated2/animation/util';
import { maybeBuild } from '../animationBuilder';
import { SkipEnteringContext } from '../reanimated2/component/LayoutAnimationConfig';
import JSPropsUpdater from './JSPropsUpdater';
import { has, flattenArray } from './utils';
import setAndForwardRef from './setAndForwardRef';
import { isFabric, isJest, isWeb, shouldBeUseWeb } from '../reanimated2/PlatformChecker';
import { InlinePropManager } from './InlinePropManager';
import { PropsFilter } from './PropsFilter';
import { startWebLayoutAnimation, tryActivateLayoutTransition, configureWebLayoutAnimations, getReducedMotionFromConfig, saveSnapshot } from '../reanimated2/layoutReanimation/web';
import { updateLayoutAnimations } from '../reanimated2/UpdateLayoutAnimations';
import { addHTMLMutationObserver } from '../reanimated2/layoutReanimation/web/domUtils';
import { getViewInfo } from './getViewInfo';
const IS_WEB = isWeb();
if (IS_WEB) {
configureWebLayoutAnimations();
}
function onlyAnimatedStyles(styles) {
return styles.filter(style => style === null || style === void 0 ? void 0 : style.viewDescriptors);
}
/**
* Lets you create an Animated version of any React Native component.
*
* @param component - The component you want to make animatable.
* @returns A component that Reanimated is capable of animating.
* @see https://docs.swmansion.com/react-native-reanimated/docs/core/createAnimatedComponent
*/
// Don't change the order of overloads, since such a change breaks current behavior
/**
* @deprecated Please use `Animated.FlatList` component instead of calling `Animated.createAnimatedComponent(FlatList)` manually.
*/
// @ts-ignore This is required to create this overload, since type of createAnimatedComponent is incorrect and doesn't include typeof FlatList
export function createAnimatedComponent(Component, options) {
invariant(typeof Component !== 'function' || Component.prototype && Component.prototype.isReactComponent, `Looks like you're passing a function component \`${Component.name}\` to \`createAnimatedComponent\` function which supports only class components. Please wrap your function component with \`React.forwardRef()\` or use a class component instead.`);
class AnimatedComponent extends React.Component {
constructor(props) {
super(props);
_defineProperty(this, "_styles", null);
_defineProperty(this, "_animatedProps", void 0);
_defineProperty(this, "_viewTag", -1);
_defineProperty(this, "_isFirstRender", true);
_defineProperty(this, "jestAnimatedStyle", {
value: {}
});
_defineProperty(this, "_component", null);
_defineProperty(this, "_sharedElementTransition", null);
_defineProperty(this, "_jsPropsUpdater", new JSPropsUpdater());
_defineProperty(this, "_InlinePropManager", new InlinePropManager());
_defineProperty(this, "_PropsFilter", new PropsFilter());
_defineProperty(this, "_viewInfo", void 0);
_defineProperty(this, "context", void 0);
_defineProperty(this, "_setComponentRef", setAndForwardRef({
getForwardedRef: () => this.props.forwardedRef,
setLocalRef: ref => {
// TODO update config
const tag = IS_WEB ? ref : findNodeHandle(ref);
this._viewTag = tag;
const {
layout,
entering,
exiting,
sharedTransitionTag
} = this.props;
if ((layout || entering || exiting || sharedTransitionTag) && tag != null) {
var _this$context;
if (!shouldBeUseWeb()) {
enableLayoutAnimations(true, false);
}
if (sharedTransitionTag) {
this._configureSharedTransition();
}
const skipEntering = (_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.current;
if (entering && !skipEntering) {
var _this$props;
updateLayoutAnimations(tag, LayoutAnimationType.ENTERING, maybeBuild(entering, (_this$props = this.props) === null || _this$props === void 0 ? void 0 : _this$props.style, AnimatedComponent.displayName));
}
}
if (ref !== this._component) {
this._component = ref;
}
}
}));
if (isJest()) {
this.jestAnimatedStyle = {
value: {}
};
}
}
componentDidMount() {
this._viewTag = this._getViewInfo().viewTag;
this._attachNativeEvents();
this._jsPropsUpdater.addOnJSPropsChangeListener(this);
this._attachAnimatedStyles();
this._InlinePropManager.attachInlineProps(this, this._getViewInfo());
const layout = this.props.layout;
if (layout) {
this._configureLayoutTransition();
}
if (IS_WEB) {
if (this.props.exiting) {
saveSnapshot(this._component);
}
if (!this.props.entering || getReducedMotionFromConfig(this.props.entering)) {
this._isFirstRender = false;
return;
}
startWebLayoutAnimation(this.props, this._component, LayoutAnimationType.ENTERING);
}
this._isFirstRender = false;
}
componentWillUnmount() {
var _this$_sharedElementT;
this._detachNativeEvents();
this._jsPropsUpdater.removeOnJSPropsChangeListener(this);
this._detachStyles();
this._InlinePropManager.detachInlineProps();
if (this.props.sharedTransitionTag) {
this._configureSharedTransition(true);
}
(_this$_sharedElementT = this._sharedElementTransition) === null || _this$_sharedElementT === void 0 || _this$_sharedElementT.unregisterTransition(this._viewTag, true);
const exiting = this.props.exiting;
if (IS_WEB && this._component && this.props.exiting && !getReducedMotionFromConfig(this.props.exiting)) {
addHTMLMutationObserver();
startWebLayoutAnimation(this.props, this._component, LayoutAnimationType.EXITING);
} else if (exiting) {
const reduceMotionInExiting = 'getReduceMotion' in exiting && typeof exiting.getReduceMotion === 'function' ? getReduceMotionFromConfig(exiting.getReduceMotion()) : getReduceMotionFromConfig();
if (!reduceMotionInExiting) {
var _this$props2;
updateLayoutAnimations(this._viewTag, LayoutAnimationType.EXITING, maybeBuild(exiting, (_this$props2 = this.props) === null || _this$props2 === void 0 ? void 0 : _this$props2.style, AnimatedComponent.displayName));
}
}
}
_getEventViewRef() {
var _this$_component, _getScrollableNode, _ref;
// Make sure to get the scrollable node for components that implement
// `ScrollResponder.Mixin`.
return (_this$_component = this._component) !== null && _this$_component !== void 0 && _this$_component.getScrollableNode ? (_getScrollableNode = (_ref = this._component).getScrollableNode) === null || _getScrollableNode === void 0 ? void 0 : _getScrollableNode.call(_ref) : this._component;
}
_attachNativeEvents() {
for (const key in this.props) {
const prop = this.props[key];
if (has('workletEventHandler', prop) && prop.workletEventHandler instanceof WorkletEventHandler) {
prop.workletEventHandler.registerForEvents(this._viewTag, key);
}
}
}
_detachNativeEvents() {
for (const key in this.props) {
const prop = this.props[key];
if (has('workletEventHandler', prop) && prop.workletEventHandler instanceof WorkletEventHandler) {
prop.workletEventHandler.unregisterFromEvents(this._viewTag);
}
}
}
_detachStyles() {
if (IS_WEB && this._styles !== null) {
for (const style of this._styles) {
style.viewsRef.remove(this);
}
} else if (this._viewTag !== -1 && this._styles !== null) {
var _this$props$animatedP;
for (const style of this._styles) {
style.viewDescriptors.remove(this._viewTag);
}
if ((_this$props$animatedP = this.props.animatedProps) !== null && _this$props$animatedP !== void 0 && _this$props$animatedP.viewDescriptors) {
this.props.animatedProps.viewDescriptors.remove(this._viewTag);
}
if (isFabric()) {
removeFromPropsRegistry(this._viewTag);
}
}
}
_updateNativeEvents(prevProps) {
for (const key in prevProps) {
const prevProp = prevProps[key];
if (has('workletEventHandler', prevProp) && prevProp.workletEventHandler instanceof WorkletEventHandler) {
const newProp = this.props[key];
if (!newProp) {
// Prop got deleted
prevProp.workletEventHandler.unregisterFromEvents(this._viewTag);
} else if (has('workletEventHandler', newProp) && newProp.workletEventHandler instanceof WorkletEventHandler && newProp.workletEventHandler !== prevProp.workletEventHandler) {
// Prop got changed
prevProp.workletEventHandler.unregisterFromEvents(this._viewTag);
newProp.workletEventHandler.registerForEvents(this._viewTag);
}
}
}
for (const key in this.props) {
const newProp = this.props[key];
if (has('workletEventHandler', newProp) && newProp.workletEventHandler instanceof WorkletEventHandler && !prevProps[key]) {
// Prop got added
newProp.workletEventHandler.registerForEvents(this._viewTag);
}
}
}
_updateFromNative(props) {
if (options !== null && options !== void 0 && options.setNativeProps) {
options.setNativeProps(this._component, props);
} else {
var _this$_component2, _this$_component2$set;
(_this$_component2 = this._component) === null || _this$_component2 === void 0 || (_this$_component2$set = _this$_component2.setNativeProps) === null || _this$_component2$set === void 0 || _this$_component2$set.call(_this$_component2, props);
}
}
_getViewInfo() {
var _this$_component3, _getAnimatableRef, _ref2;
if (this._viewInfo !== undefined) {
return this._viewInfo;
}
let viewTag;
let viewName;
let shadowNodeWrapper = null;
let viewConfig;
// Component can specify ref which should be animated when animated version of the component is created.
// Otherwise, we animate the component itself.
const component = (_this$_component3 = this._component) !== null && _this$_component3 !== void 0 && _this$_component3.getAnimatableRef ? (_getAnimatableRef = (_ref2 = this._component).getAnimatableRef) === null || _getAnimatableRef === void 0 ? void 0 : _getAnimatableRef.call(_ref2) : this;
if (IS_WEB) {
// At this point I assume that `_setComponentRef` was already called and `_component` is set.
// `this._component` on web represents HTMLElement of our component, that's why we use casting
viewTag = this._component;
viewName = null;
shadowNodeWrapper = null;
viewConfig = null;
} else {
// hostInstance can be null for a component that doesn't render anything (render function returns null). Example: svg Stop: https://github.com/react-native-svg/react-native-svg/blob/develop/src/elements/Stop.tsx
const hostInstance = RNRenderer.findHostInstance_DEPRECATED(component);
if (!hostInstance) {
throw new Error('[Reanimated] Cannot find host instance for this component. Maybe it renders nothing?');
}
const viewInfo = getViewInfo(hostInstance);
viewTag = viewInfo.viewTag;
viewName = viewInfo.viewName;
viewConfig = viewInfo.viewConfig;
shadowNodeWrapper = isFabric() ? getShadowNodeWrapperFromRef(this) : null;
}
this._viewInfo = {
viewTag,
viewName,
shadowNodeWrapper,
viewConfig
};
return this._viewInfo;
}
_attachAnimatedStyles() {
var _this$props$animatedP2, _this$props$animatedP3;
const styles = this.props.style ? onlyAnimatedStyles(flattenArray(this.props.style)) : [];
const prevStyles = this._styles;
this._styles = styles;
const prevAnimatedProps = this._animatedProps;
this._animatedProps = this.props.animatedProps;
const {
viewTag,
viewName,
shadowNodeWrapper,
viewConfig
} = this._getViewInfo();
// update UI props whitelist for this view
const hasReanimated2Props = ((_this$props$animatedP2 = this.props.animatedProps) === null || _this$props$animatedP2 === void 0 ? void 0 : _this$props$animatedP2.viewDescriptors) || styles.length;
if (hasReanimated2Props && viewConfig) {
adaptViewConfig(viewConfig);
}
this._viewTag = viewTag;
// remove old styles
if (prevStyles) {
// in most of the cases, views have only a single animated style and it remains unchanged
const hasOneSameStyle = styles.length === 1 && prevStyles.length === 1 && styles[0] === prevStyles[0];
if (!hasOneSameStyle) {
// otherwise, remove each style that is not present in new styles
for (const prevStyle of prevStyles) {
const isPresent = styles.some(style => style === prevStyle);
if (!isPresent) {
prevStyle.viewDescriptors.remove(viewTag);
}
}
}
}
styles.forEach(style => {
style.viewDescriptors.add({
tag: viewTag,
name: viewName,
shadowNodeWrapper
});
if (isJest()) {
/**
* We need to connect Jest's TestObject instance whose contains just props object
* with the updateProps() function where we update the properties of the component.
* We can't update props object directly because TestObject contains a copy of props - look at render function:
* const props = this._filterNonAnimatedProps(this.props);
*/
this.jestAnimatedStyle.value = {
...this.jestAnimatedStyle.value,
...style.initial.value
};
style.jestAnimatedStyle.current = this.jestAnimatedStyle;
}
});
// detach old animatedProps
if (prevAnimatedProps && prevAnimatedProps !== this.props.animatedProps) {
prevAnimatedProps.viewDescriptors.remove(viewTag);
}
// attach animatedProps property
if ((_this$props$animatedP3 = this.props.animatedProps) !== null && _this$props$animatedP3 !== void 0 && _this$props$animatedP3.viewDescriptors) {
this.props.animatedProps.viewDescriptors.add({
tag: viewTag,
name: viewName,
shadowNodeWrapper: shadowNodeWrapper
});
}
}
componentDidUpdate(prevProps, _prevState,
// This type comes straight from React
// eslint-disable-next-line @typescript-eslint/no-explicit-any
snapshot) {
const layout = this.props.layout;
const oldLayout = prevProps.layout;
if (layout !== oldLayout) {
this._configureLayoutTransition();
}
if (this.props.sharedTransitionTag !== undefined || prevProps.sharedTransitionTag !== undefined) {
this._configureSharedTransition();
}
this._updateNativeEvents(prevProps);
this._attachAnimatedStyles();
this._InlinePropManager.attachInlineProps(this, this._getViewInfo());
if (IS_WEB && this.props.exiting) {
saveSnapshot(this._component);
}
// Snapshot won't be undefined because it comes from getSnapshotBeforeUpdate method
if (IS_WEB && snapshot !== null && this.props.layout && !getReducedMotionFromConfig(this.props.layout)) {
tryActivateLayoutTransition(this.props, this._component, snapshot);
}
}
_configureLayoutTransition() {
const layout = this.props.layout ? maybeBuild(this.props.layout, undefined /* We don't have to warn user if style has common properties with animation for LAYOUT */, AnimatedComponent.displayName) : undefined;
updateLayoutAnimations(this._viewTag, LayoutAnimationType.LAYOUT, layout);
}
_configureSharedTransition(isUnmounting = false) {
if (IS_WEB) {
return;
}
const {
sharedTransitionTag
} = this.props;
if (!sharedTransitionTag) {
var _this$_sharedElementT2;
(_this$_sharedElementT2 = this._sharedElementTransition) === null || _this$_sharedElementT2 === void 0 || _this$_sharedElementT2.unregisterTransition(this._viewTag, isUnmounting);
this._sharedElementTransition = null;
return;
}
const sharedElementTransition = this.props.sharedTransitionStyle ?? this._sharedElementTransition ?? new SharedTransition();
sharedElementTransition.registerTransition(this._viewTag, sharedTransitionTag, isUnmounting);
this._sharedElementTransition = sharedElementTransition;
}
// This is a component lifecycle method from React, therefore we are not calling it directly.
// It is called before the component gets rerendered. This way we can access components' position before it changed
// and later on, in componentDidUpdate, calculate translation for layout transition.
getSnapshotBeforeUpdate() {
var _this$_component4;
if (IS_WEB && ((_this$_component4 = this._component) === null || _this$_component4 === void 0 ? void 0 : _this$_component4.getBoundingClientRect) !== undefined) {
return this._component.getBoundingClientRect();
}
return null;
}
render() {
const filteredProps = this._PropsFilter.filterNonAnimatedProps(this);
if (isJest()) {
filteredProps.jestAnimatedStyle = this.jestAnimatedStyle;
}
// Layout animations on web are set inside `componentDidMount` method, which is called after first render.
// Because of that we can encounter a situation in which component is visible for a short amount of time, and later on animation triggers.
// I've tested that on various browsers and devices and it did not happen to me. To be sure that it won't happen to someone else,
// I've decided to hide component at first render. Its visibility is reset in `componentDidMount`.
if (this._isFirstRender && IS_WEB && filteredProps.entering && !getReducedMotionFromConfig(filteredProps.entering)) {
filteredProps.style = {
...(filteredProps.style ?? {}),
visibility: 'hidden' // Hide component until `componentDidMount` triggers
};
}
const platformProps = Platform.select({
web: {},
default: {
collapsable: false
}
});
return /*#__PURE__*/React.createElement(Component, _extends({}, filteredProps, {
// Casting is used here, because ref can be null - in that case it cannot be assigned to HTMLElement.
// After spending some time trying to figure out what to do with this problem, we decided to leave it this way
ref: this._setComponentRef
}, platformProps));
}
}
_defineProperty(AnimatedComponent, "displayName", void 0);
_defineProperty(AnimatedComponent, "contextType", SkipEnteringContext);
AnimatedComponent.displayName = `AnimatedComponent(${Component.displayName || Component.name || 'Component'})`;
return /*#__PURE__*/React.forwardRef((props, ref) => {
return /*#__PURE__*/React.createElement(AnimatedComponent, _extends({}, props, ref === null ? null : {
forwardedRef: ref
}));
});
}
//# sourceMappingURL=createAnimatedComponent.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
'use strict';
/* eslint-disable @typescript-eslint/no-explicit-any */
// This is a makeshift solution to handle both 0.73 and 0.74 versions of React Native.
export let getViewInfo = element => {
if (element._nativeTag !== undefined && element.__nativeTag !== null) {
getViewInfo = getViewInfo73;
return getViewInfo73(element);
} else if (element.__nativeTag !== undefined && element.__nativeTag !== null) {
getViewInfo = getViewInfoLatest;
return getViewInfoLatest(element);
}
return getViewInfo73(element);
};
function getViewInfo73(element) {
var _element$viewConfig;
return {
// we can access view tag in the same way it's accessed here https://github.com/facebook/react/blob/e3f4eb7272d4ca0ee49f27577156b57eeb07cf73/packages/react-native-renderer/src/ReactFabric.js#L146
viewName: element === null || element === void 0 || (_element$viewConfig = element.viewConfig) === null || _element$viewConfig === void 0 ? void 0 : _element$viewConfig.uiViewClassName,
/**
* RN uses viewConfig for components for storing different properties of the component(example: https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js#L24).
* The name we're looking for is in the field named uiViewClassName.
*/
viewTag: element === null || element === void 0 ? void 0 : element._nativeTag,
viewConfig: element === null || element === void 0 ? void 0 : element.viewConfig
};
}
function getViewInfoLatest(element) {
var _element$_viewConfig;
return {
viewName: element === null || element === void 0 || (_element$_viewConfig = element._viewConfig) === null || _element$_viewConfig === void 0 ? void 0 : _element$_viewConfig.uiViewClassName,
viewTag: element === null || element === void 0 ? void 0 : element.__nativeTag,
viewConfig: element === null || element === void 0 ? void 0 : element._viewConfig
};
}
//# sourceMappingURL=getViewInfo.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getViewInfo","element","_nativeTag","undefined","__nativeTag","getViewInfo73","getViewInfoLatest","_element$viewConfig","viewName","viewConfig","uiViewClassName","viewTag","_element$_viewConfig","_viewConfig"],"sources":["getViewInfo.ts"],"sourcesContent":["'use strict';\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// This is a makeshift solution to handle both 0.73 and 0.74 versions of React Native.\n\nexport let getViewInfo = (element: any) => {\n if (element._nativeTag !== undefined && element.__nativeTag !== null) {\n getViewInfo = getViewInfo73;\n return getViewInfo73(element);\n } else if (\n element.__nativeTag !== undefined &&\n element.__nativeTag !== null\n ) {\n getViewInfo = getViewInfoLatest;\n return getViewInfoLatest(element);\n }\n return getViewInfo73(element);\n};\n\nfunction getViewInfo73(element: any) {\n return {\n // we can access view tag in the same way it's accessed here https://github.com/facebook/react/blob/e3f4eb7272d4ca0ee49f27577156b57eeb07cf73/packages/react-native-renderer/src/ReactFabric.js#L146\n viewName: element?.viewConfig?.uiViewClassName,\n /**\n * RN uses viewConfig for components for storing different properties of the component(example: https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Components/ScrollView/ScrollViewNativeComponent.js#L24).\n * The name we're looking for is in the field named uiViewClassName.\n */\n viewTag: element?._nativeTag,\n viewConfig: element?.viewConfig,\n };\n}\n\nfunction getViewInfoLatest(element: any) {\n return {\n viewName: element?._viewConfig?.uiViewClassName,\n viewTag: element?.__nativeTag,\n viewConfig: element?._viewConfig,\n };\n}\n"],"mappings":"AAAA,YAAY;;AACZ;;AAEA;AAEA,OAAO,IAAIA,WAAW,GAAIC,OAAY,IAAK;EACzC,IAAIA,OAAO,CAACC,UAAU,KAAKC,SAAS,IAAIF,OAAO,CAACG,WAAW,KAAK,IAAI,EAAE;IACpEJ,WAAW,GAAGK,aAAa;IAC3B,OAAOA,aAAa,CAACJ,OAAO,CAAC;EAC/B,CAAC,MAAM,IACLA,OAAO,CAACG,WAAW,KAAKD,SAAS,IACjCF,OAAO,CAACG,WAAW,KAAK,IAAI,EAC5B;IACAJ,WAAW,GAAGM,iBAAiB;IAC/B,OAAOA,iBAAiB,CAACL,OAAO,CAAC;EACnC;EACA,OAAOI,aAAa,CAACJ,OAAO,CAAC;AAC/B,CAAC;AAED,SAASI,aAAaA,CAACJ,OAAY,EAAE;EAAA,IAAAM,mBAAA;EACnC,OAAO;IACL;IACAC,QAAQ,EAAEP,OAAO,aAAPA,OAAO,gBAAAM,mBAAA,GAAPN,OAAO,CAAEQ,UAAU,cAAAF,mBAAA,uBAAnBA,mBAAA,CAAqBG,eAAe;IAC9C;AACJ;AACA;AACA;IACIC,OAAO,EAAEV,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEC,UAAU;IAC5BO,UAAU,EAAER,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEQ;EACvB,CAAC;AACH;AAEA,SAASH,iBAAiBA,CAACL,OAAY,EAAE;EAAA,IAAAW,oBAAA;EACvC,OAAO;IACLJ,QAAQ,EAAEP,OAAO,aAAPA,OAAO,gBAAAW,oBAAA,GAAPX,OAAO,CAAEY,WAAW,cAAAD,oBAAA,uBAApBA,oBAAA,CAAsBF,eAAe;IAC/CC,OAAO,EAAEV,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEG,WAAW;IAC7BK,UAAU,EAAER,OAAO,aAAPA,OAAO,uBAAPA,OAAO,CAAEY;EACvB,CAAC;AACH","ignoreList":[]}

View File

@@ -0,0 +1,4 @@
'use strict';
export { createAnimatedComponent } from './createAnimatedComponent';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createAnimatedComponent"],"sources":["index.ts"],"sourcesContent":["'use strict';\nexport { createAnimatedComponent } from './createAnimatedComponent';\n"],"mappings":"AAAA,YAAY;;AACZ,SAASA,uBAAuB,QAAQ,2BAA2B","ignoreList":[]}

View File

@@ -0,0 +1,57 @@
'use strict';
/**
* imported from react-native
*/
/* eslint-disable */
/**
* This is a helper function for when a component needs to be able to forward a ref
* to a child component, but still needs to have access to that component as part of
* its implementation.
*
* Its main use case is in wrappers for native components.
*
* Usage:
*
* class MyView extends React.Component {
* _nativeRef = null;
*
* _setNativeRef = setAndForwardRef({
* getForwardedRef: () => this.props.forwardedRef,
* setLocalRef: ref => {
* this._nativeRef = ref;
* },
* });
*
* render() {
* return <View ref={this._setNativeRef} />;
* }
* }
*
* const MyViewWithRef = React.forwardRef((props, ref) => (
* <MyView {...props} forwardedRef={ref} />
* ));
*
* module.exports = MyViewWithRef;
*/
/* eslint-enable */
function setAndForwardRef({
getForwardedRef,
setLocalRef
}) {
return function forwardRef(ref) {
const forwardedRef = getForwardedRef();
setLocalRef(ref);
// Forward to user ref prop (if one has been specified)
if (typeof forwardedRef === 'function') {
// Handle function-based refs. String-based refs are handled as functions.
forwardedRef(ref);
} else if (typeof forwardedRef === 'object' && forwardedRef != null) {
// Handle createRef-based refs
forwardedRef.current = ref;
}
};
}
export default setAndForwardRef;
//# sourceMappingURL=setAndForwardRef.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["setAndForwardRef","getForwardedRef","setLocalRef","forwardRef","ref","forwardedRef","current"],"sources":["setAndForwardRef.ts"],"sourcesContent":["'use strict';\n/**\n * imported from react-native\n */\n\nimport type { MutableRefObject } from 'react';\n\n/* eslint-disable */\n/**\n * This is a helper function for when a component needs to be able to forward a ref\n * to a child component, but still needs to have access to that component as part of\n * its implementation.\n *\n * Its main use case is in wrappers for native components.\n *\n * Usage:\n *\n * class MyView extends React.Component {\n * _nativeRef = null;\n *\n * _setNativeRef = setAndForwardRef({\n * getForwardedRef: () => this.props.forwardedRef,\n * setLocalRef: ref => {\n * this._nativeRef = ref;\n * },\n * });\n *\n * render() {\n * return <View ref={this._setNativeRef} />;\n * }\n * }\n *\n * const MyViewWithRef = React.forwardRef((props, ref) => (\n * <MyView {...props} forwardedRef={ref} />\n * ));\n *\n * module.exports = MyViewWithRef;\n */\n/* eslint-enable */\n\ntype ForwardedRef<T> = () => MutableRefObject<T> | ((ref: T) => void);\n\nfunction setAndForwardRef<T>({\n getForwardedRef,\n setLocalRef,\n}: {\n getForwardedRef: ForwardedRef<T>;\n setLocalRef: (ref: T) => void;\n}): (ref: T) => void {\n return function forwardRef(ref: T) {\n const forwardedRef = getForwardedRef();\n\n setLocalRef(ref);\n\n // Forward to user ref prop (if one has been specified)\n if (typeof forwardedRef === 'function') {\n // Handle function-based refs. String-based refs are handled as functions.\n forwardedRef(ref);\n } else if (typeof forwardedRef === 'object' && forwardedRef != null) {\n // Handle createRef-based refs\n forwardedRef.current = ref;\n }\n };\n}\n\nexport default setAndForwardRef;\n"],"mappings":"AAAA,YAAY;;AACZ;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA,SAASA,gBAAgBA,CAAI;EAC3BC,eAAe;EACfC;AAIF,CAAC,EAAoB;EACnB,OAAO,SAASC,UAAUA,CAACC,GAAM,EAAE;IACjC,MAAMC,YAAY,GAAGJ,eAAe,CAAC,CAAC;IAEtCC,WAAW,CAACE,GAAG,CAAC;;IAEhB;IACA,IAAI,OAAOC,YAAY,KAAK,UAAU,EAAE;MACtC;MACAA,YAAY,CAACD,GAAG,CAAC;IACnB,CAAC,MAAM,IAAI,OAAOC,YAAY,KAAK,QAAQ,IAAIA,YAAY,IAAI,IAAI,EAAE;MACnE;MACAA,YAAY,CAACC,OAAO,GAAGF,GAAG;IAC5B;EACF,CAAC;AACH;AAEA,eAAeJ,gBAAgB","ignoreList":[]}

View File

@@ -0,0 +1,30 @@
'use strict';
export function flattenArray(array) {
if (!Array.isArray(array)) {
return [array];
}
const resultArr = [];
const _flattenArray = arr => {
arr.forEach(item => {
if (Array.isArray(item)) {
_flattenArray(item);
} else {
resultArr.push(item);
}
});
};
_flattenArray(array);
return resultArr;
}
export const has = (key, x) => {
if (typeof x === 'function' || typeof x === 'object') {
if (x === null || x === undefined) {
return false;
} else {
return key in x;
}
}
return false;
};
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["flattenArray","array","Array","isArray","resultArr","_flattenArray","arr","forEach","item","push","has","key","x","undefined"],"sources":["utils.ts"],"sourcesContent":["'use strict';\nimport type { NestedArray } from './commonTypes';\n\nexport function flattenArray<T>(array: NestedArray<T>): T[] {\n if (!Array.isArray(array)) {\n return [array];\n }\n const resultArr: T[] = [];\n\n const _flattenArray = (arr: NestedArray<T>[]): void => {\n arr.forEach((item) => {\n if (Array.isArray(item)) {\n _flattenArray(item);\n } else {\n resultArr.push(item);\n }\n });\n };\n _flattenArray(array);\n return resultArr;\n}\n\nexport const has = <K extends string>(\n key: K,\n x: unknown\n): x is { [key in K]: unknown } => {\n if (typeof x === 'function' || typeof x === 'object') {\n if (x === null || x === undefined) {\n return false;\n } else {\n return key in x;\n }\n }\n return false;\n};\n"],"mappings":"AAAA,YAAY;;AAGZ,OAAO,SAASA,YAAYA,CAAIC,KAAqB,EAAO;EAC1D,IAAI,CAACC,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC,EAAE;IACzB,OAAO,CAACA,KAAK,CAAC;EAChB;EACA,MAAMG,SAAc,GAAG,EAAE;EAEzB,MAAMC,aAAa,GAAIC,GAAqB,IAAW;IACrDA,GAAG,CAACC,OAAO,CAAEC,IAAI,IAAK;MACpB,IAAIN,KAAK,CAACC,OAAO,CAACK,IAAI,CAAC,EAAE;QACvBH,aAAa,CAACG,IAAI,CAAC;MACrB,CAAC,MAAM;QACLJ,SAAS,CAACK,IAAI,CAACD,IAAI,CAAC;MACtB;IACF,CAAC,CAAC;EACJ,CAAC;EACDH,aAAa,CAACJ,KAAK,CAAC;EACpB,OAAOG,SAAS;AAClB;AAEA,OAAO,MAAMM,GAAG,GAAGA,CACjBC,GAAM,EACNC,CAAU,KACuB;EACjC,IAAI,OAAOA,CAAC,KAAK,UAAU,IAAI,OAAOA,CAAC,KAAK,QAAQ,EAAE;IACpD,IAAIA,CAAC,KAAK,IAAI,IAAIA,CAAC,KAAKC,SAAS,EAAE;MACjC,OAAO,KAAK;IACd,CAAC,MAAM;MACL,OAAOF,GAAG,IAAIC,CAAC;IACjB;EACF;EACA,OAAO,KAAK;AACd,CAAC","ignoreList":[]}