react-native-external-keyboard 0.6.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +37 -129
  2. package/android/src/main/java/com/externalkeyboard/ExternalKeyboardViewPackage.java +2 -0
  3. package/android/src/main/java/com/externalkeyboard/helper/FocusHelper.java +70 -0
  4. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockView.java +115 -0
  5. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/ExternalKeyboardLockViewManager.java +32 -0
  6. package/android/src/main/java/com/externalkeyboard/views/ExternalKeyboardLockView/LockService.java +44 -0
  7. package/android/src/newarch/ExternalKeyboardLockViewManagerSpec.java +8 -0
  8. package/android/src/oldarch/ExternalKeyboardLockViewManagerSpec.java +12 -0
  9. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.h +36 -0
  10. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusGuideDelegate/RNCEKVFocusGuideDelegate.mm +150 -0
  11. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.h +14 -0
  12. package/ios/Delegates/RNCEKVFocusOrderDelegate/RNCEKVFocusOrderDelegate.mm +98 -349
  13. package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.h +1 -1
  14. package/ios/Extensions/RCTTextInputComponentView+RNCEKVExternalKeyboard.mm +11 -3
  15. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.h +1 -1
  16. package/ios/Extensions/UIViewController+RNCEKVExternalKeyboard.mm +17 -17
  17. package/ios/Helpers/RNCEKVFocusGuideHelper/RNCEKVFocusGuideHelper.h +32 -0
  18. package/ios/Helpers/RNCEKVFocusGuideHelper/RNCEKVFocusGuideHelper.mm +81 -0
  19. package/ios/Helpers/RNCEKVSwizzlingHelper/RNCEKVSwizzlingHelper.h +16 -0
  20. package/ios/Helpers/RNCEKVSwizzlingHelper/RNCEKVSwizzlingHelper.mm +27 -0
  21. package/ios/Modules/RNCEKVExternalKeyboardModule.mm +3 -3
  22. package/ios/Services/RNCEKVFocusLinkObserver.h +7 -1
  23. package/ios/Services/RNCEKVFocusLinkObserver.mm +31 -6
  24. package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.h +17 -0
  25. package/ios/Services/RNCEKVKeyboardOrderManager/RNCEKVKeyboardOrderManager.mm +15 -0
  26. package/ios/Services/{RNCEKVRelashioship.h → RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVOrderRelationship.h} +8 -7
  27. package/ios/Services/{RNCEKVRelashioship.mm → RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVOrderRelationship.mm} +36 -13
  28. package/ios/Services/RNCEKVOrderLinking.h +2 -7
  29. package/ios/Services/RNCEKVOrderLinking.mm +27 -64
  30. package/ios/Services/RNCEKVOrderSubscriber.h +4 -3
  31. package/ios/Services/RNCEKVOrderSubscriber.mm +2 -1
  32. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.h +38 -0
  33. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockView.mm +62 -0
  34. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockViewManager.h +14 -0
  35. package/ios/Views/RNCEKVExternalKeyboardLockView/RNCEKVExternalKeyboardLockViewManager.mm +25 -0
  36. package/ios/Views/RNCEKVExternalKeyboardView/RNCEKVExternalKeyboardView.mm +2 -2
  37. package/ios/Views/RNCEKVKeyboardFocusGroupView/RNCEKVKeyboardFocusGroup.mm +0 -1
  38. package/ios/Views/RNCEKVTextInputFocusWrapper/RNCEKVTextInputFocusWrapper.mm +1 -15
  39. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js +21 -0
  40. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js.map +1 -0
  41. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.js +11 -0
  42. package/lib/commonjs/components/KeyboardFocusLock/FocusFrame/FocusFrame.js.map +1 -0
  43. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js +19 -0
  44. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js.map +1 -0
  45. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +15 -0
  46. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -0
  47. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.js +46 -0
  48. package/lib/commonjs/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.js.map +1 -0
  49. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +21 -0
  50. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +1 -0
  51. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +9 -0
  52. package/lib/commonjs/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -0
  53. package/lib/commonjs/context/FocusFrameProviderContext.js +28 -0
  54. package/lib/commonjs/context/FocusFrameProviderContext.js.map +1 -0
  55. package/lib/commonjs/index.js +7 -1
  56. package/lib/commonjs/index.js.map +1 -1
  57. package/lib/commonjs/nativeSpec/ExternalKeyboardLockViewNativeComponent.js +10 -0
  58. package/lib/commonjs/nativeSpec/ExternalKeyboardLockViewNativeComponent.js.map +1 -0
  59. package/lib/commonjs/types/KeyboardFocusLock.types.js +6 -0
  60. package/lib/commonjs/types/KeyboardFocusLock.types.js.map +1 -0
  61. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js +14 -0
  62. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.js.map +1 -0
  63. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.js +4 -0
  64. package/lib/module/components/KeyboardFocusLock/FocusFrame/FocusFrame.js.map +1 -0
  65. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js +12 -0
  66. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.js.map +1 -0
  67. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js +8 -0
  68. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrap.js.map +1 -0
  69. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.js +39 -0
  70. package/lib/module/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.js.map +1 -0
  71. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js +14 -0
  72. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.js.map +1 -0
  73. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js +3 -0
  74. package/lib/module/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.js.map +1 -0
  75. package/lib/module/context/FocusFrameProviderContext.js +20 -0
  76. package/lib/module/context/FocusFrameProviderContext.js.map +1 -0
  77. package/lib/module/index.js +6 -0
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/nativeSpec/ExternalKeyboardLockViewNativeComponent.js +3 -0
  80. package/lib/module/nativeSpec/ExternalKeyboardLockViewNativeComponent.js.map +1 -0
  81. package/lib/module/types/KeyboardFocusLock.types.js +2 -0
  82. package/lib/module/types/KeyboardFocusLock.types.js.map +1 -0
  83. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.d.ts +4 -0
  84. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.d.ts.map +1 -0
  85. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.d.ts +3 -0
  86. package/lib/typescript/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.d.ts.map +1 -0
  87. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.d.ts +4 -0
  88. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.d.ts.map +1 -0
  89. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts +3 -0
  90. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.d.ts.map +1 -0
  91. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.d.ts +3 -0
  92. package/lib/typescript/src/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.d.ts.map +1 -0
  93. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts +4 -0
  94. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.d.ts.map +1 -0
  95. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts +3 -0
  96. package/lib/typescript/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.d.ts.map +1 -0
  97. package/lib/typescript/src/components/Touchable/Pressable.d.ts +1 -1
  98. package/lib/typescript/src/context/FocusFrameProviderContext.d.ts +12 -0
  99. package/lib/typescript/src/context/FocusFrameProviderContext.d.ts.map +1 -0
  100. package/lib/typescript/src/index.d.ts +4 -0
  101. package/lib/typescript/src/index.d.ts.map +1 -1
  102. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts +9 -0
  103. package/lib/typescript/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.d.ts.map +1 -0
  104. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts +6 -0
  105. package/lib/typescript/src/types/KeyboardFocusLock.types.d.ts.map +1 -0
  106. package/lib/typescript/src/utils/withKeyboardFocus.d.ts +1 -1
  107. package/package.json +4 -3
  108. package/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.tsx +18 -0
  109. package/src/components/KeyboardFocusLock/FocusFrame/FocusFrame.tsx +8 -0
  110. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.tsx +17 -0
  111. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrap.tsx +9 -0
  112. package/src/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.ts +40 -0
  113. package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.tsx +16 -0
  114. package/src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.tsx +5 -0
  115. package/src/context/FocusFrameProviderContext.tsx +36 -0
  116. package/src/index.tsx +8 -0
  117. package/src/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts +13 -0
  118. package/src/types/KeyboardFocusLock.types.ts +6 -0
  119. package/ios/Services/RNCEKVFocusLinkObserverManager.h +0 -23
  120. package/ios/Services/RNCEKVFocusLinkObserverManager.mm +0 -30
  121. /package/ios/Services/{RNCEKVSortedMap.h → RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVSortedMap/RNCEKVSortedMap.h} +0 -0
  122. /package/ios/Services/{RNCEKVSortedMap.mm → RNCEKVKeyboardOrderManager/RNCEKVOrderRelationship/RNCEKVSortedMap/RNCEKVSortedMap.mm} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","useMemo","createContext","useContext","useState","FocusFrameProviderContext","undefined","useFocusFrameContext","FrameProvider","children","hasFocusLock","setHasFocusLock","focusLockId","setFocusLockId","state","createElement","Provider","value"],"sourceRoot":"../../../src","sources":["context/FocusFrameProviderContext.tsx"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SACEC,aAAa,EACbC,UAAU,EACVC,QAAQ,QAEH,OAAO;AASd,MAAMC,yBAAyB,gBAAGH,aAAa,CAE7CI,SAAS,CAAC;AAEZ,OAAO,MAAMC,oBAAoB,GAAGA,CAAA,KAAMJ,UAAU,CAACE,yBAAyB,CAAC;AAE/E,OAAO,MAAMG,aAA0C,GAAGA,CAAC;EAAEC;AAAS,CAAC,KAAK;EAC1E,MAAM,CAACC,YAAY,EAAEC,eAAe,CAAC,GAAGP,QAAQ,CAAC,KAAK,CAAC;EACvD,MAAM,CAACQ,WAAW,EAAEC,cAAc,CAAC,GAAGT,QAAQ,CAAgB,IAAI,CAAC;EAEnE,MAAMU,KAAK,GAAGb,OAAO,CACnB,OAAO;IAAES,YAAY;IAAEE,WAAW;IAAED,eAAe;IAAEE;EAAe,CAAC,CAAC,EACtE,CAACH,YAAY,EAAEE,WAAW,EAAED,eAAe,EAAEE,cAAc,CAC7D,CAAC;EAED,oBACEb,KAAA,CAAAe,aAAA,CAACV,yBAAyB,CAACW,QAAQ;IAACC,KAAK,EAAEH;EAAM,GAC9CL,QACiC,CAAC;AAEzC,CAAC","ignoreList":[]}
