@zayne-labs/toolkit-react 0.11.1 → 0.11.3

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.
@@ -1,225 +1,2 @@
1
- import * as react10 from "react";
2
- import { RefCallback } from "react";
3
- import { AnyFunction, AnyObject, CallbackFn, EmptyObject, Prettify, UnionDiscriminator, UnionToIntersection, UnknownObject } from "@zayne-labs/toolkit-type-helpers";
4
-
5
- //#region src/utils/composeEventHandlers.d.ts
6
- declare const composeTwoEventHandlers: (formerHandler: AnyFunction | undefined, latterHandler: AnyFunction | undefined) => (event: unknown) => unknown;
7
- declare const composeEventHandlers: (...eventHandlerArray: Array<AnyFunction | undefined>) => (event: unknown) => unknown;
8
- //#endregion
9
- //#region src/utils/composeRefs.d.ts
10
- type PossibleRef<TRef extends HTMLElement> = React.Ref<TRef> | undefined;
11
- /**
12
- * @description Set a given ref to a given value.
13
- *
14
- * This utility takes care of different types of refs: callback refs and RefObject(s)
15
- */
16
- declare const setRef: <TRef extends HTMLElement>(ref: PossibleRef<TRef>, node: TRef | null) => ReturnType<RefCallback<TRef>>;
17
- /**
18
- * @description A utility to combine refs. Accepts callback refs and RefObject(s)
19
- */
20
- declare const composeRefs: <TRef extends HTMLElement>(...refs: Array<PossibleRef<TRef>>) => RefCallback<TRef>;
21
- //#endregion
22
- //#region src/utils/getSlot/getSlot.d.ts
23
- type FunctionalComponent<TProps extends UnknownObject = never> = React.FunctionComponent<TProps>;
24
- /**
25
- * @description Checks if a react child (within the children array) matches the provided SlotComponent using multiple matching strategies:
26
- * 1. Matches by slot symbol property
27
- * 2. Matches by component name
28
- */
29
- declare const matchesSlotComponent: (child: React.ReactNode, SlotComponent: FunctionalComponent) => boolean;
30
- /**
31
- * @description Checks if a react child (within the children array) matches any of the provided SlotComponents.
32
- */
33
- declare const matchesAnySlotComponent: (child: React.ReactNode, SlotComponents: FunctionalComponent[]) => boolean;
34
- type SlotOptions = {
35
- /**
36
- * @description The error message to throw when multiple slots are found for a given slot component
37
- */
38
- errorMessage?: string;
39
- /**
40
- * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component
41
- */
42
- throwOnMultipleSlotMatch?: boolean;
43
- };
44
- /**
45
- * @description Retrieves a single slot element from a collection of React children that matches the provided SlotComponent component.
46
- *
47
- * @throws { AssertionError } when throwOnMultipleSlotMatch is true and multiple slots are found
48
- */
49
- declare const getSingleSlot: (children: React.ReactNode, SlotComponent: FunctionalComponent, options?: SlotOptions) => react10.ReactNode;
50
- type MultipleSlotsOptions = {
51
- /**
52
- * @description The error message to throw when multiple slots are found for a given slot component
53
- * If a string is provided, the same message will be used for all slot components
54
- * If an array is provided, each string in the array will be used as the errorMessage for the corresponding slot component
55
- */
56
- errorMessage?: string | string[];
57
- /**
58
- * @description When true, an AssertionError will be thrown if multiple slots are found for a given slot component
59
- * If a boolean is provided, the same value will be used for all slot components
60
- * If an array is provided, each boolean in the array will be used as the throwOnMultipleSlotMatch value for the corresponding slot component
61
- */
62
- throwOnMultipleSlotMatch?: boolean | boolean[];
63
- };
64
- type GetMultipleSlotsResult<TSlotComponents extends FunctionalComponent[]> = {
65
- regularChildren: React.ReactNode[];
66
- slots: { [Key in keyof TSlotComponents]: ReturnType<TSlotComponents[Key]> };
67
- };
68
- /**
69
- * @description The same as getSingleSlot, but for multiple slot components
70
- */
71
- declare const getMultipleSlots: <const TSlotComponents extends FunctionalComponent[]>(children: React.ReactNode, SlotComponents: TSlotComponents, options?: MultipleSlotsOptions) => Prettify<GetMultipleSlotsResult<TSlotComponents>>;
72
- /**
73
- * @description Returns all children that are not slot elements (i.e., don't match any of the provided slot components)
74
- */
75
- declare const getRegularChildren: (children: React.ReactNode, SlotComponentOrComponents: FunctionalComponent | FunctionalComponent[]) => react10.ReactNode[];
76
- //#endregion
77
- //#region src/utils/getSlotMap/getSlotMap.d.ts
78
- type GetSlotName<TSlotComponentProps extends GetSlotComponentProps> = string extends TSlotComponentProps["name"] ? never : "default" extends TSlotComponentProps["name"] ? never : TSlotComponentProps["name"];
79
- type GetSpecificSlotsType<TSlotComponentProps extends GetSlotComponentProps> = { [TName in keyof TSlotComponentProps as GetSlotName<TSlotComponentProps>]: Extract<TSlotComponentProps["children"], React.ReactNode> };
80
- /**
81
- * Maps slot names to their corresponding children types
82
- */
83
- type GetSlotMapResult<TSlotComponentProps extends GetSlotComponentProps> = UnionToIntersection<GetSpecificSlotsType<TSlotComponentProps>> & {
84
- default: React.ReactNode[];
85
- };
86
- /**
87
- * Symbol used to identify SlotComponent instances
88
- */
89
- declare const slotComponentSymbol: unique symbol;
90
- /**
91
- * @description Creates a map of named slots from React children. Returns an object mapping slot names to their children,
92
- * with a default slot for unmatched children.
93
- *
94
- * @example
95
- * ```tsx
96
- * import { type GetSlotComponentProps, SlotComponent } from "@zayne-labs/toolkit-react/utils"
97
- *
98
- * type SlotProps = GetSlotComponentProps<"header" | "footer">;
99
- *
100
- * function Parent({ children }: { children: React.ReactNode }) {
101
- * const slots = getSlotMap<SlotProps>(children);
102
- *
103
- * return (
104
- * <div>
105
- * <header>{slots.header}</header>
106
- * <main>{slots.default}</main>
107
- * <footer>{slots.footer}</footer>
108
- * </div>
109
- * );
110
- * }
111
- * ```
112
- *
113
- * Usage:
114
- * ```tsx
115
- * <Parent>
116
- * <SlotComponent name="header">Header Content</SlotComponent>
117
- * <div>Random stuff</div>
118
- * <SlotComponent name="footer">Footer Content</SlotComponent>
119
- * </Parent>
120
- * ```
121
- */
122
- declare const getSlotMap: <TSlotComponentProps extends GetSlotComponentProps>(children: React.ReactNode) => Prettify<GetSlotMapResult<TSlotComponentProps>>;
123
- /**
124
- * @description Produce props for the SlotComponent
125
- *
126
- * @example
127
- * ```ts
128
- * // Pattern One (slot or slots have same children type, which is just React.ReactNode by default)
129
- * type SlotProps = GetSlotComponentProps<"header" | "content" | "footer">;
130
- *
131
- * // Pattern Two (some slots can have different children type)
132
- * type SlotProps = GetSlotComponentProps<"header", React.ReactNode> | GetSlotComponentProps<"header", (renderProp: RenderProp) => React.ReactNode>;
133
- * ```
134
- */
135
- type GetSlotComponentProps<TName extends string = string, TChildren extends CallbackFn<never, React.ReactNode> | React.ReactNode = CallbackFn<never, React.ReactNode> | React.ReactNode> = {
136
- children: TChildren;
137
- /**
138
- * Name of the slot where content should be rendered
139
- */
140
- name: TName;
141
- };
142
- /**
143
- * @description Creates a slot component
144
- */
145
- declare const createSlotComponent: <TSlotComponentProps extends GetSlotComponentProps>() => {
146
- (props: TSlotComponentProps): React.ReactNode;
147
- slotSymbol: typeof slotComponentSymbol;
148
- };
149
- type SlotWithNameAndSymbol<TSlotComponentProps extends GetSlotComponentProps = GetSlotComponentProps, TOtherProps extends UnknownObject = EmptyObject> = {
150
- (props: Pick<TSlotComponentProps, "children"> & TOtherProps): React.ReactNode;
151
- readonly slotName?: TSlotComponentProps["name"];
152
- readonly slotSymbol?: symbol;
153
- };
154
- /**
155
- * @description Adds a slot symbol and name to a slot component passed in
156
- */
157
- declare const withSlotNameAndSymbol: <TSlotComponentProps extends GetSlotComponentProps, TOtherProps extends UnknownObject = EmptyObject>(name: TSlotComponentProps["name"], SlotComponent?: SlotWithNameAndSymbol<TSlotComponentProps, TOtherProps>) => SlotWithNameAndSymbol<TSlotComponentProps, TOtherProps>;
158
- //#endregion
159
- //#region src/utils/mergeProps.d.ts
160
- type UnionToIntersection$1<TUnion> = (TUnion extends unknown ? (param: TUnion) => void : "") extends ((param: infer TParam) => void) ? TParam : "";
161
- /**
162
- * Merges multiple sets of React props.
163
- *
164
- * - It follows the Object.assign pattern where the rightmost object's fields overwrite
165
- * the conflicting ones from others. This doesn't apply to event handlers, `className` and `style` props.
166
- * - Event handlers are merged such that they are called in sequence (the rightmost one being called first),
167
- * and allows the user to prevent the previous event handlers from being executed by calling the `preventDefault` method.
168
- * - It also merges the `className` and `style` props, whereby the classes are concatenated
169
- * and the rightmost styles overwrite the previous ones.
170
- *
171
- * @important **`ref` is not merged.**
172
- * @param props props to merge.
173
- * @returns the merged props.
174
- */
175
- declare const mergeProps: <TProps extends Record<never, never>>(...propsObjectArray: Array<TProps | undefined>) => UnionToIntersection$1<TProps>;
176
- //#endregion
177
- //#region src/utils/mergeTwoProps.d.ts
178
- declare const mergeTwoProps: <TProps extends Record<never, never>>(formerProps: TProps | undefined, latterProps: TProps | undefined) => TProps;
179
- //#endregion
180
- //#region src/utils/types/common.d.ts
181
- type ForwardedRefType<TComponent extends HTMLElement | React.ElementType> = TComponent extends React.ElementType ? React.ForwardedRef<React.Ref<TComponent>> : React.ForwardedRef<TComponent>;
182
- type InferProps<TComponent extends HTMLElement | React.ElementType> = TComponent extends React.ElementType ? React.ComponentPropsWithRef<TComponent> : React.HTMLAttributes<TComponent>;
183
- type StateSetter<TSetter = unknown> = React.Dispatch<React.SetStateAction<TSetter>>;
184
- type CssWithCustomProperties<TExtra extends Record<string, string> = NonNullable<unknown>> = React.CSSProperties & Record<`--${string}`, string> & TExtra;
185
- type DefaultRenderItemErrorMessages = {
186
- children: "Hey, Sorry but the children prop is redundant since you're currently using the render prop to do the same thing";
187
- renderItem: "Hey, Sorry but the renderItem prop is redundant since you're currently using the children prop to do the same thing";
188
- };
189
- /**
190
- * @description Represents a set of props that can be used to render a component conditionally based on a discriminated union type.
191
- * This type allows for the use of either a render prop or children prop, but not both at the same time.
192
- * If both are provided, a TypeScript error will be thrown.
193
- * @template TErrorMessages An object of custom messages to display on the disallowed property.
194
- */
195
- type DiscriminatedRenderItemProps<TRenderItemPropType, TErrorMessages extends Record<keyof DefaultRenderItemErrorMessages, string> = DefaultRenderItemErrorMessages> = UnionDiscriminator<[{
196
- children: TRenderItemPropType;
197
- }, {
198
- renderItem: TRenderItemPropType;
199
- }], TErrorMessages>;
200
- type DefaultRenderErrorMessages = {
201
- children: "Hey, Sorry but the children prop is redundant since you're currently using the render prop to do the same thing";
202
- render: "Hey, Sorry but the render prop is redundant since you're currently using the children prop to do the same thing";
203
- };
204
- /**
205
- * @description Represents a set of props that can be used to render a component conditionally based on a discriminated union type.
206
- * This type allows for the use of either a render prop or children prop, but not both at the same time.
207
- * If both are provided, a TypeScript error will be thrown.
208
- * @template TErrorMessages An object of custom messages to display on the disallowed property.
209
- */
210
- type DiscriminatedRenderProps<TRenderPropType, TErrorMessages extends Record<keyof DefaultRenderErrorMessages, string> = DefaultRenderErrorMessages> = UnionDiscriminator<[{
211
- children: TRenderPropType;
212
- }, {
213
- render: TRenderPropType;
214
- }], TErrorMessages>;
215
- //#endregion
216
- //#region src/utils/types/polymorphism.d.ts
217
- type AsProp<TElement extends React.ElementType> = {
218
- as?: TElement;
219
- };
220
- type InferRemainingProps<TElement extends React.ElementType, TProps> = Omit<InferProps<TElement>, keyof TProps>;
221
- type MergedGivenPropsWithAs<TElement extends React.ElementType, TProps> = Prettify<Omit<AsProp<TElement>, keyof TProps> & TProps>;
222
- type PolymorphicProps<TElement extends React.ElementType, TProps extends AnyObject = NonNullable<unknown>> = MergedGivenPropsWithAs<TElement, TProps> & InferRemainingProps<TElement, TProps>;
223
- //#endregion
224
- export { AsProp, CssWithCustomProperties, DefaultRenderErrorMessages, DefaultRenderItemErrorMessages, DiscriminatedRenderItemProps, DiscriminatedRenderProps, ForwardedRefType, FunctionalComponent, GetSlotComponentProps, GetSlotMapResult, InferProps, PolymorphicProps, PossibleRef, StateSetter, composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol };
225
- //# sourceMappingURL=index.d.ts.map
1
+ import { AsProp, CssWithCustomProperties, DefaultRenderErrorMessages, DefaultRenderItemErrorMessages, DiscriminatedRenderItemProps, DiscriminatedRenderProps, ForwardedRefType, FunctionalComponent, GetSlotComponentProps, GetSlotMapResult, InferProps, PolymorphicProps, PossibleRef, StateSetter, composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol } from "../index-CByHxS0M.js";
2
+ export { AsProp, CssWithCustomProperties, DefaultRenderErrorMessages, DefaultRenderItemErrorMessages, DiscriminatedRenderItemProps, DiscriminatedRenderProps, ForwardedRefType, FunctionalComponent, GetSlotComponentProps, GetSlotMapResult, InferProps, PolymorphicProps, PossibleRef, StateSetter, composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol };
@@ -1,279 +1,3 @@
1
- import { Fragment, isValidElement } from "react";
2
- import { toArray } from "@zayne-labs/toolkit-core";
3
- import { AssertionError, isArray, isFunction, isObject } from "@zayne-labs/toolkit-type-helpers";
1
+ import { composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol } from "../utils-Bvs8tFDM.js";
4
2
 
