Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Migrate base-panels components to composition api #1491

Merged
Merged
1 change: 1 addition & 0 deletions packages/_vue3-migration-test/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export { default as TestBaseVariableColumnGrid } from './test-base-variable-colu
export { default as TestSlidingPanel } from './test-sliding-panel.vue';
export { default as TestUseLayouts } from './test-use-layouts.vue';
export { default as TestBaseSuggestions } from './suggestions/test-base-suggestions.vue';
export { default as TestBasePanel } from './panels/test-base-panel.vue';
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<div>
<h2>Base header toggle panel</h2>
<BaseHeaderTogglePanel :start-collapsed="false">
<template #header-content="{ open }">
<p>Header, open: {{ open ? 'close' : 'open' }}</p>
</template>
<template>
<p>Default content</p>
</template>
</BaseHeaderTogglePanel>

<h2>Base id toggle panel, Base id toggle panel button and Base Toggle panel</h2>
<BaseIdTogglePanelButton panelId="myToggle">Toggle Aside</BaseIdTogglePanelButton>
<BaseIdTogglePanel :startOpen="true" panelId="myToggle">
<div>My toggle</div>
</BaseIdTogglePanel>

<h2>Base tabs panel component</h2>
<BaseTabsPanel initial-tab="fall">
<template #summer>
<div>Summer Top Sales</div>
</template>

<template #fall>
<div>Fall Top Sales</div>
</template>

<template #outlet>
<div>Outlet Top Sales</div>
</template>
</BaseTabsPanel>
</div>
</template>

<script setup>
import BaseHeaderTogglePanel from '../../../../x-components/src/components/panels/base-header-toggle-panel.vue';
import BaseIdTogglePanelButton from '../../../../x-components/src/components/panels/base-id-toggle-panel-button.vue';
import BaseIdTogglePanel from '../../../../x-components/src/components/panels/base-id-toggle-panel.vue';
import BaseTabsPanel from '../../../../x-components/src/components/panels/base-tabs-panel.vue';
</script>

<style scoped></style>
8 changes: 7 additions & 1 deletion packages/_vue3-migration-test/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import {
TestEmpathize,
TestUseLayouts,
TestSlidingPanel,
TestBaseSuggestions
TestBaseSuggestions,
TestBasePanel
} from './';

