Skip to content

Commit

Permalink
feature(composables): create useNoElementRender composable
Browse files Browse the repository at this point in the history
  • Loading branch information
CachedaCodes committed Feb 20, 2024
1 parent 2236948 commit d67b465
Showing 3 changed files with 97 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Vue, { ComponentOptions, defineComponent } from 'vue';
import { mount, Wrapper } from '@vue/test-utils';
import { Dictionary } from '@empathyco/x-utils';
import { useNoElementRender } from '../use-no-element-render';
import { getDataTestSelector } from '../../__tests__/utils';

const renderUseNoElementRender = ({
slots,
component
}: RenderUseNoElementRenderOptions = {}): Wrapper<Vue> => {
const wrapper = mount(
component ??
(defineComponent({
render() {
return useNoElementRender(this.$slots);
}
}) as ComponentOptions<Vue>),
{
slots
}
);

return wrapper;
};

describe('testing useNoElementRender composable', () => {
it('renders as empty if there are no slots', () => {
let wrapper = renderUseNoElementRender();

expect(wrapper.html()).toBe('');

wrapper = renderUseNoElementRender({
slots: {
nonDefault: '<div data-test="non-default-slot"></div>'
}
});

expect(wrapper.html()).toBe('');
});

it('renders the default slot if there is any', () => {
const wrapper = renderUseNoElementRender({
slots: {
default: '<div data-test="default-slot"></div>',
nonDefault: '<div data-test="non-default-slot"></div>'
}
});

expect(wrapper.find(getDataTestSelector('default-slot')).exists()).toBe(true);
});

it('also works from the `setup` function', () => {
const component = defineComponent({
setup(_, { slots }) {
return () => useNoElementRender(slots);
}
});

let wrapper = renderUseNoElementRender({
component
});

expect(wrapper.html()).toBe('');

wrapper = renderUseNoElementRender({
slots: {
default: '<div data-test="default-slot"></div>'
},
component
});

expect(wrapper.find(getDataTestSelector('default-slot')).exists()).toBe(true);
});
});

type RenderUseNoElementRenderOptions = {
slots?: Dictionary<string>;
component?: ComponentOptions<Vue>;
};
1 change: 1 addition & 0 deletions packages/x-components/src/composables/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './create-use-device.composable';
export * from './use-no-element-render';
export * from './use-$x';
export * from './use-register-x-module';
export * from './use-on-display';
17 changes: 17 additions & 0 deletions packages/x-components/src/composables/use-no-element-render.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { h, SetupContext } from 'vue';
import { VNode } from 'vue/types/vnode';

/**
* Returns a render function that returns the default slot or nothing if it's not defined.
*
* @param slots - The slots object from the component.
* @returns The result of the rendering function to use.
*/
export function useNoElementRender(
slots: { [key: string]: VNode[] | undefined } | SetupContext['slots']
): VNode {
const defaultSlotContent =
typeof slots.default === 'function' ? slots.default()?.[0] : slots.default?.[0];

return defaultSlotContent ?? h();
}

0 comments on commit d67b465

Please sign in to comment.