@cleartrip/ct-design-container 4.0.0 → 4.1.0-SNAPSHOT-native-main.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/README.md +63 -0
- package/dist/Container.d.ts +2 -4
- package/dist/Container.d.ts.map +1 -1
- package/dist/Container.native.d.ts +4 -0
- package/dist/Container.native.d.ts.map +1 -0
- package/dist/ct-design-container.browser.cjs.js +1 -1
- package/dist/ct-design-container.browser.cjs.js.map +1 -1
- package/dist/ct-design-container.browser.esm.js +1 -1
- package/dist/ct-design-container.browser.esm.js.map +1 -1
- package/dist/ct-design-container.cjs.js +70 -17
- package/dist/ct-design-container.cjs.js.map +1 -1
- package/dist/ct-design-container.esm.js +71 -14
- package/dist/ct-design-container.esm.js.map +1 -1
- package/dist/ct-design-container.umd.js +73 -58
- package/dist/ct-design-container.umd.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/type.d.ts +63 -41
- package/dist/type.d.ts.map +1 -1
- package/package.json +25 -8
- package/src/Container.native.tsx +132 -0
- package/src/Container.tsx +137 -0
- package/src/index.ts +2 -0
- package/src/type.ts +143 -0
- package/dist/style.d.ts +0 -4
- package/dist/style.d.ts.map +0 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CSSProperties,
|
|
3
|
+
forwardRef,
|
|
4
|
+
MutableRefObject,
|
|
5
|
+
useCallback,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useLayoutEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { makeStyles, useWebMergeStyles } from '@cleartrip/ct-design-style-manager';
|
|
11
|
+
import { IContainer, Rect, ContainerRef } from './type';
|
|
12
|
+
|
|
13
|
+
// Added below to sync with RN as flexDirection is mostly used as column
|
|
14
|
+
const staticContainerStyles = makeStyles(() => {
|
|
15
|
+
return {
|
|
16
|
+
root: {
|
|
17
|
+
display: 'flex',
|
|
18
|
+
flexDirection: 'column',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const Container = forwardRef<ContainerRef, IContainer>(
|
|
24
|
+
(
|
|
25
|
+
{
|
|
26
|
+
id,
|
|
27
|
+
as: ContainerAs = 'div',
|
|
28
|
+
children,
|
|
29
|
+
styleConfig,
|
|
30
|
+
onClick,
|
|
31
|
+
onLayout,
|
|
32
|
+
onMouseEnter,
|
|
33
|
+
onMouseLeave,
|
|
34
|
+
onTransitionEnd,
|
|
35
|
+
onTouchStart,
|
|
36
|
+
onTouchEnd,
|
|
37
|
+
onTouchCancel,
|
|
38
|
+
onTouchMove,
|
|
39
|
+
},
|
|
40
|
+
forwardedRef,
|
|
41
|
+
) => {
|
|
42
|
+
const localRef = useRef<HTMLDivElement | null>(null);
|
|
43
|
+
|
|
44
|
+
// Focuses the container element programmatically
|
|
45
|
+
const handleFocus = useCallback(() => {
|
|
46
|
+
localRef.current?.focus();
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
// Gets the bounding rectangle dimensions and position of the container
|
|
50
|
+
const handleGetBoundingRect = useCallback((callback?: (rect: Rect) => void) => {
|
|
51
|
+
const rect = localRef.current?.getBoundingClientRect();
|
|
52
|
+
// Only invoke callback if the element exists and has a bounding rect
|
|
53
|
+
if (rect) {
|
|
54
|
+
callback?.({
|
|
55
|
+
x: rect.x,
|
|
56
|
+
y: rect.y,
|
|
57
|
+
width: rect.width,
|
|
58
|
+
height: rect.height,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
const handleAddEventListener = useCallback(
|
|
64
|
+
(type: string, listener: EventListener, options?: boolean | AddEventListenerOptions) => {
|
|
65
|
+
localRef.current?.addEventListener(type, listener, options);
|
|
66
|
+
},
|
|
67
|
+
[],
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const handleRemoveEventListener = useCallback(
|
|
71
|
+
(type: string, listener: EventListener, options?: boolean | EventListenerOptions) => {
|
|
72
|
+
localRef.current?.removeEventListener(type, listener, options);
|
|
73
|
+
},
|
|
74
|
+
[],
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// Using useImperativeHandle to limit the number of methods exposed to the parent, In order to sync with RN
|
|
78
|
+
useImperativeHandle(
|
|
79
|
+
forwardedRef,
|
|
80
|
+
() => ({
|
|
81
|
+
focus: handleFocus,
|
|
82
|
+
getBoundingRectWithCallback: handleGetBoundingRect,
|
|
83
|
+
getElementRef: () => localRef as MutableRefObject<ContainerRef | null>,
|
|
84
|
+
style: (localRef.current?.style || {}) as CSSProperties,
|
|
85
|
+
classList: {
|
|
86
|
+
add: (className: string) => {
|
|
87
|
+
localRef.current?.classList.add(className);
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
measure: (
|
|
91
|
+
_callback: (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void,
|
|
92
|
+
) => {
|
|
93
|
+
localRef.current?.getBoundingClientRect();
|
|
94
|
+
},
|
|
95
|
+
addEventListener: handleAddEventListener,
|
|
96
|
+
removeEventListener: handleRemoveEventListener,
|
|
97
|
+
}),
|
|
98
|
+
[handleFocus, handleGetBoundingRect, handleAddEventListener, handleRemoveEventListener],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const { root: rootStyles = [] } = styleConfig || {};
|
|
102
|
+
|
|
103
|
+
const mergedRootStyles = useWebMergeStyles([staticContainerStyles.root, ...rootStyles], [rootStyles]);
|
|
104
|
+
|
|
105
|
+
useLayoutEffect(() => {
|
|
106
|
+
onLayout?.({
|
|
107
|
+
layout: {
|
|
108
|
+
height: localRef.current?.clientHeight ?? 0,
|
|
109
|
+
width: localRef.current?.clientWidth ?? 0,
|
|
110
|
+
x: localRef.current?.getBoundingClientRect().x ?? 0,
|
|
111
|
+
y: localRef.current?.getBoundingClientRect().y ?? 0,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}, [onLayout]);
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<ContainerAs
|
|
118
|
+
id={id}
|
|
119
|
+
ref={localRef}
|
|
120
|
+
className={mergedRootStyles}
|
|
121
|
+
onClick={onClick}
|
|
122
|
+
onMouseEnter={onMouseEnter}
|
|
123
|
+
onMouseLeave={onMouseLeave}
|
|
124
|
+
onTransitionEnd={onTransitionEnd}
|
|
125
|
+
onTouchStart={onTouchStart}
|
|
126
|
+
onTouchEnd={onTouchEnd}
|
|
127
|
+
onTouchCancel={onTouchCancel}
|
|
128
|
+
onTouchMove={onTouchMove}
|
|
129
|
+
>
|
|
130
|
+
{children}
|
|
131
|
+
</ContainerAs>
|
|
132
|
+
);
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
Container.displayName = 'Container';
|
|
137
|
+
export default Container;
|
package/src/index.ts
ADDED
package/src/type.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { MouseEventHandler, MutableRefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Styles } from '@cleartrip/ct-design-types';
|
|
4
|
+
import { INativeUIEvent } from '@cleartrip/ct-design-types';
|
|
5
|
+
|
|
6
|
+
export type HapticVariant = 'subtle' | 'loud';
|
|
7
|
+
|
|
8
|
+
export interface HapticFeedbackProps {
|
|
9
|
+
/**
|
|
10
|
+
* Enables haptic feedback on interaction with the container.
|
|
11
|
+
* When true, the container will trigger haptic feedback on click/tap events.
|
|
12
|
+
* @example
|
|
13
|
+
* <Component hapticEnabled={true} />
|
|
14
|
+
*/
|
|
15
|
+
hapticEnabled?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Specifies the intensity of the haptic feedback.
|
|
19
|
+
* - 'light': Light haptic feedback, suitable for most interactions
|
|
20
|
+
* - 'loud': Strong haptic feedback, for more prominent interactions
|
|
21
|
+
* @example
|
|
22
|
+
* <Component hapticEnabled={true} hapticVariant="subtle" />
|
|
23
|
+
*/
|
|
24
|
+
hapticVariant?: HapticVariant;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* When enabled, the haptic feedback will repeat continuously while the interaction is active.
|
|
28
|
+
* Useful for long-press or drag interactions.
|
|
29
|
+
* @example
|
|
30
|
+
* <Component hapticEnabled={true} hapticRepeat={true} />
|
|
31
|
+
*/
|
|
32
|
+
hapticRepeat?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IHapticFeedbackProps {
|
|
36
|
+
pattern?: number | number[];
|
|
37
|
+
repeat?: boolean;
|
|
38
|
+
variant: HapticVariant;
|
|
39
|
+
intensity?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface IContainer extends HapticFeedbackProps {
|
|
43
|
+
/**
|
|
44
|
+
* The id of the container
|
|
45
|
+
*/
|
|
46
|
+
id?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The children of the container
|
|
49
|
+
*/
|
|
50
|
+
children?: React.ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* The type of HTML element to be used for rendering
|
|
53
|
+
*/
|
|
54
|
+
as?: 'main' | 'section' | 'article' | 'div' | 'p';
|
|
55
|
+
/**
|
|
56
|
+
* Callback when user clicks on the container
|
|
57
|
+
*/
|
|
58
|
+
onClick?: (event: INativeUIEvent) => void;
|
|
59
|
+
/**
|
|
60
|
+
* Callback for layout changes. Works only for native.
|
|
61
|
+
*/
|
|
62
|
+
onLayout?: (event: {
|
|
63
|
+
layout: {
|
|
64
|
+
height: number;
|
|
65
|
+
width: number;
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
};
|
|
69
|
+
}) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Custom style configuration for the container
|
|
72
|
+
*/
|
|
73
|
+
styleConfig?: {
|
|
74
|
+
root?: Styles[];
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Triggered when the mouse enters the container.
|
|
78
|
+
*/
|
|
79
|
+
onMouseEnter?: MouseEventHandler<HTMLElement>;
|
|
80
|
+
/**
|
|
81
|
+
* Triggered when the mouse leaves the container.
|
|
82
|
+
*/
|
|
83
|
+
onMouseLeave?: () => void;
|
|
84
|
+
onTouchStart?: () => void;
|
|
85
|
+
onTouchEnd?: () => void;
|
|
86
|
+
onTouchCancel?: () => void;
|
|
87
|
+
onTouchMove?: () => void;
|
|
88
|
+
/**
|
|
89
|
+
* Triggered when the transition ends.
|
|
90
|
+
*/
|
|
91
|
+
onTransitionEnd?: () => void;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Sets additional distance outside of element in which a press can be detected.
|
|
95
|
+
*/
|
|
96
|
+
hitSlop?: {
|
|
97
|
+
top: number;
|
|
98
|
+
bottom: number;
|
|
99
|
+
left: number;
|
|
100
|
+
right: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Sets the pointer events for the container.
|
|
104
|
+
* @example
|
|
105
|
+
* <Component pointerEvents="box-none" />
|
|
106
|
+
*/
|
|
107
|
+
pointerEvents?: 'box-none' | 'box-only' | 'auto';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface Rect {
|
|
111
|
+
x: number;
|
|
112
|
+
y: number;
|
|
113
|
+
width: number;
|
|
114
|
+
height: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface ContainerRef {
|
|
118
|
+
/**
|
|
119
|
+
* Focuses the container element
|
|
120
|
+
*/
|
|
121
|
+
focus: () => void;
|
|
122
|
+
/**
|
|
123
|
+
* Gets the bounding rectangle of the container with a callback
|
|
124
|
+
*/
|
|
125
|
+
getBoundingRectWithCallback: (callback?: (rect: Rect) => void) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Measures the container's dimensions and position
|
|
128
|
+
*/
|
|
129
|
+
measure: (
|
|
130
|
+
callback: (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void,
|
|
131
|
+
) => void;
|
|
132
|
+
|
|
133
|
+
style: React.CSSProperties;
|
|
134
|
+
|
|
135
|
+
getElementRef: () => MutableRefObject<ContainerRef | null>;
|
|
136
|
+
|
|
137
|
+
classList: {
|
|
138
|
+
add: (className: string) => void;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
addEventListener: (event: string, callback: () => void) => void;
|
|
142
|
+
removeEventListener: (event: string, callback: () => void) => void;
|
|
143
|
+
}
|
package/dist/style.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { CSSObject } from 'styled-components';
|
|
2
|
-
import { CSSWithTheme } from '@cleartrip/ct-design-types';
|
|
3
|
-
export declare const getContainerStyles: ({ alignItems, borderRadius, boxShadow, bottom, display, flex, justifyContent, flexWrap, flexDirection, rowGap, columnGap, left, position, right, top, zIndex, paddingTop, paddingBottom, paddingLeft, paddingRight, marginTop, marginBottom, marginLeft, marginRight, backgroundColor, cursor, width, height, wordBreak, theme, textAlign, gridTemplateColumns, ...rest }: CSSWithTheme) => CSSObject;
|
|
4
|
-
//# sourceMappingURL=style.d.ts.map
|
package/dist/style.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../packages/components/Container/src/style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,eAAO,MAAM,kBAAkB,8WAkC5B,YAAY,KAAG,SAmCjB,CAAC"}
|