@cleartrip/ct-design-event-propagation 4.0.0-SNAPSHOT-test.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.
- package/README.md +63 -0
- package/package.json +41 -0
- package/src/index.tsx +91 -0
- package/src/type.ts +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# EventPropagation
|
|
2
|
+
|
|
3
|
+
A utility component for managing event propagation behavior.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @cleartrip/ct-design-event-propagation
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @cleartrip/ct-design-event-propagation
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Peer dependencies
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Required for all targets
|
|
19
|
+
npm install react
|
|
20
|
+
|
|
21
|
+
# Web only
|
|
22
|
+
npm install react-dom
|
|
23
|
+
|
|
24
|
+
# React Native only
|
|
25
|
+
npm install react-native
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Basic
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { EventPropagation } from '@cleartrip/ct-design-event-propagation';
|
|
36
|
+
|
|
37
|
+
function Example() {
|
|
38
|
+
return (
|
|
39
|
+
<EventPropagation>
|
|
40
|
+
{/* Basic usage */}
|
|
41
|
+
</EventPropagation>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Accessibility
|
|
49
|
+
|
|
50
|
+
- The component follows accessibility best practices
|
|
51
|
+
- Ensure proper ARIA attributes are provided where needed
|
|
52
|
+
- Test with screen readers to ensure usability
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Migration
|
|
57
|
+
|
|
58
|
+
If migrating from a previous version:
|
|
59
|
+
|
|
60
|
+
```diff
|
|
61
|
+
- import { EventPropagation } from 'yagami/core/components';
|
|
62
|
+
+ import { EventPropagation } from '@cleartrip/ct-design-event-propagation';
|
|
63
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cleartrip/ct-design-event-propagation",
|
|
3
|
+
"version": "4.0.0-SNAPSHOT-test.0",
|
|
4
|
+
"description": "Event Propagation Component",
|
|
5
|
+
"main": "./src/index.tsx",
|
|
6
|
+
"module": "src/index.tsx",
|
|
7
|
+
"jsnext:main": "src/index.tsx",
|
|
8
|
+
"react-native": "src/index.tsx",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./src/index.tsx",
|
|
13
|
+
"import": "./src/index.tsx",
|
|
14
|
+
"default": "./src/index.tsx"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"src"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@cleartrip/ct-design-theme": "4.0.0-SNAPSHOT-test.0"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": ">=16.8.0",
|
|
25
|
+
"react-dom": ">=16.8.0"
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"author": "Cleartrip",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"minimatch": "^10.2.5"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
37
|
+
"watch-package": "tsc -p tsconfig.json -w",
|
|
38
|
+
"build-package": "tsc -p tsconfig.json",
|
|
39
|
+
"build-package:clean": "tsc -p tsconfig.json"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createContext, useCallback, useContext, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Keyboard } from 'react-native';
|
|
4
|
+
import { makeMutable } from 'react-native-reanimated';
|
|
5
|
+
|
|
6
|
+
import { EventFunction, IEventCollectorProviderProps, IEvents, INativeUIEvent } from './type';
|
|
7
|
+
|
|
8
|
+
export const EventCollector = createContext<IEvents>({});
|
|
9
|
+
|
|
10
|
+
export const useEventCollector = () => {
|
|
11
|
+
const events = useContext(EventCollector);
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
events,
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const filterEvents = (eventValue: EventFunction[]) => {
|
|
19
|
+
const filteredEvents = eventValue.filter((event) => {
|
|
20
|
+
return typeof event !== 'undefined';
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return filteredEvents;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const useMergeEvents = (additionalEvents: IEvents) => {
|
|
27
|
+
const { events = {} } = useEventCollector();
|
|
28
|
+
|
|
29
|
+
const mergedEvents = useMemo(() => {
|
|
30
|
+
const updatedEvents: IEvents = {};
|
|
31
|
+
|
|
32
|
+
for (const [eventName, eventValue] of Object.entries(events)) {
|
|
33
|
+
updatedEvents[eventName] = filterEvents(eventValue);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (const [eventName, eventValue] of Object.entries(additionalEvents)) {
|
|
37
|
+
if (updatedEvents.hasOwnProperty(eventName)) {
|
|
38
|
+
const filteredEvents = filterEvents(eventValue);
|
|
39
|
+
updatedEvents[eventName] = [...updatedEvents[eventName], ...filteredEvents];
|
|
40
|
+
} else {
|
|
41
|
+
updatedEvents[eventName] = filterEvents(eventValue);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return updatedEvents;
|
|
46
|
+
}, [additionalEvents, events]);
|
|
47
|
+
|
|
48
|
+
return mergedEvents;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Handling special ios scenario
|
|
53
|
+
*/
|
|
54
|
+
export const isCarouselSwiping = makeMutable(false);
|
|
55
|
+
|
|
56
|
+
export const useTriggerEvents = (events: IEvents) => {
|
|
57
|
+
const { onClick: onClickEvents = [] } = events ?? {};
|
|
58
|
+
|
|
59
|
+
const onClick = useCallback(
|
|
60
|
+
(e: INativeUIEvent) => {
|
|
61
|
+
if (isCarouselSwiping.value) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
Keyboard.dismiss();
|
|
65
|
+
let stopPropagationValue = false;
|
|
66
|
+
e.stopPropagation = () => {
|
|
67
|
+
stopPropagationValue = true;
|
|
68
|
+
};
|
|
69
|
+
for (let i = onClickEvents.length - 1; i >= 0; i--) {
|
|
70
|
+
const event = onClickEvents[i];
|
|
71
|
+
if (typeof event === 'function') {
|
|
72
|
+
if (stopPropagationValue) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
event?.(e);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
[onClickEvents],
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
onClick,
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const EventCollectorProvider = ({ children, value = {} }: IEventCollectorProviderProps) => {
|
|
88
|
+
return <EventCollector.Provider value={value}>{children}</EventCollector.Provider>;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export default EventCollectorProvider;
|
package/src/type.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface INativeUIEvent {
|
|
2
|
+
stopPropagation?: () => void;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export type EventFunction = ((e: INativeUIEvent) => void) | undefined;
|
|
6
|
+
|
|
7
|
+
export interface IEvents {
|
|
8
|
+
[key: string]: EventFunction[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IEventCollectorProviderProps {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
value?: IEvents;
|
|
14
|
+
}
|