@raxium/vue-addons-shared 0.1.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/dist/composables/useEmitAsProps.d.ts +10 -0
- package/dist/composables/useEmitAsProps.js +31 -0
- package/dist/composables/useForwardExpose.d.ts +6 -0
- package/dist/composables/useForwardExpose.js +54 -0
- package/dist/composables/useForwardProps.d.ts +9 -0
- package/dist/composables/useForwardProps.js +32 -0
- package/dist/composables/useFowardPropsEmits.d.ts +14 -0
- package/dist/composables/useFowardPropsEmits.js +23 -0
- package/dist/context/createContext.d.ts +14 -0
- package/dist/context/createContext.js +41 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/package.json +45 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `useEmitAsProps` function is a TypeScript utility that converts emitted events into props for a
|
|
3
|
+
* Vue component.
|
|
4
|
+
* @param emit - The `emit` parameter is a function that is used to emit events from a component. It
|
|
5
|
+
* takes two parameters: `name` which is the name of the event to be emitted, and `...args` which are
|
|
6
|
+
* the arguments to be passed along with the event.
|
|
7
|
+
* @returns The function `useEmitAsProps` returns an object that maps event names to functions that
|
|
8
|
+
* call the `emit` function with the corresponding event name and arguments.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useEmitAsProps<Name extends string>(emit: (name: Name, ...args: any[]) => void): Record<string, any>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { camelize, getCurrentInstance, toHandlerKey } from 'vue';
|
|
2
|
+
// Vue doesn't have emits forwarding, in order to bind the emits we have to convert events into `onXXX` handlers
|
|
3
|
+
// issue: https://github.com/vuejs/core/issues/5917
|
|
4
|
+
/**
|
|
5
|
+
* The `useEmitAsProps` function is a TypeScript utility that converts emitted events into props for a
|
|
6
|
+
* Vue component.
|
|
7
|
+
* @param emit - The `emit` parameter is a function that is used to emit events from a component. It
|
|
8
|
+
* takes two parameters: `name` which is the name of the event to be emitted, and `...args` which are
|
|
9
|
+
* the arguments to be passed along with the event.
|
|
10
|
+
* @returns The function `useEmitAsProps` returns an object that maps event names to functions that
|
|
11
|
+
* call the `emit` function with the corresponding event name and arguments.
|
|
12
|
+
*/
|
|
13
|
+
export function useEmitAsProps(emit) {
|
|
14
|
+
const vm = getCurrentInstance();
|
|
15
|
+
const events = vm?.type.emits;
|
|
16
|
+
const result = {};
|
|
17
|
+
if (!events?.length) {
|
|
18
|
+
console.warn(`No emitted event found. Please check component: ${vm?.type.__name}`);
|
|
19
|
+
}
|
|
20
|
+
events?.forEach((ev) => {
|
|
21
|
+
result[toHandlerKey(camelize(ev))] = (...arg) => {
|
|
22
|
+
/*
|
|
23
|
+
this is for jsx usage to exicute if we use on={{...}} to add listeners
|
|
24
|
+
*/
|
|
25
|
+
;
|
|
26
|
+
vm?.props?.on?.[ev]?.(...arg);
|
|
27
|
+
return emit(ev, ...arg);
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentPublicInstance } from 'vue';
|
|
2
|
+
export declare function useForwardExpose<T extends ComponentPublicInstance>(): {
|
|
3
|
+
forwardRef: (ref: Element | T | null) => void;
|
|
4
|
+
currentRef: import("vue").Ref<Element | T | null | undefined, Element | T | null | undefined>;
|
|
5
|
+
currentElement: import("vue").ComputedRef<HTMLElement>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// reference: https://github.com/vuejs/rfcs/issues/258#issuecomment-1068697672
|
|
2
|
+
import { unrefElement } from '@vueuse/core';
|
|
3
|
+
import { computed, getCurrentInstance, ref } from 'vue';
|
|
4
|
+
export function useForwardExpose() {
|
|
5
|
+
const instance = getCurrentInstance();
|
|
6
|
+
const currentRef = ref();
|
|
7
|
+
const currentElement = computed(() => {
|
|
8
|
+
// $el could be text/comment for non-single root normal or text root, thus we retrieve the nextElementSibling
|
|
9
|
+
// @ts-expect-error ignore ts error
|
|
10
|
+
return ['#text', '#comment'].includes(currentRef.value?.$el.nodeName) ? currentRef.value?.$el.nextElementSibling : unrefElement(currentRef);
|
|
11
|
+
});
|
|
12
|
+
// Do give us credit if you reference our code :D
|
|
13
|
+
// localExpose should only be assigned once else will create infinite loop
|
|
14
|
+
const localExpose = Object.assign({}, instance.exposed);
|
|
15
|
+
const ret = {};
|
|
16
|
+
// retrieve props for current instance
|
|
17
|
+
for (const key in instance.props) {
|
|
18
|
+
Object.defineProperty(ret, key, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
get: () => instance.props[key],
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
// retrieve default exposed value
|
|
25
|
+
if (Object.keys(localExpose).length > 0) {
|
|
26
|
+
for (const key in localExpose) {
|
|
27
|
+
Object.defineProperty(ret, key, {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
get: () => localExpose[key],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// retrieve original first root element
|
|
35
|
+
Object.defineProperty(ret, '$el', {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
get: () => instance.vnode.el,
|
|
39
|
+
});
|
|
40
|
+
instance.exposed = ret;
|
|
41
|
+
function forwardRef(ref) {
|
|
42
|
+
currentRef.value = ref;
|
|
43
|
+
if (!ref)
|
|
44
|
+
return;
|
|
45
|
+
// retrieve the forwarded element
|
|
46
|
+
Object.defineProperty(ret, '$el', {
|
|
47
|
+
enumerable: true,
|
|
48
|
+
configurable: true,
|
|
49
|
+
get: () => (ref instanceof Element ? ref : ref.$el),
|
|
50
|
+
});
|
|
51
|
+
instance.exposed = ret;
|
|
52
|
+
}
|
|
53
|
+
return { forwardRef, currentRef, currentElement };
|
|
54
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* The `useForwardProps` function in TypeScript takes in a set of props and returns a computed value
|
|
4
|
+
* that combines default props with assigned props from the current instance.
|
|
5
|
+
* @param {T} props - The `props` parameter is an object that represents the props passed to a
|
|
6
|
+
* component.
|
|
7
|
+
* @returns computed value that combines the default props, preserved props, and assigned props.
|
|
8
|
+
*/
|
|
9
|
+
export declare function useForwardProps<T extends Record<string, any>>(props: MaybeRefOrGetter<T>): import("vue").ComputedRef<T>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { camelize, computed, getCurrentInstance, toRef } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* The `useForwardProps` function in TypeScript takes in a set of props and returns a computed value
|
|
4
|
+
* that combines default props with assigned props from the current instance.
|
|
5
|
+
* @param {T} props - The `props` parameter is an object that represents the props passed to a
|
|
6
|
+
* component.
|
|
7
|
+
* @returns computed value that combines the default props, preserved props, and assigned props.
|
|
8
|
+
*/
|
|
9
|
+
export function useForwardProps(props) {
|
|
10
|
+
const vm = getCurrentInstance();
|
|
11
|
+
// Default value for declared props
|
|
12
|
+
const defaultProps = Object.keys(vm?.type.props ?? {}).reduce((prev, curr) => {
|
|
13
|
+
const defaultValue = (vm?.type.props[curr]).default;
|
|
14
|
+
if (defaultValue !== undefined)
|
|
15
|
+
prev[curr] = defaultValue;
|
|
16
|
+
return prev;
|
|
17
|
+
}, {});
|
|
18
|
+
const refProps = toRef(props);
|
|
19
|
+
return computed(() => {
|
|
20
|
+
const preservedProps = {};
|
|
21
|
+
const assignedProps = vm?.vnode.props ?? {};
|
|
22
|
+
Object.keys(assignedProps).forEach((key) => {
|
|
23
|
+
preservedProps[camelize(key)] = assignedProps[key];
|
|
24
|
+
});
|
|
25
|
+
// Only return value from the props parameter
|
|
26
|
+
return Object.keys({ ...defaultProps, ...preservedProps }).reduce((prev, curr) => {
|
|
27
|
+
if (refProps.value[curr] !== undefined)
|
|
28
|
+
prev[curr] = refProps.value[curr];
|
|
29
|
+
return prev;
|
|
30
|
+
}, {});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* The function `useForwardPropsEmits` takes in props and an optional emit function, and returns a
|
|
4
|
+
* computed object that combines the parsed props and emits as props.
|
|
5
|
+
* @param {T} props - The `props` parameter is of type `T`, which is a generic type that extends the
|
|
6
|
+
* parameters of the `useForwardProps` function. It represents the props object that is passed to the
|
|
7
|
+
* `useForwardProps` function.
|
|
8
|
+
* @param [emit] - The `emit` parameter is a function that can be used to emit events. It takes two
|
|
9
|
+
* arguments: `name`, which is the name of the event to be emitted, and `args`, which are the arguments
|
|
10
|
+
* to be passed along with the event.
|
|
11
|
+
* @returns a computed property that combines the parsed
|
|
12
|
+
* props and emits as props.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useForwardPropsEmits<T extends Record<string, any>, Name extends string>(props: MaybeRefOrGetter<T>, emit?: (name: Name, ...args: any[]) => void): import("vue").ComputedRef<T & Record<string, any>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { computed } from 'vue';
|
|
2
|
+
import { useEmitAsProps } from './useEmitAsProps';
|
|
3
|
+
import { useForwardProps } from './useForwardProps';
|
|
4
|
+
/**
|
|
5
|
+
* The function `useForwardPropsEmits` takes in props and an optional emit function, and returns a
|
|
6
|
+
* computed object that combines the parsed props and emits as props.
|
|
7
|
+
* @param {T} props - The `props` parameter is of type `T`, which is a generic type that extends the
|
|
8
|
+
* parameters of the `useForwardProps` function. It represents the props object that is passed to the
|
|
9
|
+
* `useForwardProps` function.
|
|
10
|
+
* @param [emit] - The `emit` parameter is a function that can be used to emit events. It takes two
|
|
11
|
+
* arguments: `name`, which is the name of the event to be emitted, and `args`, which are the arguments
|
|
12
|
+
* to be passed along with the event.
|
|
13
|
+
* @returns a computed property that combines the parsed
|
|
14
|
+
* props and emits as props.
|
|
15
|
+
*/
|
|
16
|
+
export function useForwardPropsEmits(props, emit) {
|
|
17
|
+
const parsedProps = useForwardProps(props);
|
|
18
|
+
const emitsAsProps = emit ? useEmitAsProps(emit) : {};
|
|
19
|
+
return computed(() => ({
|
|
20
|
+
...parsedProps.value,
|
|
21
|
+
...emitsAsProps,
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create context for component
|
|
3
|
+
* @description source from reka-ui
|
|
4
|
+
* @see https://github.com/unovue/reka-ui/blob/v2/packages/core/src/shared/createContext.ts
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @param providerComponentName - The name(s) of the component(s) providing the context.
|
|
9
|
+
*
|
|
10
|
+
* There are situations where context can come from multiple components. In such cases, you might need to give an array of component names to provide your context, instead of just a single string.
|
|
11
|
+
*
|
|
12
|
+
* @param contextName The description for injection key symbol.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createContext<ContextValue>(providerComponentName: string | string[], contextName?: string): readonly [<T extends ContextValue | null | undefined = ContextValue>(fallback?: T) => T extends null ? ContextValue | null : ContextValue, (contextValue: ContextValue) => ContextValue];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create context for component
|
|
3
|
+
* @description source from reka-ui
|
|
4
|
+
* @see https://github.com/unovue/reka-ui/blob/v2/packages/core/src/shared/createContext.ts
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
import { inject, provide } from 'vue';
|
|
8
|
+
/**
|
|
9
|
+
* @param providerComponentName - The name(s) of the component(s) providing the context.
|
|
10
|
+
*
|
|
11
|
+
* There are situations where context can come from multiple components. In such cases, you might need to give an array of component names to provide your context, instead of just a single string.
|
|
12
|
+
*
|
|
13
|
+
* @param contextName The description for injection key symbol.
|
|
14
|
+
*/
|
|
15
|
+
export function createContext(providerComponentName, contextName) {
|
|
16
|
+
const symbolDescription = typeof providerComponentName === 'string' && !contextName
|
|
17
|
+
? `${providerComponentName}Context`
|
|
18
|
+
: contextName;
|
|
19
|
+
const injectionKey = Symbol(symbolDescription);
|
|
20
|
+
/**
|
|
21
|
+
* @param fallback The context value to return if the injection fails.
|
|
22
|
+
*
|
|
23
|
+
* @throws When context injection failed and no fallback is specified.
|
|
24
|
+
* This happens when the component injecting the context is not a child of the root component providing the context.
|
|
25
|
+
*/
|
|
26
|
+
const injectContext = (fallback) => {
|
|
27
|
+
const context = inject(injectionKey, fallback);
|
|
28
|
+
if (context)
|
|
29
|
+
return context;
|
|
30
|
+
if (context === null)
|
|
31
|
+
return context;
|
|
32
|
+
throw new Error(`Injection \`${injectionKey.toString()}\` not found. Component must be used within ${Array.isArray(providerComponentName)
|
|
33
|
+
? `one of the following components: ${providerComponentName.join(', ')}`
|
|
34
|
+
: `\`${providerComponentName}\``}`);
|
|
35
|
+
};
|
|
36
|
+
const provideContext = (contextValue) => {
|
|
37
|
+
provide(injectionKey, contextValue);
|
|
38
|
+
return contextValue;
|
|
39
|
+
};
|
|
40
|
+
return [injectContext, provideContext];
|
|
41
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@raxium/vue-addons-shared",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.1",
|
|
5
|
+
"description": "Shared utilities for Raxium Vue Addons",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Hwacc",
|
|
8
|
+
"email": "mshcccck@gmail.com",
|
|
9
|
+
"url": "https://github.com/raxium-ui/raxium-ui"
|
|
10
|
+
},
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"raxium",
|
|
14
|
+
"raxium-ui",
|
|
15
|
+
"vue",
|
|
16
|
+
"addons",
|
|
17
|
+
"shared"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"vue": "^3.5.27"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@vueuse/core": "^14.1.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typescript": "^5.9.3"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc --project tsconfig.build.json",
|
|
43
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
44
|
+
}
|
|
45
|
+
}
|