@@ -1,3 +1,5 @@
1
+ import { FocusFrame } from './components/KeyboardFocusLock/FocusFrame/FocusFrame';
2
+ import { FocusTrap } from './components/KeyboardFocusLock/FocusTrap/FocusTrap';
1
3
  export { ExternalKeyboardViewNative, TextInputFocusWrapperNative } from './nativeSpec';
2
4
  export { BaseKeyboardView, KeyboardFocusView, ExternalKeyboardView, KeyboardExtendedView, KeyboardExtendedBaseView } from './components';
3
5
  export { Pressable, Pressable as KeyboardExtendedPressable } from './components/Touchable/Pressable';
@@ -8,4 +10,8 @@ export { useIsViewFocused } from './context/IsViewFocusedContext';
8
10
  export { KeyboardOrderFocusGroup, OrderFocusGroupContext, useOrderFocusGroup } from './context/OrderFocusContext';
9
11
  import * as Keyboard from './modules/Keyboard';
10
12
  export { Keyboard };
13
+ export const Focus = {
14
+ Frame: FocusFrame,
15
+ Trap: FocusTrap
16
+ };
11
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["ExternalKeyboardViewNative","TextInputFocusWrapperNative","BaseKeyboardView","KeyboardFocusView","ExternalKeyboardView","KeyboardExtendedView","KeyboardExtendedBaseView","Pressable","KeyboardExtendedPressable","KeyboardExtendedInput","TextInput","KeyboardFocusGroup","withKeyboardFocus","useIsViewFocused","KeyboardOrderFocusGroup","OrderFocusGroupContext","useOrderFocusGroup","Keyboard"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SACEA,0BAA0B,EAC1BC,2BAA2B,QAEtB,cAAc;AAUrB,SACEC,gBAAgB,EAChBC,iBAAiB,EACjBC,oBAAoB,EACpBC,oBAAoB,EACpBC,wBAAwB,QACnB,cAAc;AACrB,SACEC,SAAS,EACTA,SAAS,IAAIC,yBAAyB,QACjC,kCAAkC;AACzC,SACEC,qBAAqB,EACrBA,qBAAqB,IAAIC,SAAS,QAC7B,0DAA0D;AACjE,SAASC,kBAAkB,QAAQ,oDAAoD;AACvF,SAASC,iBAAiB,QAAQ,2BAA2B;AAC7D,SAASC,gBAAgB,QAAQ,gCAAgC;AACjE,SACEC,uBAAuB,EACvBC,sBAAsB,EACtBC,kBAAkB,QACb,6BAA6B;AACpC,OAAO,KAAKC,QAAQ,MAAM,oBAAoB;AAC9C,SAASA,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["FocusFrame","FocusTrap","ExternalKeyboardViewNative","TextInputFocusWrapperNative","BaseKeyboardView","KeyboardFocusView","ExternalKeyboardView","KeyboardExtendedView","KeyboardExtendedBaseView","Pressable","KeyboardExtendedPressable","KeyboardExtendedInput","TextInput","KeyboardFocusGroup","withKeyboardFocus","useIsViewFocused","KeyboardOrderFocusGroup","OrderFocusGroupContext","useOrderFocusGroup","Keyboard","Focus","Frame","Trap"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,UAAU,QAAQ,sDAAsD;AACjF,SAASC,SAAS,QAAQ,oDAAoD;AAE9E,SACEC,0BAA0B,EAC1BC,2BAA2B,QAEtB,cAAc;AAUrB,SACEC,gBAAgB,EAChBC,iBAAiB,EACjBC,oBAAoB,EACpBC,oBAAoB,EACpBC,wBAAwB,QACnB,cAAc;AACrB,SACEC,SAAS,EACTA,SAAS,IAAIC,yBAAyB,QACjC,kCAAkC;AACzC,SACEC,qBAAqB,EACrBA,qBAAqB,IAAIC,SAAS,QAC7B,0DAA0D;AACjE,SAASC,kBAAkB,QAAQ,oDAAoD;AACvF,SAASC,iBAAiB,QAAQ,2BAA2B;AAC7D,SAASC,gBAAgB,QAAQ,gCAAgC;AACjE,SACEC,uBAAuB,EACvBC,sBAAsB,EACtBC,kBAAkB,QACb,6BAA6B;AACpC,OAAO,KAAKC,QAAQ,MAAM,oBAAoB;AAC9C,SAASA,QAAQ;AAEjB,OAAO,MAAMC,KAAK,GAAG;EACnBC,KAAK,EAAErB,UAAU;EACjBsB,IAAI,EAAErB;AACR,CAAC","ignoreList":[]}
@@ -0,0 +1,3 @@
1
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
2
+ export default codegenNativeComponent('ExternalKeyboardLockView');
3
+ //# sourceMappingURL=ExternalKeyboardLockViewNativeComponent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["codegenNativeComponent"],"sourceRoot":"../../../src","sources":["nativeSpec/ExternalKeyboardLockViewNativeComponent.ts"],"mappings":"AAEA,OAAOA,sBAAsB,MAAM,yDAAyD;AAQ5F,eAAeA,sBAAsB,CACnC,0BACF,CAAC","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=KeyboardFocusLock.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["types/KeyboardFocusLock.types.ts"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
3
+ export declare const FocusFrame: React.NamedExoticComponent<KeyboardFocusLockProps>;
4
+ //# sourceMappingURL=FocusFrame.android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusFrame.android.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/FocusFrame/FocusFrame.android.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAErF,eAAO,MAAM,UAAU,oDAYtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ViewProps } from 'react-native';
2
+ export declare const FocusFrame: (props: ViewProps) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=FocusFrame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusFrame.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/FocusFrame/FocusFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGpD,eAAO,MAAM,UAAU,GAAI,OAAO,SAAS,4CAI1C,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
3
+ export declare const FocusTrap: React.NamedExoticComponent<KeyboardFocusLockProps>;
4
+ //# sourceMappingURL=FocusTrap.android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusTrap.android.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/FocusTrap/FocusTrap.android.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAErF,eAAO,MAAM,SAAS,oDAUrB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
2
+ export declare const FocusTrap: (props: KeyboardFocusLockProps) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=FocusTrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusTrap.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/FocusTrap/FocusTrap.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAErF,eAAO,MAAM,SAAS,GAAI,OAAO,sBAAsB,4CAItD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ export declare const FocusTrapMountWrapper: React.FC<PropsWithChildren>;
3
+ //# sourceMappingURL=FocusTrapMountWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusTrapMountWrapper.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/FocusTrap/FocusTrapMountWrapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAGlE,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAoC7D,CAAC"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
3
+ export declare const KeyboardFocusLockBase: React.NamedExoticComponent<KeyboardFocusLockProps>;
4
+ //# sourceMappingURL=KeyboardFocusLockBase.android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyboardFocusLockBase.android.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.android.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAErF,eAAO,MAAM,qBAAqB,oDAUjC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
2
+ export declare const KeyboardFocusLockBase: React.ExoticComponent<KeyboardFocusLockProps>;
3
+ //# sourceMappingURL=KeyboardFocusLockBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyboardFocusLockBase.d.ts","sourceRoot":"","sources":["../../../../../../src/components/KeyboardFocusLock/KeyboardFocusLockBase/KeyboardFocusLockBase.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAErF,eAAO,MAAM,qBAAqB,EACb,KAAK,CAAC,eAAe,CAAC,sBAAsB,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const Pressable: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<import("../../utils/withKeyboardFocus").WithKeyboardFocus<unknown, unknown, import("react-native").PressableProps & import("react").RefAttributes<import("react-native").View>, unknown>, "ref"> & import("react").RefAttributes<import("../..").KeyboardFocus | import("react-native").View>>>;
1
+ export declare const Pressable: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<Omit<import("../../utils/withKeyboardFocus").WithKeyboardFocus<unknown, unknown, import("react-native").PressableProps & import("react").RefAttributes<import("react-native").View>, unknown>, "ref"> & import("react").RefAttributes<import("react-native").View | import("../..").KeyboardFocus>>>;
2
2
  //# sourceMappingURL=Pressable.d.ts.map
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { type PropsWithChildren } from 'react';
3
+ type FocusFrameContextType = {
4
+ hasFocusLock: boolean;
5
+ setHasFocusLock: (v: boolean) => void;
6
+ focusLockId: symbol | null;
7
+ setFocusLockId: (v: symbol | null) => void;
8
+ };
9
+ export declare const useFocusFrameContext: () => FocusFrameContextType | undefined;
10
+ export declare const FrameProvider: React.FC<PropsWithChildren>;
11
+ export {};
12
+ //# sourceMappingURL=FocusFrameProviderContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FocusFrameProviderContext.d.ts","sourceRoot":"","sources":["../../../../src/context/FocusFrameProviderContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AAEf,KAAK,qBAAqB,GAAG;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC5C,CAAC;AAMF,eAAO,MAAM,oBAAoB,yCAA8C,CAAC;AAEhF,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAcrD,CAAC"}
@@ -10,4 +10,8 @@ export { useIsViewFocused } from './context/IsViewFocusedContext';
10
10
  export { KeyboardOrderFocusGroup, OrderFocusGroupContext, useOrderFocusGroup, } from './context/OrderFocusContext';
11
11
  import * as Keyboard from './modules/Keyboard';
12
12
  export { Keyboard };
13
+ export declare const Focus: {
14
+ Frame: (props: import("react-native").ViewProps) => import("react/jsx-runtime").JSX.Element;
15
+ Trap: (props: import("./types/KeyboardFocusLock.types").KeyboardFocusLockProps) => import("react/jsx-runtime").JSX.Element;
16
+ };
13
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,UAAU,EACV,aAAa,EACb,oBAAoB,IAAI,wBAAwB,GACjD,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,SAAS,EACT,SAAS,IAAI,yBAAyB,GACvC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,qBAAqB,EACrB,qBAAqB,IAAI,SAAS,GACnC,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,UAAU,EACV,aAAa,EACb,oBAAoB,IAAI,wBAAwB,GACjD,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,SAAS,EACT,SAAS,IAAI,yBAAyB,GACvC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,qBAAqB,EACrB,qBAAqB,IAAI,SAAS,GACnC,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,eAAO,MAAM,KAAK;;;CAGjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ViewProps } from 'react-native';
2
+ import type { Int32 } from 'react-native/Libraries/Types/CodegenTypes';
3
+ export interface ExternalKeyboardLockViewNativeComponentProps extends ViewProps {
4
+ componentType: Int32;
5
+ lockDisabled?: boolean;
6
+ }
7
+ declare const _default: import("react-native/Libraries/Utilities/codegenNativeComponent").NativeComponentType<ExternalKeyboardLockViewNativeComponentProps>;
8
+ export default _default;
9
+ //# sourceMappingURL=ExternalKeyboardLockViewNativeComponent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExternalKeyboardLockViewNativeComponent.d.ts","sourceRoot":"","sources":["../../../../src/nativeSpec/ExternalKeyboardLockViewNativeComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2CAA2C,CAAC;AAGvE,MAAM,WAAW,4CACf,SAAQ,SAAS;IACjB,aAAa,EAAE,KAAK,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;;AAED,wBAEE"}
@@ -0,0 +1,6 @@
1
+ import type { ViewProps } from 'react-native';
2
+ export type KeyboardFocusLockProps = ViewProps & {
3
+ componentType?: number;
4
+ lockDisabled?: boolean;
5
+ };
6
+ //# sourceMappingURL=KeyboardFocusLock.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyboardFocusLock.types.d.ts","sourceRoot":"","sources":["../../../../src/types/KeyboardFocusLock.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC"}
@@ -21,5 +21,5 @@ export type WithKeyboardProps<R> = {
21
21
  style?: PressableProps['style'];
22
22
  };
23
23
  export type WithKeyboardFocus<K, T, C, R> = C & KeyboardPressType<K, T> & FocusViewProps & WithKeyboardProps<R>;
24
- export declare const withKeyboardFocus: <K, T, C extends {}, R>(Component: React.ComponentType<C>) => React.MemoExoticComponent<React.ForwardRefExoticComponent<React.PropsWithoutRef<WithKeyboardFocus<K, T, C, R>> & React.RefAttributes<KeyboardFocus | View>>>;
24
+ export declare const withKeyboardFocus: <K, T, C extends {}, R>(Component: React.ComponentType<C>) => React.MemoExoticComponent<React.ForwardRefExoticComponent<React.PropsWithoutRef<WithKeyboardFocus<K, T, C, R>> & React.RefAttributes<View | KeyboardFocus>>>;
25
25
  //# sourceMappingURL=withKeyboardFocus.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-external-keyboard",
3
- "version": "0.6.8",
3
+ "version": "0.7.0",
4
4
  "description": "Toolkit for improving physical keyboard support in React Native",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -112,7 +112,7 @@
112
112
  },
