aix 0.0.14 → 0.1.0-alpha.1
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.
- package/Aix.podspec +32 -0
- package/LICENSE +2 -2
- package/README.md +165 -33
- package/android/CMakeLists.txt +32 -0
- package/android/build.gradle +148 -0
- package/android/fix-prefab.gradle +51 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/com/aix/AixPackage.kt +29 -0
- package/android/src/main/java/com/aix/HybridAix.kt +27 -0
- package/ios/Bridge.h +8 -0
- package/ios/HybridAix.swift +1072 -0
- package/ios/HybridAixCellView.swift +174 -0
- package/ios/HybridAixComposer.swift +119 -0
- package/lib/commonjs/aix.js +25 -0
- package/lib/commonjs/aix.js.map +1 -0
- package/lib/commonjs/fade-in/createUsePool.js +50 -0
- package/lib/commonjs/fade-in/createUsePool.js.map +1 -0
- package/lib/commonjs/fade-in/createUseStaggered.js +82 -0
- package/lib/commonjs/fade-in/createUseStaggered.js.map +1 -0
- package/lib/commonjs/fade-in/index.js +78 -0
- package/lib/commonjs/fade-in/index.js.map +1 -0
- package/lib/commonjs/footer.js +28 -0
- package/lib/commonjs/footer.js.map +1 -0
- package/lib/commonjs/index.js +48 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/views/aix.nitro.js +6 -0
- package/lib/commonjs/views/aix.nitro.js.map +1 -0
- package/lib/module/aix.js +20 -0
- package/lib/module/aix.js.map +1 -0
- package/lib/module/fade-in/createUsePool.js +46 -0
- package/lib/module/fade-in/createUsePool.js.map +1 -0
- package/lib/module/fade-in/createUseStaggered.js +79 -0
- package/lib/module/fade-in/createUseStaggered.js.map +1 -0
- package/lib/module/fade-in/index.js +74 -0
- package/lib/module/fade-in/index.js.map +1 -0
- package/lib/module/footer.js +23 -0
- package/lib/module/footer.js.map +1 -0
- package/lib/module/index.js +13 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/views/aix.nitro.js +4 -0
- package/lib/module/views/aix.nitro.js.map +1 -0
- package/lib/typescript/src/aix.d.ts +14 -0
- package/lib/typescript/src/aix.d.ts.map +1 -0
- package/lib/typescript/src/fade-in/createUsePool.d.ts +5 -0
- package/lib/typescript/src/fade-in/createUsePool.d.ts.map +1 -0
- package/lib/typescript/src/fade-in/createUseStaggered.d.ts +2 -0
- package/lib/typescript/src/fade-in/createUseStaggered.d.ts.map +1 -0
- package/lib/typescript/src/fade-in/index.d.ts +5 -0
- package/lib/typescript/src/fade-in/index.d.ts.map +1 -0
- package/lib/typescript/src/footer.d.ts +5 -0
- package/lib/typescript/src/footer.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/views/aix.nitro.d.ts +101 -0
- package/lib/typescript/src/views/aix.nitro.d.ts.map +1 -0
- package/nitro.json +26 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/Aix+autolinking.cmake +91 -0
- package/nitrogen/generated/android/Aix+autolinking.gradle +27 -0
- package/nitrogen/generated/android/AixOnLoad.cpp +70 -0
- package/nitrogen/generated/android/AixOnLoad.hpp +25 -0
- package/nitrogen/generated/android/c++/JAixAdditionalContentInsets.hpp +61 -0
- package/nitrogen/generated/android/c++/JAixAdditionalContentInsetsProp.hpp +63 -0
- package/nitrogen/generated/android/c++/JAixScrollIndicatorInsetValue.hpp +61 -0
- package/nitrogen/generated/android/c++/JAixScrollIndicatorInsets.hpp +63 -0
- package/nitrogen/generated/android/c++/JAixScrollOnFooterSizeUpdate.hpp +65 -0
- package/nitrogen/generated/android/c++/JHybridAixCellViewSpec.cpp +65 -0
- package/nitrogen/generated/android/c++/JHybridAixCellViewSpec.hpp +68 -0
- package/nitrogen/generated/android/c++/JHybridAixComposerSpec.cpp +48 -0
- package/nitrogen/generated/android/c++/JHybridAixComposerSpec.hpp +65 -0
- package/nitrogen/generated/android/c++/JHybridAixSpec.cpp +137 -0
- package/nitrogen/generated/android/c++/JHybridAixSpec.hpp +79 -0
- package/nitrogen/generated/android/c++/views/JHybridAixCellViewStateUpdater.cpp +60 -0
- package/nitrogen/generated/android/c++/views/JHybridAixCellViewStateUpdater.hpp +49 -0
- package/nitrogen/generated/android/c++/views/JHybridAixComposerStateUpdater.cpp +53 -0
- package/nitrogen/generated/android/c++/views/JHybridAixComposerStateUpdater.hpp +49 -0
- package/nitrogen/generated/android/c++/views/JHybridAixStateUpdater.cpp +80 -0
- package/nitrogen/generated/android/c++/views/JHybridAixStateUpdater.hpp +49 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixAdditionalContentInsets.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixAdditionalContentInsetsProp.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixOnLoad.kt +35 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollIndicatorInsetValue.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollIndicatorInsets.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollOnFooterSizeUpdate.kt +44 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixCellViewSpec.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixComposerSpec.kt +55 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixSpec.kt +101 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixCellViewManager.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixCellViewStateUpdater.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixComposerManager.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixComposerStateUpdater.kt +23 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixManager.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixStateUpdater.kt +23 -0
- package/nitrogen/generated/ios/Aix+autolinking.rb +60 -0
- package/nitrogen/generated/ios/Aix-Swift-Cxx-Bridge.cpp +67 -0
- package/nitrogen/generated/ios/Aix-Swift-Cxx-Bridge.hpp +222 -0
- package/nitrogen/generated/ios/Aix-Swift-Cxx-Umbrella.hpp +70 -0
- package/nitrogen/generated/ios/AixAutolinking.mm +49 -0
- package/nitrogen/generated/ios/AixAutolinking.swift +55 -0
- package/nitrogen/generated/ios/c++/HybridAixCellViewSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridAixCellViewSpecSwift.hpp +80 -0
- package/nitrogen/generated/ios/c++/HybridAixComposerSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridAixComposerSpecSwift.hpp +69 -0
- package/nitrogen/generated/ios/c++/HybridAixSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridAixSpecSwift.hpp +142 -0
- package/nitrogen/generated/ios/c++/views/HybridAixCellViewComponent.mm +101 -0
- package/nitrogen/generated/ios/c++/views/HybridAixComponent.mm +126 -0
- package/nitrogen/generated/ios/c++/views/HybridAixComposerComponent.mm +92 -0
- package/nitrogen/generated/ios/swift/AixAdditionalContentInsets.swift +47 -0
- package/nitrogen/generated/ios/swift/AixAdditionalContentInsetsProp.swift +71 -0
- package/nitrogen/generated/ios/swift/AixScrollIndicatorInsetValue.swift +47 -0
- package/nitrogen/generated/ios/swift/AixScrollIndicatorInsets.swift +71 -0
- package/nitrogen/generated/ios/swift/AixScrollOnFooterSizeUpdate.swift +89 -0
- package/nitrogen/generated/ios/swift/HybridAixCellViewSpec.swift +57 -0
- package/nitrogen/generated/ios/swift/HybridAixCellViewSpec_cxx.swift +151 -0
- package/nitrogen/generated/ios/swift/HybridAixComposerSpec.swift +56 -0
- package/nitrogen/generated/ios/swift/HybridAixComposerSpec_cxx.swift +131 -0
- package/nitrogen/generated/ios/swift/HybridAixSpec.swift +63 -0
- package/nitrogen/generated/ios/swift/HybridAixSpec_cxx.swift +292 -0
- package/nitrogen/generated/shared/c++/AixAdditionalContentInsets.hpp +79 -0
- package/nitrogen/generated/shared/c++/AixAdditionalContentInsetsProp.hpp +81 -0
- package/nitrogen/generated/shared/c++/AixScrollIndicatorInsetValue.hpp +79 -0
- package/nitrogen/generated/shared/c++/AixScrollIndicatorInsets.hpp +81 -0
- package/nitrogen/generated/shared/c++/AixScrollOnFooterSizeUpdate.hpp +83 -0
- package/nitrogen/generated/shared/c++/HybridAixCellViewSpec.cpp +24 -0
- package/nitrogen/generated/shared/c++/HybridAixCellViewSpec.hpp +65 -0
- package/nitrogen/generated/shared/c++/HybridAixComposerSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridAixComposerSpec.hpp +62 -0
- package/nitrogen/generated/shared/c++/HybridAixSpec.cpp +36 -0
- package/nitrogen/generated/shared/c++/HybridAixSpec.hpp +85 -0
- package/nitrogen/generated/shared/c++/views/HybridAixCellViewComponent.cpp +99 -0
- package/nitrogen/generated/shared/c++/views/HybridAixCellViewComponent.hpp +108 -0
- package/nitrogen/generated/shared/c++/views/HybridAixComponent.cpp +159 -0
- package/nitrogen/generated/shared/c++/views/HybridAixComponent.hpp +117 -0
- package/nitrogen/generated/shared/c++/views/HybridAixComposerComponent.cpp +75 -0
- package/nitrogen/generated/shared/c++/views/HybridAixComposerComponent.hpp +106 -0
- package/nitrogen/generated/shared/json/AixCellViewConfig.json +11 -0
- package/nitrogen/generated/shared/json/AixComposerConfig.json +9 -0
- package/nitrogen/generated/shared/json/AixConfig.json +16 -0
- package/package.json +115 -12
- package/src/aix.tsx +43 -0
- package/src/fade-in/createUsePool.ts +46 -0
- package/src/fade-in/createUseStaggered.ts +82 -0
- package/src/fade-in/index.tsx +97 -0
- package/src/footer.tsx +30 -0
- package/src/index.ts +20 -16
- package/src/views/aix.nitro.ts +148 -0
- package/docs/API.md +0 -193
- package/jest.config.js +0 -17
- package/lib/__tests__/deferredIterable.test.d.ts +0 -1
- package/lib/__tests__/deferredIterable.test.js +0 -111
- package/lib/__tests__/filter.test.d.ts +0 -1
- package/lib/__tests__/filter.test.js +0 -56
- package/lib/__tests__/flatMap.test.d.ts +0 -1
- package/lib/__tests__/flatMap.test.js +0 -80
- package/lib/__tests__/lookahead.test.d.ts +0 -1
- package/lib/__tests__/lookahead.test.js +0 -60
- package/lib/__tests__/map.test.d.ts +0 -1
- package/lib/__tests__/map.test.js +0 -56
- package/lib/__tests__/merge.test.d.ts +0 -1
- package/lib/__tests__/merge.test.js +0 -58
- package/lib/__tests__/reduce.test.d.ts +0 -1
- package/lib/__tests__/reduce.test.js +0 -55
- package/lib/__tests__/spanAll.test.d.ts +0 -1
- package/lib/__tests__/spanAll.test.js +0 -123
- package/lib/concat.d.ts +0 -5
- package/lib/concat.js +0 -127
- package/lib/deferred.d.ts +0 -10
- package/lib/deferred.js +0 -19
- package/lib/deferredIterable.d.ts +0 -23
- package/lib/deferredIterable.js +0 -112
- package/lib/filter.d.ts +0 -8
- package/lib/filter.js +0 -100
- package/lib/flatMap.d.ts +0 -2
- package/lib/flatMap.js +0 -120
- package/lib/fromEvent.d.ts +0 -6
- package/lib/fromEvent.js +0 -17
- package/lib/index.d.ts +0 -16
- package/lib/index.js +0 -34
- package/lib/insert.d.ts +0 -5
- package/lib/insert.js +0 -114
- package/lib/interval.d.ts +0 -5
- package/lib/interval.js +0 -68
- package/lib/iterableToArray.d.ts +0 -2
- package/lib/iterableToArray.js +0 -88
- package/lib/iteratorToIterable.d.ts +0 -7
- package/lib/iteratorToIterable.js +0 -71
- package/lib/lookahead.d.ts +0 -11
- package/lib/lookahead.js +0 -82
- package/lib/map.d.ts +0 -5
- package/lib/map.js +0 -99
- package/lib/merge.d.ts +0 -7
- package/lib/merge.js +0 -25
- package/lib/reduce.d.ts +0 -5
- package/lib/reduce.js +0 -93
- package/lib/restToIterable.d.ts +0 -5
- package/lib/restToIterable.js +0 -74
- package/lib/spanAll.d.ts +0 -2
- package/lib/spanAll.js +0 -34
- package/lib/tap.d.ts +0 -5
- package/lib/tap.js +0 -97
- package/lib/toCallbacks.d.ts +0 -12
- package/lib/toCallbacks.js +0 -98
- package/lib/zip.d.ts +0 -5
- package/lib/zip.js +0 -76
- package/src/__tests__/deferredIterable.test.ts +0 -22
- package/src/__tests__/filter.test.ts +0 -10
- package/src/__tests__/flatMap.test.ts +0 -12
- package/src/__tests__/lookahead.test.ts +0 -9
- package/src/__tests__/map.test.ts +0 -10
- package/src/__tests__/merge.test.ts +0 -9
- package/src/__tests__/reduce.test.ts +0 -10
- package/src/__tests__/spanAll.test.ts +0 -17
- package/src/concat.ts +0 -13
- package/src/deferred.ts +0 -15
- package/src/deferredIterable.ts +0 -111
- package/src/filter.ts +0 -16
- package/src/flatMap.ts +0 -9
- package/src/fromEvent.ts +0 -16
- package/src/insert.ts +0 -13
- package/src/interval.ts +0 -20
- package/src/iterableToArray.ts +0 -7
- package/src/iteratorToIterable.ts +0 -12
- package/src/lookahead.ts +0 -27
- package/src/map.ts +0 -11
- package/src/merge.ts +0 -16
- package/src/of.ts +0 -4
- package/src/reduce.ts +0 -12
- package/src/restToIterable.ts +0 -8
- package/src/spanAll.ts +0 -26
- package/src/tap.ts +0 -11
- package/src/toCallbacks.ts +0 -27
- package/src/zip.ts +0 -19
- package/tsconfig.json +0 -63
- package/yarn.lock +0 -3514
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridAixComponent.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <optional>
|
|
11
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
12
|
+
#include <NitroModules/NitroHash.hpp>
|
|
13
|
+
#include <NitroModules/CachedProp.hpp>
|
|
14
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
15
|
+
#include <react/renderer/core/PropsParserContext.h>
|
|
16
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
17
|
+
#include <react/renderer/components/view/ViewProps.h>
|
|
18
|
+
|
|
19
|
+
#include "AixScrollOnFooterSizeUpdate.hpp"
|
|
20
|
+
#include <optional>
|
|
21
|
+
#include "AixAdditionalContentInsetsProp.hpp"
|
|
22
|
+
#include "AixScrollIndicatorInsets.hpp"
|
|
23
|
+
#include <string>
|
|
24
|
+
#include <memory>
|
|
25
|
+
#include "HybridAixSpec.hpp"
|
|
26
|
+
#include <functional>
|
|
27
|
+
|
|
28
|
+
namespace margelo::nitro::aix::views {
|
|
29
|
+
|
|
30
|
+
using namespace facebook;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The name of the actual native View.
|
|
34
|
+
*/
|
|
35
|
+
extern const char HybridAixComponentName[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Props for the "Aix" View.
|
|
39
|
+
*/
|
|
40
|
+
class HybridAixProps final: public react::ViewProps {
|
|
41
|
+
public:
|
|
42
|
+
HybridAixProps() = default;
|
|
43
|
+
HybridAixProps(const HybridAixProps&);
|
|
44
|
+
HybridAixProps(const react::PropsParserContext& context,
|
|
45
|
+
const HybridAixProps& sourceProps,
|
|
46
|
+
const react::RawProps& rawProps);
|
|
47
|
+
|
|
48
|
+
public:
|
|
49
|
+
CachedProp<bool> shouldStartAtEnd;
|
|
50
|
+
CachedProp<std::optional<AixScrollOnFooterSizeUpdate>> scrollOnFooterSizeUpdate;
|
|
51
|
+
CachedProp<std::optional<double>> scrollEndReachedThreshold;
|
|
52
|
+
CachedProp<std::optional<AixAdditionalContentInsetsProp>> additionalContentInsets;
|
|
53
|
+
CachedProp<std::optional<AixScrollIndicatorInsets>> additionalScrollIndicatorInsets;
|
|
54
|
+
CachedProp<std::optional<std::string>> mainScrollViewID;
|
|
55
|
+
CachedProp<std::optional<double>> penultimateCellIndex;
|
|
56
|
+
CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixSpec>& /* ref */)>>> hybridRef;
|
|
57
|
+
|
|
58
|
+
private:
|
|
59
|
+
static bool filterObjectKeys(const std::string& propName);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* State for the "Aix" View.
|
|
64
|
+
*/
|
|
65
|
+
class HybridAixState final {
|
|
66
|
+
public:
|
|
67
|
+
HybridAixState() = default;
|
|
68
|
+
|
|
69
|
+
public:
|
|
70
|
+
void setProps(const HybridAixProps& props) { _props.emplace(props); }
|
|
71
|
+
const std::optional<HybridAixProps>& getProps() const { return _props; }
|
|
72
|
+
|
|
73
|
+
public:
|
|
74
|
+
#ifdef ANDROID
|
|
75
|
+
HybridAixState(const HybridAixState& /* previousState */, folly::dynamic /* data */) {}
|
|
76
|
+
folly::dynamic getDynamic() const {
|
|
77
|
+
throw std::runtime_error("HybridAixState does not support folly!");
|
|
78
|
+
}
|
|
79
|
+
react::MapBuffer getMapBuffer() const {
|
|
80
|
+
throw std::runtime_error("HybridAixState does not support MapBuffer!");
|
|
81
|
+
};
|
|
82
|
+
#endif
|
|
83
|
+
|
|
84
|
+
private:
|
|
85
|
+
std::optional<HybridAixProps> _props;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The Shadow Node for the "Aix" View.
|
|
90
|
+
*/
|
|
91
|
+
using HybridAixShadowNode = react::ConcreteViewShadowNode<HybridAixComponentName /* "HybridAix" */,
|
|
92
|
+
HybridAixProps /* custom props */,
|
|
93
|
+
react::ViewEventEmitter /* default */,
|
|
94
|
+
HybridAixState /* custom state */>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* The Component Descriptor for the "Aix" View.
|
|
98
|
+
*/
|
|
99
|
+
class HybridAixComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridAixShadowNode> {
|
|
100
|
+
public:
|
|
101
|
+
HybridAixComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
|
|
102
|
+
|
|
103
|
+
public:
|
|
104
|
+
/**
|
|
105
|
+
* A faster path for cloning props - reuses the caching logic from `HybridAixProps`.
|
|
106
|
+
*/
|
|
107
|
+
std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
|
|
108
|
+
const std::shared_ptr<const react::Props>& props,
|
|
109
|
+
react::RawProps rawProps) const override;
|
|
110
|
+
#ifdef ANDROID
|
|
111
|
+
void adopt(react::ShadowNode& shadowNode) const override;
|
|
112
|
+
#endif
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/* The actual view for "Aix" needs to be implemented in platform-specific code. */
|
|
116
|
+
|
|
117
|
+
} // namespace margelo::nitro::aix::views
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridAixComposerComponent.cpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#include "HybridAixComposerComponent.hpp"
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <exception>
|
|
12
|
+
#include <utility>
|
|
13
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
14
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
15
|
+
#include <react/renderer/core/RawValue.h>
|
|
16
|
+
#include <react/renderer/core/ShadowNode.h>
|
|
17
|
+
#include <react/renderer/core/ComponentDescriptor.h>
|
|
18
|
+
#include <react/renderer/components/view/ViewProps.h>
|
|
19
|
+
|
|
20
|
+
namespace margelo::nitro::aix::views {
|
|
21
|
+
|
|
22
|
+
extern const char HybridAixComposerComponentName[] = "AixComposer";
|
|
23
|
+
|
|
24
|
+
HybridAixComposerProps::HybridAixComposerProps(const react::PropsParserContext& context,
|
|
25
|
+
const HybridAixComposerProps& sourceProps,
|
|
26
|
+
const react::RawProps& rawProps):
|
|
27
|
+
react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
|
|
28
|
+
hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>> {
|
|
29
|
+
try {
|
|
30
|
+
const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
|
|
31
|
+
if (rawValue == nullptr) return sourceProps.hybridRef;
|
|
32
|
+
const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
|
|
33
|
+
return CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, "f"), sourceProps.hybridRef);
|
|
34
|
+
} catch (const std::exception& exc) {
|
|
35
|
+
throw std::runtime_error(std::string("AixComposer.hybridRef: ") + exc.what());
|
|
36
|
+
}
|
|
37
|
+
}()) { }
|
|
38
|
+
|
|
39
|
+
HybridAixComposerProps::HybridAixComposerProps(const HybridAixComposerProps& other):
|
|
40
|
+
react::ViewProps(),
|
|
41
|
+
hybridRef(other.hybridRef) { }
|
|
42
|
+
|
|
43
|
+
bool HybridAixComposerProps::filterObjectKeys(const std::string& propName) {
|
|
44
|
+
switch (hashString(propName)) {
|
|
45
|
+
case hashString("hybridRef"): return true;
|
|
46
|
+
default: return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
HybridAixComposerComponentDescriptor::HybridAixComposerComponentDescriptor(const react::ComponentDescriptorParameters& parameters)
|
|
51
|
+
: ConcreteComponentDescriptor(parameters,
|
|
52
|
+
react::RawPropsParser(/* enableJsiParser */ true)) {}
|
|
53
|
+
|
|
54
|
+
std::shared_ptr<const react::Props> HybridAixComposerComponentDescriptor::cloneProps(const react::PropsParserContext& context,
|
|
55
|
+
const std::shared_ptr<const react::Props>& props,
|
|
56
|
+
react::RawProps rawProps) const {
|
|
57
|
+
// 1. Prepare raw props parser
|
|
58
|
+
rawProps.parse(rawPropsParser_);
|
|
59
|
+
// 2. Copy props with Nitro's cached copy constructor
|
|
60
|
+
return HybridAixComposerShadowNode::Props(context, /* & */ rawProps, props);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#ifdef ANDROID
|
|
64
|
+
void HybridAixComposerComponentDescriptor::adopt(react::ShadowNode& shadowNode) const {
|
|
65
|
+
// This is called immediately after `ShadowNode` is created, cloned or in progress.
|
|
66
|
+
// On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
|
|
67
|
+
auto& concreteShadowNode = dynamic_cast<HybridAixComposerShadowNode&>(shadowNode);
|
|
68
|
+
const HybridAixComposerProps& props = concreteShadowNode.getConcreteProps();
|
|
69
|
+
HybridAixComposerState state;
|
|
70
|
+
state.setProps(props);
|
|
71
|
+
concreteShadowNode.setStateData(std::move(state));
|
|
72
|
+
}
|
|
73
|
+
#endif
|
|
74
|
+
|
|
75
|
+
} // namespace margelo::nitro::aix::views
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridAixComposerComponent.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2026 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <optional>
|
|
11
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
12
|
+
#include <NitroModules/NitroHash.hpp>
|
|
13
|
+
#include <NitroModules/CachedProp.hpp>
|
|
14
|
+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
|
15
|
+
#include <react/renderer/core/PropsParserContext.h>
|
|
16
|
+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
|
17
|
+
#include <react/renderer/components/view/ViewProps.h>
|
|
18
|
+
|
|
19
|
+
#include <memory>
|
|
20
|
+
#include "HybridAixComposerSpec.hpp"
|
|
21
|
+
#include <functional>
|
|
22
|
+
#include <optional>
|
|
23
|
+
|
|
24
|
+
namespace margelo::nitro::aix::views {
|
|
25
|
+
|
|
26
|
+
using namespace facebook;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The name of the actual native View.
|
|
30
|
+
*/
|
|
31
|
+
extern const char HybridAixComposerComponentName[];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Props for the "AixComposer" View.
|
|
35
|
+
*/
|
|
36
|
+
class HybridAixComposerProps final: public react::ViewProps {
|
|
37
|
+
public:
|
|
38
|
+
HybridAixComposerProps() = default;
|
|
39
|
+
HybridAixComposerProps(const HybridAixComposerProps&);
|
|
40
|
+
HybridAixComposerProps(const react::PropsParserContext& context,
|
|
41
|
+
const HybridAixComposerProps& sourceProps,
|
|
42
|
+
const react::RawProps& rawProps);
|
|
43
|
+
|
|
44
|
+
public:
|
|
45
|
+
CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>> hybridRef;
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
static bool filterObjectKeys(const std::string& propName);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* State for the "AixComposer" View.
|
|
53
|
+
*/
|
|
54
|
+
class HybridAixComposerState final {
|
|
55
|
+
public:
|
|
56
|
+
HybridAixComposerState() = default;
|
|
57
|
+
|
|
58
|
+
public:
|
|
59
|
+
void setProps(const HybridAixComposerProps& props) { _props.emplace(props); }
|
|
60
|
+
const std::optional<HybridAixComposerProps>& getProps() const { return _props; }
|
|
61
|
+
|
|
62
|
+
public:
|
|
63
|
+
#ifdef ANDROID
|
|
64
|
+
HybridAixComposerState(const HybridAixComposerState& /* previousState */, folly::dynamic /* data */) {}
|
|
65
|
+
folly::dynamic getDynamic() const {
|
|
66
|
+
throw std::runtime_error("HybridAixComposerState does not support folly!");
|
|
67
|
+
}
|
|
68
|
+
react::MapBuffer getMapBuffer() const {
|
|
69
|
+
throw std::runtime_error("HybridAixComposerState does not support MapBuffer!");
|
|
70
|
+
};
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
private:
|
|
74
|
+
std::optional<HybridAixComposerProps> _props;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The Shadow Node for the "AixComposer" View.
|
|
79
|
+
*/
|
|
80
|
+
using HybridAixComposerShadowNode = react::ConcreteViewShadowNode<HybridAixComposerComponentName /* "HybridAixComposer" */,
|
|
81
|
+
HybridAixComposerProps /* custom props */,
|
|
82
|
+
react::ViewEventEmitter /* default */,
|
|
83
|
+
HybridAixComposerState /* custom state */>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The Component Descriptor for the "AixComposer" View.
|
|
87
|
+
*/
|
|
88
|
+
class HybridAixComposerComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridAixComposerShadowNode> {
|
|
89
|
+
public:
|
|
90
|
+
HybridAixComposerComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
|
|
91
|
+
|
|
92
|
+
public:
|
|
93
|
+
/**
|
|
94
|
+
* A faster path for cloning props - reuses the caching logic from `HybridAixComposerProps`.
|
|
95
|
+
*/
|
|
96
|
+
std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
|
|
97
|
+
const std::shared_ptr<const react::Props>& props,
|
|
98
|
+
react::RawProps rawProps) const override;
|
|
99
|
+
#ifdef ANDROID
|
|
100
|
+
void adopt(react::ShadowNode& shadowNode) const override;
|
|
101
|
+
#endif
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/* The actual view for "AixComposer" needs to be implemented in platform-specific code. */
|
|
105
|
+
|
|
106
|
+
} // namespace margelo::nitro::aix::views
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"uiViewClassName": "Aix",
|
|
3
|
+
"supportsRawText": false,
|
|
4
|
+
"bubblingEventTypes": {},
|
|
5
|
+
"directEventTypes": {},
|
|
6
|
+
"validAttributes": {
|
|
7
|
+
"shouldStartAtEnd": true,
|
|
8
|
+
"scrollOnFooterSizeUpdate": true,
|
|
9
|
+
"scrollEndReachedThreshold": true,
|
|
10
|
+
"additionalContentInsets": true,
|
|
11
|
+
"additionalScrollIndicatorInsets": true,
|
|
12
|
+
"mainScrollViewID": true,
|
|
13
|
+
"penultimateCellIndex": true,
|
|
14
|
+
"hybridRef": true
|
|
15
|
+
}
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,122 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aix",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"author": "Fernando Rojo",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/vercel/aix.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "./lib/commonjs/index.js",
|
|
10
|
+
"module": "./lib/module/index.js",
|
|
5
11
|
"devDependencies": {
|
|
6
|
-
"@
|
|
7
|
-
"@
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
+
"@jamesacarr/eslint-formatter-github-actions": "^0.2.0",
|
|
13
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
14
|
+
"@semantic-release/git": "^10.0.1",
|
|
15
|
+
"@types/jest": "^29.5.12",
|
|
16
|
+
"@types/react": "19.1.1",
|
|
17
|
+
"nitrogen": "0.31.10",
|
|
18
|
+
"react": "19.1.1",
|
|
19
|
+
"react-native": "0.82",
|
|
20
|
+
"react-native-builder-bob": "^0.37.0",
|
|
21
|
+
"react-native-nitro-modules": "0.31.10",
|
|
22
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
23
|
+
"semantic-release": "^24.2.9",
|
|
24
|
+
"typescript": "^5.8.3"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"react": "*",
|
|
28
|
+
"react-native": "*",
|
|
29
|
+
"react-native-nitro-modules": "*"
|
|
30
|
+
},
|
|
31
|
+
"bugs": "https://github.com/vercel/aix/issues",
|
|
32
|
+
"description": "aix is a react native package built with Nitro",
|
|
33
|
+
"eslintConfig": {
|
|
34
|
+
"root": true,
|
|
35
|
+
"extends": [
|
|
36
|
+
"@react-native",
|
|
37
|
+
"prettier"
|
|
38
|
+
],
|
|
39
|
+
"plugins": [
|
|
40
|
+
"prettier"
|
|
41
|
+
],
|
|
42
|
+
"rules": {
|
|
43
|
+
"prettier/prettier": [
|
|
44
|
+
"warn",
|
|
45
|
+
{
|
|
46
|
+
"quoteProps": "consistent",
|
|
47
|
+
"singleQuote": true,
|
|
48
|
+
"tabWidth": 2,
|
|
49
|
+
"trailingComma": "es5",
|
|
50
|
+
"useTabs": false
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"eslintIgnore": [
|
|
56
|
+
"node_modules/",
|
|
57
|
+
"lib/"
|
|
58
|
+
],
|
|
59
|
+
"files": [
|
|
60
|
+
"src",
|
|
61
|
+
"react-native.config.js",
|
|
62
|
+
"lib",
|
|
63
|
+
"nitrogen",
|
|
64
|
+
"cpp",
|
|
65
|
+
"nitro.json",
|
|
66
|
+
"android/build.gradle",
|
|
67
|
+
"android/fix-prefab.gradle",
|
|
68
|
+
"android/gradle.properties",
|
|
69
|
+
"android/CMakeLists.txt",
|
|
70
|
+
"android/src",
|
|
71
|
+
"ios/**/*.h",
|
|
72
|
+
"ios/**/*.m",
|
|
73
|
+
"ios/**/*.mm",
|
|
74
|
+
"ios/**/*.cpp",
|
|
75
|
+
"ios/**/*.swift",
|
|
76
|
+
"app.plugin.js",
|
|
77
|
+
"*.podspec",
|
|
78
|
+
"README.md"
|
|
79
|
+
],
|
|
80
|
+
"homepage": "https://github.com/vercel/aix#readme",
|
|
81
|
+
"keywords": [
|
|
82
|
+
"react-native",
|
|
83
|
+
"aix"
|
|
84
|
+
],
|
|
85
|
+
"license": "MIT",
|
|
86
|
+
"prettier": {
|
|
87
|
+
"quoteProps": "consistent",
|
|
88
|
+
"singleQuote": true,
|
|
89
|
+
"tabWidth": 2,
|
|
90
|
+
"trailingComma": "es5",
|
|
91
|
+
"useTabs": false,
|
|
92
|
+
"semi": false
|
|
93
|
+
},
|
|
94
|
+
"publishConfig": {
|
|
95
|
+
"access": "public",
|
|
96
|
+
"registry": "https://registry.npmjs.org/"
|
|
97
|
+
},
|
|
98
|
+
"react-native": "src/index",
|
|
99
|
+
"react-native-builder-bob": {
|
|
100
|
+
"source": "src",
|
|
101
|
+
"output": "lib",
|
|
102
|
+
"targets": [
|
|
103
|
+
"commonjs",
|
|
104
|
+
"module",
|
|
105
|
+
[
|
|
106
|
+
"typescript",
|
|
107
|
+
{
|
|
108
|
+
"project": "tsconfig.json"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
]
|
|
12
112
|
},
|
|
13
113
|
"scripts": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
114
|
+
"typecheck": "tsc --noEmit",
|
|
115
|
+
"clean": "git clean -dfX",
|
|
116
|
+
"release": "semantic-release",
|
|
117
|
+
"build": "bun run typecheck && bob build",
|
|
118
|
+
"codegen": "nitrogen --logLevel=\"debug\" && bun run build && node post-script.js"
|
|
16
119
|
},
|
|
17
|
-
"
|
|
18
|
-
"types": "lib/index.d.ts"
|
|
120
|
+
"source": "src/index",
|
|
121
|
+
"types": "./lib/typescript/src/index.d.ts"
|
|
19
122
|
}
|
package/src/aix.tsx
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
callback,
|
|
3
|
+
getHostComponent,
|
|
4
|
+
type HybridRef,
|
|
5
|
+
} from 'react-native-nitro-modules'
|
|
6
|
+
import AixConfig from '../nitrogen/generated/shared/json/AixConfig.json'
|
|
7
|
+
import type { AixProps, AixMethods } from './views/aix.nitro'
|
|
8
|
+
import { forwardRef } from 'react'
|
|
9
|
+
|
|
10
|
+
export type AixRef = HybridRef<AixProps, AixMethods>
|
|
11
|
+
|
|
12
|
+
const AixInternal = getHostComponent<AixProps, AixMethods>(
|
|
13
|
+
'Aix',
|
|
14
|
+
() => AixConfig
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
export const Aix = forwardRef<AixRef, React.ComponentProps<typeof AixInternal>>(
|
|
18
|
+
function Aix(props, ref) {
|
|
19
|
+
return (
|
|
20
|
+
<AixInternal
|
|
21
|
+
{...props}
|
|
22
|
+
scrollOnFooterSizeUpdate={
|
|
23
|
+
props.scrollOnFooterSizeUpdate ?? {
|
|
24
|
+
enabled: true,
|
|
25
|
+
scrolledToEndThreshold: 100,
|
|
26
|
+
animated: false,
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
hybridRef={
|
|
30
|
+
ref
|
|
31
|
+
? callback((r) => {
|
|
32
|
+
if (typeof ref === 'function') {
|
|
33
|
+
ref(r)
|
|
34
|
+
} else {
|
|
35
|
+
ref.current = r
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
: undefined
|
|
39
|
+
}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useState, useRef, useEffect, useCallback } from 'react'
|
|
2
|
+
|
|
3
|
+
export function createUsePool(maxPoolSize?: number) {
|
|
4
|
+
// Use parallel arrays instead of one array for fast array operations
|
|
5
|
+
const items: object[] = []
|
|
6
|
+
const setters: ((value: boolean) => void)[] = []
|
|
7
|
+
|
|
8
|
+
const removeItem = (item: object, setInactive?: boolean) => {
|
|
9
|
+
const index = items.indexOf(item)
|
|
10
|
+
if (index !== -1) {
|
|
11
|
+
if (setInactive) {
|
|
12
|
+
setters[index]!(false)
|
|
13
|
+
}
|
|
14
|
+
items.splice(index, 1)
|
|
15
|
+
setters.splice(index, 1)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const usePool = () => {
|
|
20
|
+
// Use a stable object reference as the key
|
|
21
|
+
const item = useRef({}).current
|
|
22
|
+
const [isActive, setIsActive] = useState(true)
|
|
23
|
+
|
|
24
|
+
// A function that is stable and only changes when the item changes
|
|
25
|
+
const evict = useCallback(() => removeItem(item, true), [item])
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
items.push(item)
|
|
29
|
+
setters.push(setIsActive)
|
|
30
|
+
|
|
31
|
+
// Evict oldest item if over capacity
|
|
32
|
+
if (maxPoolSize && items.length > maxPoolSize) {
|
|
33
|
+
items.shift()
|
|
34
|
+
const evictedListener = setters.shift()!
|
|
35
|
+
evictedListener(false)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Remove from pool when unmounting
|
|
39
|
+
return () => removeItem(item)
|
|
40
|
+
}, [item])
|
|
41
|
+
|
|
42
|
+
return { isActive, evict }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return usePool
|
|
46
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react'
|
|
2
|
+
|
|
3
|
+
// Creates a staggered animation system - only one animation starts per frame/delay
|
|
4
|
+
export function createUseStaggered(delay: number) {
|
|
5
|
+
const animationQueue: (() => void)[] = []
|
|
6
|
+
let isProcessing = false
|
|
7
|
+
|
|
8
|
+
// Schedule next animation with delay or requestAnimationFrame
|
|
9
|
+
const scheduleNext = () => {
|
|
10
|
+
if (delay && delay > 0) {
|
|
11
|
+
setTimeout(processNextAnimation, delay)
|
|
12
|
+
} else {
|
|
13
|
+
requestAnimationFrame(processNextAnimation)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const processNextAnimation = () => {
|
|
18
|
+
if (animationQueue.length === 0) {
|
|
19
|
+
isProcessing = false
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Calculate how many animations to process this cycle
|
|
24
|
+
const queueLength = animationQueue.length
|
|
25
|
+
let animationsToProcess = 1
|
|
26
|
+
|
|
27
|
+
// Catch-up logic: process more animations when queue is long
|
|
28
|
+
if (queueLength > 10) {
|
|
29
|
+
animationsToProcess = Math.min(5, Math.ceil(queueLength / 4))
|
|
30
|
+
} else if (queueLength > 5) {
|
|
31
|
+
animationsToProcess = 2
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Process the calculated number of animations
|
|
35
|
+
for (let i = 0; i < animationsToProcess && animationQueue.length > 0; i++) {
|
|
36
|
+
const startAnimation = animationQueue.shift()!
|
|
37
|
+
startAnimation()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Continue processing or mark as idle
|
|
41
|
+
if (animationQueue.length > 0) {
|
|
42
|
+
scheduleNext()
|
|
43
|
+
} else {
|
|
44
|
+
isProcessing = false
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const queueAnimation = (startFn: () => void) => {
|
|
49
|
+
animationQueue.push(startFn)
|
|
50
|
+
|
|
51
|
+
if (!isProcessing) {
|
|
52
|
+
isProcessing = true
|
|
53
|
+
scheduleNext()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const useStaggered = (animationFn: () => void) => {
|
|
58
|
+
const animationRef = useRef<(() => void) | null>(animationFn)
|
|
59
|
+
|
|
60
|
+
// Queue animation on mount
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (animationRef.current) {
|
|
63
|
+
queueAnimation(animationRef.current)
|
|
64
|
+
}
|
|
65
|
+
}, [])
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const animation = animationRef.current
|
|
69
|
+
return () => {
|
|
70
|
+
// Clean up pending animation on unmount
|
|
71
|
+
if (animation) {
|
|
72
|
+
const index = animationQueue.indexOf(animation)
|
|
73
|
+
if (index !== -1) {
|
|
74
|
+
animationQueue.splice(index, 1)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, [])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return useStaggered
|
|
82
|
+
}
|