const routes = [
Expand Down Expand Up @@ -140,6 +141,11 @@ const routes = [
path: '/base-suggestions',
name: 'BaseSuggestions',
component: TestBaseSuggestions
},
{
path: '/test-base-panel',
name: 'TestBasePanel',
component: TestBasePanel
}
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { mount, Wrapper } from '@vue/test-utils';
import Vue from 'vue';
import { getDataTestSelector } from '../../../__tests__/utils';
import BaseHeaderTogglePanelComponent from '../base-header-toggle-panel.vue';
import BaseHeaderTogglePanel from '../base-header-toggle-panel.vue';

/**
* Function that returns a BaseHeaderTogglePanel wrapper. The animation prop is not gonna be tested
Expand All @@ -16,12 +16,12 @@ function renderBaseHeaderTogglePanel({
}: RenderBaseTogglePanelOptions = {}): RenderBaseHeaderTogglePanelAPI {
const wrapperContainer = mount({
components: {
BaseHeaderTogglePanel: BaseHeaderTogglePanelComponent
BaseHeaderTogglePanel
},
template
});

const wrapper = wrapperContainer.findComponent(BaseHeaderTogglePanelComponent);
const wrapper = wrapperContainer.findComponent(BaseHeaderTogglePanel);
const headerWrapper = wrapper.find(getDataTestSelector('toggle-panel-header'));

return {
Expand Down Expand Up @@ -62,6 +62,7 @@ describe('testing BaseHeaderTogglePanel component', () => {

it('emits its open status as an event on header click', async () => {
const { wrapper, toggleOpen } = renderBaseHeaderTogglePanel();

await toggleOpen();
expect(wrapper.emitted().close).toHaveLength(1);
await toggleOpen();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { defineComponent, ref } from 'vue';
import { AnimationProp } from '../../types/animation-prop';
import { NoElement } from '../no-element';
import { dynamicPropsMixin } from '../dynamic-props.mixin';
import BaseTogglePanel from './base-toggle-panel.vue';

/**
Expand All @@ -35,49 +33,58 @@
*
* @public
*/
@Component({
export default defineComponent({
name: 'BaseHeaderTogglePanel',
components: { BaseTogglePanel },
mixins: [dynamicPropsMixin(['headerClass'])]
})
export default class BaseHeaderTogglePanel extends Vue {
/**
* Animation component that will be used to animate the base-toggle-panel.
*
* @public
*/
@Prop({ default: () => NoElement })
protected animation!: typeof AnimationProp;
/**
* Handles if the panel is open by default.
*
* @public
*/
@Prop({ default: false })
protected startCollapsed!: boolean;
/**
* Handles if the base panel is open or closed.
*
* @internal
*/
protected open = !this.startCollapsed;
/**
* Toggles the open property.
*
* @internal
*/
protected toggleOpen(): void {
this.open = !this.open;
this.emitOpenStatusEvent();
props: {
/**
* Animation component that will be used to animate the base-toggle-panel.
*
* @public
*/
animation: { type: AnimationProp, default: () => NoElement },
/**
* Handles if the panel is open by default.
*
* @public
*/
startCollapsed: { type: Boolean, default: false },
/** Class inherited by content element. */
headerClass: String
},
setup: function (props, { emit }) {
/**
* Handles if the base panel is open or closed.
*
* @internal
*/
const open = ref(!props.startCollapsed);

/**
* Emits open status event.
*
* @internal
*/
const emitOpenStatusEvent = () => {
emit(open.value ? 'open' : 'close');
};

/**
* Toggles the open property.
*
* @internal
*/
const toggleOpen = () => {
open.value = !open.value;
emitOpenStatusEvent();
};

return {
open,
toggleOpen
};
}
/**
* Emits open status event.
*
* @internal
*/
protected emitOpenStatusEvent(): void {
this.$emit(this.open ? 'open' : 'close');
}
}
});
</script>

<style lang="scss" scoped>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { defineComponent, ref, computed } from 'vue';
import { XEventsTypes } from '../../wiring/events.types';
import { WireMetadata } from '../../wiring/wiring.types';
import BaseEventButton from '../base-event-button.vue';
import { XOn } from '../decorators/bus.decorators';
import { useXBus } from '../../composables';

/**
* Component containing an event button that emits
Expand All @@ -28,44 +27,60 @@
*
* @public
*/
@Component({
components: { BaseEventButton }
})
export default class BaseIdTogglePanelButton extends Vue {
/**
* The panel state to pass through the slot.
*/
protected isPanelOpen = false;

/** The panelId to use for the toggle event listeners. */
@Prop({ required: true })
protected panelId!: string;

/**
* List of events to emit by the BaseEventButton.
*
* @returns An object with the event and payload.
*
* @internal
*/
protected get events(): Partial<XEventsTypes> {
return { UserClickedPanelToggleButton: this.panelId };
}

/**
* The subscription to the {@link XEventsTypes.TogglePanelStateChanged} event
* to update the `isPanelOpen` property.
*
* @param newState - The new isOpen state of the panel.
* @param id - The `panelId`.
*/
@XOn('TogglePanelStateChanged')
updatePanelState(newState: boolean, { id }: WireMetadata): void {
if (this.panelId === id) {
this.isPanelOpen = newState;
export default defineComponent({
name: 'BaseIdTogglePanelButton',
components: { BaseEventButton },
props: {
/**
* The panelId to use for the toggle event listeners.
*/
panelId: {
type: String,
required: true
}
},
setup: function (props) {
const bus = useXBus();

/**
* The panel state to pass through the slot.
*/
const isPanelOpen = ref(false);

/**
* List of events to emit by the BaseEventButton.
*
* @returns An object with the event and payload.
*
* @internal
*/
const events = computed(
(): Partial<XEventsTypes> => ({ UserClickedPanelToggleButton: props.panelId })
);

/**
* The subscription to the {@link XEventsTypes.TogglePanelStateChanged} event
* to update the `isPanelOpen` property.
*
* @param newState - The new isOpen state of the panel.
* @param id - The `panelId`.
*/
const updatePanelState = (newState: boolean, { id }: WireMetadata) => {
if (props.panelId === id) {
isPanelOpen.value = newState;
}
};

bus
.on('TogglePanelStateChanged', false)
.subscribe(newState => updatePanelState(newState, { id: props.panelId, moduleName: null }));

return {
isPanelOpen,
events
};
}
}
});
</script>

<docs lang="mdx">
Expand Down
Loading
Loading