113
113
  "plugins": {
114
114
  "@release-it/conventional-changelog": {
115
- "preset": "angular"
115
+ "preset": "conventionalcommits"
116
116
  }
117
117
  }
118
118
  },
@@ -169,7 +169,8 @@
169
169
  "componentProvider": {
170
170
  "ExternalKeyboardView": "RNCEKVExternalKeyboardView",
171
171
  "KeyboardFocusGroup": "RNCEKVKeyboardFocusGroup",
172
- "TextInputFocusWrapper": "RNCEKVTextInputFocusWrapper"
172
+ "TextInputFocusWrapper": "RNCEKVTextInputFocusWrapper",
173
+ "ExternalKeyboardLockView": "RNCEKVExternalKeyboardLockView"
173
174
  }
174
175
  }
175
176
  }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { FrameProvider } from '../../../context/FocusFrameProviderContext';
3
+ import { KeyboardFocusLockBase } from '../KeyboardFocusLockBase/KeyboardFocusLockBase';
4
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
5
+
6
+ export const FocusFrame = React.memo<KeyboardFocusLockProps>(
7
+ ({ lockDisabled = false, ...props }) => {
8
+ return (
9
+ <FrameProvider>
10
+ <KeyboardFocusLockBase
11
+ {...props}
12
+ componentType={1}
13
+ lockDisabled={lockDisabled}
14
+ />
15
+ </FrameProvider>
16
+ );
17
+ }
18
+ );
@@ -0,0 +1,8 @@
1
+ import { View, type ViewProps } from 'react-native';
2
+ import { FrameProvider } from '../../../context/FocusFrameProviderContext';
3
+
4
+ export const FocusFrame = (props: ViewProps) => (
5
+ <FrameProvider>
6
+ <View {...props} />
7
+ </FrameProvider>
8
+ );
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+
3
+ import { FocusTrapMountWrapper } from './FocusTrapMountWrapper';
4
+ import { KeyboardFocusLockBase } from '../KeyboardFocusLockBase/KeyboardFocusLockBase';
5
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
6
+
7
+ export const FocusTrap = React.memo<KeyboardFocusLockProps>(
8
+ ({ lockDisabled = false, ...props }) => (
9
+ <FocusTrapMountWrapper>
10
+ <KeyboardFocusLockBase
11
+ {...props}
12
+ componentType={0}
13
+ lockDisabled={lockDisabled}
14
+ />
15
+ </FocusTrapMountWrapper>
16
+ )
17
+ );
@@ -0,0 +1,9 @@
1
+ import { View } from 'react-native';
2
+ import { FocusTrapMountWrapper } from './FocusTrapMountWrapper';
3
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
4
+
5
+ export const FocusTrap = (props: KeyboardFocusLockProps) => (
6
+ <FocusTrapMountWrapper>
7
+ <View collapsable={false} accessibilityViewIsModal={true} {...props} />
8
+ </FocusTrapMountWrapper>
9
+ );
@@ -0,0 +1,40 @@
1
+ import { useEffect, useRef, type PropsWithChildren } from 'react';
2
+ import { useFocusFrameContext } from '../../../context/FocusFrameProviderContext';
3
+
4
+ export const FocusTrapMountWrapper: React.FC<PropsWithChildren> = ({
5
+ children,
6
+ }) => {
7
+ const a11yFrameContext = useFocusFrameContext();
8
+ const instanceId = useRef(Symbol('FocusLock'));
9
+
10
+ if (!a11yFrameContext) {
11
+ console.warn('Focus.Trap must be used within a Focus.Frame');
12
+ return children;
13
+ }
14
+
15
+ const { hasFocusLock, setHasFocusLock, focusLockId, setFocusLockId } =
16
+ a11yFrameContext;
17
+ const isActive = !hasFocusLock || focusLockId === instanceId.current;
18
+
19
+ // eslint-disable-next-line react-hooks/rules-of-hooks
20
+ useEffect(() => {
21
+ const id = instanceId.current;
22
+
23
+ if (!hasFocusLock) {
24
+ setHasFocusLock(true);
25
+ setFocusLockId(id);
26
+ }
27
+ return () => {
28
+ if (focusLockId === id) {
29
+ setHasFocusLock(false);
30
+ setFocusLockId(null);
31
+ }
32
+ };
33
+ }, [hasFocusLock, setHasFocusLock, focusLockId, setFocusLockId]);
34
+
35
+ if (!isActive) {
36
+ console.warn('Multiple Focus.Trap components may cause unstable behavior');
37
+ }
38
+
39
+ return children;
40
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import ExternalKeyboardLockView from '../../../nativeSpec/ExternalKeyboardLockViewNativeComponent';
3
+
4
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
5
+
6
+ export const KeyboardFocusLockBase = React.memo<KeyboardFocusLockProps>(
7
+ ({ lockDisabled = false, componentType = 0, ...props }) => {
8
+ return (
9
+ <ExternalKeyboardLockView
10
+ {...props}
11
+ componentType={componentType}
12
+ lockDisabled={lockDisabled}
13
+ />
14
+ );
15
+ }
16
+ );
@@ -0,0 +1,5 @@
1
+ import { View } from 'react-native';
2
+ import type { KeyboardFocusLockProps } from '../../../types/KeyboardFocusLock.types';
3
+
4
+ export const KeyboardFocusLockBase =
5
+ View as unknown as React.ExoticComponent<KeyboardFocusLockProps>;
@@ -0,0 +1,36 @@
1
+ import React, { useMemo } from 'react';
2
+ import {
3
+ createContext,
4
+ useContext,
5
+ useState,
6
+ type PropsWithChildren,
7
+ } from 'react';
8
+
9
+ type FocusFrameContextType = {
10
+ hasFocusLock: boolean;
11
+ setHasFocusLock: (v: boolean) => void;
12
+ focusLockId: symbol | null;
13
+ setFocusLockId: (v: symbol | null) => void;
14
+ };
15
+
16
+ const FocusFrameProviderContext = createContext<
17
+ FocusFrameContextType | undefined
18
+ >(undefined);
19
+
20
+ export const useFocusFrameContext = () => useContext(FocusFrameProviderContext);
21
+
22
+ export const FrameProvider: React.FC<PropsWithChildren> = ({ children }) => {
23
+ const [hasFocusLock, setHasFocusLock] = useState(false);
24
+ const [focusLockId, setFocusLockId] = useState<symbol | null>(null);
25
+
26
+ const state = useMemo(
27
+ () => ({ hasFocusLock, focusLockId, setHasFocusLock, setFocusLockId }),
28
+ [hasFocusLock, focusLockId, setHasFocusLock, setFocusLockId]
29
+ );
30
+
31
+ return (
32
+ <FocusFrameProviderContext.Provider value={state}>
33
+ {children}
34
+ </FocusFrameProviderContext.Provider>
35
+ );
36
+ };
package/src/index.tsx CHANGED
@@ -1,3 +1,6 @@
1
+ import { FocusFrame } from './components/KeyboardFocusLock/FocusFrame/FocusFrame';
2
+ import { FocusTrap } from './components/KeyboardFocusLock/FocusTrap/FocusTrap';
3
+
1
4
  export {
2
5
  ExternalKeyboardViewNative,
3
6
  TextInputFocusWrapperNative,
@@ -37,3 +40,8 @@ export {
37
40
  } from './context/OrderFocusContext';
38
41
  import * as Keyboard from './modules/Keyboard';
39
42
  export { Keyboard };
43
+
44
+ export const Focus = {
45
+ Frame: FocusFrame,
46
+ Trap: FocusTrap,
47
+ };
@@ -0,0 +1,13 @@
1
+ import type { ViewProps } from 'react-native';
2
+ import type { Int32 } from 'react-native/Libraries/Types/CodegenTypes';
3
+ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
4
+
5
+ export interface ExternalKeyboardLockViewNativeComponentProps
6
+ extends ViewProps {
7
+ componentType: Int32;
8
+ lockDisabled?: boolean;
9
+ }
10
+
11
+ export default codegenNativeComponent<ExternalKeyboardLockViewNativeComponentProps>(
12
+ 'ExternalKeyboardLockView'
13
+ );
@@ -0,0 +1,6 @@
1
+ import type { ViewProps } from 'react-native';
2
+
3
+ export type KeyboardFocusLockProps = ViewProps & {
4
+ componentType?: number;
5
+ lockDisabled?: boolean;
6
+ };
@@ -1,23 +0,0 @@
1
- //
2
- // RNCEKVFocusLinkObserverManager.h
3
- // Pods
4
- //
5
- // Created by Artur Kalach on 26/06/2025.
6
- //
7
-
8
- #ifndef RNCEKVFocusLinkObserverManager_h
9
- #define RNCEKVFocusLinkObserverManager_h
10
-
11
- #import <Foundation/Foundation.h>
12
- #import "RNCEKVFocusLinkObserver.h"
13
-
14
- @interface RNCEKVFocusLinkObserverManager : NSObject
15
-
16
- @property (nonatomic, strong, readonly) RNCEKVFocusLinkObserver *focusLinkObserver;
17
-
18
- + (instancetype)sharedManager;
19
-
20
- @end
21
-
22
-
23
- #endif /* RNCEKVFocusLinkObserverManager_h */
@@ -1,30 +0,0 @@
1
- //
2
- // RNCEKVFocusLinkObserverManager.m
3
- // react-native-external-keyboard
4
- //
5
- // Created by Artur Kalach on 26/06/2025.
6
- //
7
-
8
- #import <Foundation/Foundation.h>
9
- #import "RNCEKVFocusLinkObserverManager.h"
10
-
11
- @implementation RNCEKVFocusLinkObserverManager
12
-
13
- + (instancetype)sharedManager {
14
- static RNCEKVFocusLinkObserverManager *sharedInstance = nil;
15
- static dispatch_once_t onceToken;
16
- dispatch_once(&onceToken, ^{
17
- sharedInstance = [[self alloc] init];
18
- });
19
- return sharedInstance;
20
- }
21
-
22
- - (instancetype)init {
23
- self = [super init];
24
- if (self) {
25
- _focusLinkObserver = [[RNCEKVFocusLinkObserver alloc] init];
26
- }
27
- return self;
28
- }
29
-
30
- @end