5
- //#region src/utils/composeEventHandlers.ts
6
- const isSyntheticEvent = (event) => {
7
- return isObject(event) && Object.hasOwn(event, "nativeEvent");
8
- };
9
- const composeTwoEventHandlers = (formerHandler, latterHandler) => {
10
- const mergedEventHandler = (event) => {
11
- if (isSyntheticEvent(event)) {
12
- const result$1 = latterHandler?.(event);
13
- if (!event.defaultPrevented) formerHandler?.(event);
14
- return result$1;
15
- }
16
- const result = latterHandler?.(event);
17
- formerHandler?.(event);
18
- return result;
19
- };
20
- return mergedEventHandler;
21
- };
22
- const composeEventHandlers = (...eventHandlerArray) => {
23
- const mergedEventHandler = (event) => {
24
- if (eventHandlerArray.length === 0) return;
25
- if (eventHandlerArray.length === 1) return eventHandlerArray[0]?.(event);
26
- let accumulatedHandlers;
27
- for (const eventHandler of eventHandlerArray) {
28
- if (!eventHandler) continue;
29
- accumulatedHandlers = composeTwoEventHandlers(accumulatedHandlers, eventHandler);
30
- }
31
- return accumulatedHandlers?.(event);
32
- };
33
- return mergedEventHandler;
34
- };
35
-
36
- //#endregion
37
- //#region src/utils/composeRefs.ts
38
- /**
39
- * @description Set a given ref to a given value.
40
- *
41
- * This utility takes care of different types of refs: callback refs and RefObject(s)
42
- */
43
- const setRef = (ref, node) => {
44
- if (!ref) return;
45
- if (isFunction(ref)) return ref(node);
46
- ref.current = node;
47
- };
48
- /**
49
- * @description A utility to combine refs. Accepts callback refs and RefObject(s)
50
- */
51
- const composeRefs = (...refs) => {
52
- const mergedRefCallBack = (node) => {
53
- const cleanupFnArray = refs.map((ref) => setRef(ref, node));
54
- const cleanupFn = () => cleanupFnArray.forEach((cleanup) => cleanup?.());
55
- return cleanupFn;
56
- };
57
- return mergedRefCallBack;
58
- };
59
-
60
- //#endregion
61
- //#region src/utils/getSlot/getSlot.ts
62
- const isWithSlotSymbol = (component) => {
63
- return "slotSymbol" in component && Boolean(component.slotSymbol);
64
- };
65
- const isWithSlotReference = (component) => {
66
- return "slotReference" in component && Boolean(component.slotReference);
67
- };
68
- /**
69
- * @description Checks if a react child (within the children array) matches the provided SlotComponent using multiple matching strategies:
70
- * 1. Matches by slot symbol property
71
- * 2. Matches by component name
72
- */
73
- const matchesSlotComponent = (child, SlotComponent) => {
74
- if (!isValidElement(child) || !isFunction(child.type)) return false;
75
- const resolvedChildType = isWithSlotReference(child.type) ? child.type.slotReference : child.type;
76
- if (isWithSlotSymbol(resolvedChildType) && isWithSlotSymbol(SlotComponent) && resolvedChildType.slotSymbol === SlotComponent.slotSymbol) return true;
77
- if (child.type.name === SlotComponent.name) return true;
78
- return false;
79
- };
80
- /**
81
- * @description Checks if a react child (within the children array) matches any of the provided SlotComponents.
82
- */
83
- const matchesAnySlotComponent = (child, SlotComponents) => {
84
- return SlotComponents.some((SlotComponent) => matchesSlotComponent(child, SlotComponent));
85
- };
86
- /**
87
- * @description Counts how many times a given slot component appears in an array of children
88
- * @internal
89
- */
90
- const calculateSlotOccurrences = (childrenArray, SlotComponent) => {
91
- let count = 0;
92
- for (const child of childrenArray) {
93
- if (!matchesSlotComponent(child, SlotComponent)) continue;
94
- count += 1;
95
- }
96
- return count;
97
- };
98
- /**
99
- * @description Retrieves a single slot element from a collection of React children that matches the provided SlotComponent component.
100
- *
101
- * @throws { AssertionError } when throwOnMultipleSlotMatch is true and multiple slots are found
102
- */
103
- const getSingleSlot = (children, SlotComponent, options = {}) => {
104
- const { errorMessage = "Only one instance of the SlotComponent is allowed", throwOnMultipleSlotMatch = false } = options;
105
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
106
- const childrenArray = toArray(actualChildren);
107
- if (throwOnMultipleSlotMatch && calculateSlotOccurrences(childrenArray, SlotComponent) > 1) throw new AssertionError(errorMessage);
108
- return childrenArray.find((child) => matchesSlotComponent(child, SlotComponent));
109
- };
110
- /**
111
- * @description The same as getSingleSlot, but for multiple slot components
112
- */
113
- const getMultipleSlots = (children, SlotComponents, options) => {
114
- const { errorMessage, throwOnMultipleSlotMatch } = options ?? {};
115
- const slots = SlotComponents.map((SlotComponent, index) => getSingleSlot(children, SlotComponent, {
116
- errorMessage: isArray(errorMessage) ? errorMessage[index] : errorMessage,
117
- throwOnMultipleSlotMatch: isArray(throwOnMultipleSlotMatch) ? throwOnMultipleSlotMatch[index] : throwOnMultipleSlotMatch
118
- }));
119
- return {
120
- regularChildren: getRegularChildren(children, SlotComponents),
121
- slots
122
- };
123
- };
124
- /**
125
- * @description Returns all children that are not slot elements (i.e., don't match any of the provided slot components)
126
- */
127
- const getRegularChildren = (children, SlotComponentOrComponents) => {
128
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
129
- return toArray(actualChildren).filter((child) => !matchesAnySlotComponent(child, toArray(SlotComponentOrComponents)));
130
- };
131
-
132
- //#endregion
133
- //#region src/utils/getSlotMap/getSlotMap.ts
134
- /**
135
- * Symbol used to identify SlotComponent instances
136
- */
137
- const slotComponentSymbol = Symbol("slot-component");
138
- /**
139
- * @description Creates a map of named slots from React children. Returns an object mapping slot names to their children,
140
- * with a default slot for unmatched children.
141
- *
142
- * @example
143
- * ```tsx
144
- * import { type GetSlotComponentProps, SlotComponent } from "@zayne-labs/toolkit-react/utils"
145
- *
146
- * type SlotProps = GetSlotComponentProps<"header" | "footer">;
147
- *
148
- * function Parent({ children }: { children: React.ReactNode }) {
149
- * const slots = getSlotMap<SlotProps>(children);
150
- *
151
- * return (
152
- * <div>
153
- * <header>{slots.header}</header>
154
- * <main>{slots.default}</main>
155
- * <footer>{slots.footer}</footer>
156
- * </div>
157
- * );
158
- * }
159
- * ```
160
- *
161
- * Usage:
162
- * ```tsx
163
- * <Parent>
164
- * <SlotComponent name="header">Header Content</SlotComponent>
165
- * <div>Random stuff</div>
166
- * <SlotComponent name="footer">Footer Content</SlotComponent>
167
- * </Parent>
168
- * ```
169
- */
170
- const getSlotMap = (children) => {
171
- const slots = { default: [] };
172
- const actualChildren = isValidElement(children) && children.type === Fragment ? children.props.children : children;
173
- const childrenArray = toArray(actualChildren);
174
- for (const child of childrenArray) {
175
- if (!isValidElement(child) || !isFunction(child.type)) {
176
- slots.default.push(child);
177
- continue;
178
- }
179
- const childType = child.type;
180
- if (!(childType.slotSymbol === slotComponentSymbol && Boolean(childType.slotName ?? child.props.name))) {
181
- slots.default.push(child);
182
- continue;
183
- }
184
- const slotName = childType.slotName ?? child.props.name;
185
- if (slotName === "default") {
186
- slots.default.push(child);
187
- continue;
188
- }
189
- slots[slotName] = child;
190
- }
191
- return slots;
192
- };
193
- /**
194
- * @description Creates a slot component
195
- */
196
- const createSlotComponent = () => {
197
- const SlotComponent = (props) => props.children;
198
- SlotComponent.slotSymbol = slotComponentSymbol;
199
- return SlotComponent;
200
- };
201
- function DefaultSlotComponent(props) {
202
- return props.children;
203
- }
204
- /**
205
- * @description Adds a slot symbol and name to a slot component passed in
206
- */
207
- const withSlotNameAndSymbol = (name, SlotComponent = DefaultSlotComponent) => {
208
- SlotComponent.slotSymbol = slotComponentSymbol;
209
- SlotComponent.slotName = name;
210
- return SlotComponent;
211
- };
212
-
213
- //#endregion
214
- //#region src/utils/mergeTwoProps.ts
215
- const isEventHandler = (key, value) => {
216
- const thirdCharCode = key.codePointAt(2);
217
- if (!isFunction(value) || thirdCharCode === void 0) return false;
218
- return key.startsWith("on") && thirdCharCode >= 65 && thirdCharCode <= 90;
219
- };
220
- const mergeTwoClassNames = (formerClassName, latterClassName) => {
221
- if (!latterClassName || !formerClassName) return latterClassName || formerClassName;
222
- return formerClassName + " " + latterClassName;
223
- };
224
- const mergeTwoProps = (formerProps, latterProps) => {
225
- if (!latterProps || !formerProps) return latterProps ?? formerProps ?? {};
226
- const propsAccumulator = { ...formerProps };
227
- for (const latterPropName of Object.keys(latterProps)) {
228
- const formerPropValue = formerProps[latterPropName];
229
- const latterPropValue = latterProps[latterPropName];
230
- if (latterPropName === "className" || latterPropName === "class") {
231
- propsAccumulator[latterPropName] = mergeTwoClassNames(formerPropValue, latterPropValue);
232
- continue;
233
- }
234
- if (latterPropName === "style") {
235
- propsAccumulator[latterPropName] = {
236
- ...formerPropValue,
237
- ...latterPropValue
238
- };
239
- continue;
240
- }
241
- if (isEventHandler(latterPropName, latterPropValue)) {
242
- propsAccumulator[latterPropName] = composeTwoEventHandlers(formerPropValue, latterPropValue);
243
- continue;
244
- }
245
- propsAccumulator[latterPropName] = latterPropValue;
246
- }
247
- return propsAccumulator;
248
- };
249
-
250
- //#endregion
251
- //#region src/utils/mergeProps.ts
252
- /**
253
- * Merges multiple sets of React props.
254
- *
255
- * - It follows the Object.assign pattern where the rightmost object's fields overwrite
256
- * the conflicting ones from others. This doesn't apply to event handlers, `className` and `style` props.
257
- * - Event handlers are merged such that they are called in sequence (the rightmost one being called first),
258
- * and allows the user to prevent the previous event handlers from being executed by calling the `preventDefault` method.
259
- * - It also merges the `className` and `style` props, whereby the classes are concatenated
260
- * and the rightmost styles overwrite the previous ones.
261
- *
262
- * @important **`ref` is not merged.**
263
- * @param props props to merge.
264
- * @returns the merged props.
265
- */
266
- const mergeProps = (...propsObjectArray) => {
267
- if (propsObjectArray.length === 0) return {};
268
- if (propsObjectArray.length === 1) return propsObjectArray[0];
269
- let accumulatedProps = {};
270
- for (const propsObject of propsObjectArray) {
271
- if (!propsObject) continue;
272
- accumulatedProps = mergeTwoProps(accumulatedProps, propsObject);
273
- }
274
- return accumulatedProps;
275
- };
276
-
277
- //#endregion
278
- export { composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol };
279
- //# sourceMappingURL=index.js.map
3
+ export { composeEventHandlers, composeRefs, composeTwoEventHandlers, createSlotComponent, getMultipleSlots, getRegularChildren, getSingleSlot, getSlotMap, matchesAnySlotComponent, matchesSlotComponent, mergeProps, mergeTwoProps, setRef, slotComponentSymbol, withSlotNameAndSymbol };