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

Added MediaQueryList mocks #2077

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion explorer/src/lib/components/__tests__/BlocksCard.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ describe("Blocks Card", () => {
const data = getTenBlocks(gqlBlocks.blocks);

const baseProps = {
appStore: appStore,
blocks: null,
error: null,
loading: false,
appStore: appStore
};
const baseOptions = {
props: baseProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ describe("Transactions Card", () => {
const data = getTenTransactions(gqlTransactions.transactions);

const baseProps = {
appStore: appStore,
error: null,
loading: false,
txns: null,
appStore: appStore
};
const baseOptions = {
props: baseProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,36 +745,5 @@ exports[`Blocks Card > should render the \`BlocksCard\` component 1`] = `



</div>
`;

exports[`Blocks Card > should render the \`BlocksCard\` component with the mobile layout 1`] = `
<div
class="dusk-card data-card"
>
<header
class="data-card__header"
slot="header"
>
<h1
class="data-card__header-title"
>
Blocks — 0 Displayed Items
</h1>

<button
class="dusk-button dusk-button--type--button dusk-button--variant--tertiary dusk-button--size--normal"
type="button"
>
<span
class="dusk-button__text"
>
Show More
</span>
</button>
</header>



</div>
`;
8 changes: 3 additions & 5 deletions explorer/src/lib/components/blocks-card/BlocksCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
$: displayedBlocks = blocks ? blocks.slice(0, itemsToDisplay) : [];
$: isLoadMoreDisabled =
(blocks && itemsToDisplay >= blocks.length) || (loading && blocks === null);
$: ({ isSmallScreen } = $appStore);

const loadMoreItems = () => {
if (blocks && itemsToDisplay < blocks.length) {
Expand All @@ -47,16 +48,13 @@
label: "Show More",
}}
>
{#if $appStore.isSmallScreen}
{#if isSmallScreen}
<div class="blocks-card__list">
{#each displayedBlocks as block (block)}
<BlocksList data={block} />
{/each}
</div>
{:else}
<BlocksTable
data={displayedBlocks}
className="blocks-card__table"
/>
<BlocksTable data={displayedBlocks} className="blocks-card__table" />
{/if}
</DataCard>
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
/** @type {Boolean} */
export let loading;

/** @type {AppStore} */
export let appStore;
/** @type {boolean} */
export let isSmallScreen;

$: classes = makeClassName(["latest-blocks-card", className]);
</script>
Expand All @@ -36,11 +36,11 @@
label: "All Blocks",
}}
>
{#if $appStore.isSmallScreen}
{#if isSmallScreen}
{#each blocks as block (block)}
<BlocksList data={block} />
{/each}
{:else}
<BlocksTable data={blocks}/>
<BlocksTable data={blocks} />
{/if}
</DataCard>
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
/** @type {Boolean} */
export let displayTooltips = false;

/** @type {AppStore} */
export let appStore;
/** @type {boolean} */
export let isSmallScreen;

$: classes = makeClassName(["latest-transactions-card", className]);
</script>
Expand All @@ -48,7 +48,7 @@
}
: undefined}
>
{#if $appStore.isSmallScreen}
{#if isSmallScreen}
{#each txns as txn (txn)}
<TransactionsList
data={txn}
Expand All @@ -57,9 +57,6 @@
/>
{/each}
{:else}
<TransactionsTable
data={txns}
mode={isOnHomeScreen ? "compact" : "full"}
/>
<TransactionsTable data={txns} mode={isOnHomeScreen ? "compact" : "full"} />
{/if}
</DataCard>
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
$: displayedTxns = txns ? txns.slice(0, itemsToDisplay) : [];
$: isLoadMoreDisabled =
(txns && itemsToDisplay >= txns.length) || (loading && txns === null);
$: ({ isSmallScreen } = $appStore);

const loadMoreItems = () => {
if (txns && itemsToDisplay < txns.length) {
Expand All @@ -51,7 +52,7 @@
label: "Show More",
}}
>
{#if $appStore.isSmallScreen}
{#if isSmallScreen}
<div class="transactions-card__list">
{#each displayedTxns as txn (txn)}
<TransactionsList data={txn} mode="full" />
Expand Down
104 changes: 67 additions & 37 deletions explorer/src/lib/dusk/mocks/MediaQueryList.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,68 @@
export default class MediaQueryList {
/**
* @param {String} query
*/
constructor(query) {
this.matches = false;
this.media = query;
this.listeners = [];
import { afterAll } from "vitest";

const controllers = new Set();

afterAll(() => {
controllers.forEach((controller) => {
controller.abort();
controllers.delete(controller);
});
});

/**
* Mocks the `MediaQueryList` object and listens to the
* "DuskMediaQueryMatchesChange" custom event.
* Fire one manually or with the `changeMediaQueryMatches`
* helper function to simulate media query changes.
*/
export default class MediaQueryList extends EventTarget {
#matches;

#media;

/**
* @param {string} mediaQuery
* @param {boolean} initialMatches
*/
constructor(mediaQuery, initialMatches) {
super();

this.#matches = initialMatches;
this.#media = mediaQuery;

const abortController = new AbortController();

controllers.add(abortController);

global.addEventListener("DuskMediaQueryMatchesChange", this, {
signal: abortController.signal,
});
}

get matches() {
return this.#matches;
}

get media() {
return this.#media;
}

/** @param {CustomEvent<{ media: string, matches: boolean }>} evt */
handleEvent(evt) {
const { detail, type } = evt;

if (
type === "DuskMediaQueryMatchesChange" &&
detail.media === this.#media
) {
this.#matches = detail.matches;

this.dispatchEvent(
new MediaQueryListEvent("change", {
matches: this.#matches,
media: this.#media,
})
);
}

/**
* @param {String} event
* @param {Function} callback
*/
addEventListener(event, callback) {
if (event === 'change') {
this.listeners.push(callback);
}
}

/**
* @param {String} event
* @param {Function} callback
*/
removeEventListener(event, callback) {
if (event === 'change') {
this.listeners = this.listeners.filter(listener => listener !== callback);
}
}

/**
* @param {Boolean} matches
*/
change(matches) {
this.matches = matches;
this.listeners.forEach(listener => listener({ matches }));
}
}
}
}
26 changes: 26 additions & 0 deletions explorer/src/lib/dusk/mocks/MediaQueryListEvent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { pickIn } from "lamb";

export default class MediaQueryListEvent extends Event {
#matches;

#media;

/**
* @param {string} type
* @param {MediaQueryListEventInit} options
*/
constructor(type, options) {
super(type, pickIn(options, ["bubbles", "cancelable", "composed"]));

this.#matches = options.matches;
this.#media = options.media;
}

get matches() {
return this.#matches;
}

get media() {
return this.#media;
}
}
1 change: 1 addition & 0 deletions explorer/src/lib/dusk/mocks/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as IntersectionObserver } from "./IntersectionObserver";
export { default as MediaQueryList } from "./MediaQueryList";
export { default as MediaQueryListEvent } from "./MediaQueryListEvent";
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, expect, it } from "vitest";

import { changeMediaQueryMatches } from "..";

describe("changeMediaQueryMatches", () => {
it('should dispatch "DuskMediaQueryMatchesChange" custom events', () => {
const media = "(max-width: 1024px)";
const matches = true;

/** @param {Event} evt */
const handler = (evt) => {
expect(evt).toBeInstanceOf(CustomEvent);
expect(evt.type).toBe("DuskMediaQueryMatchesChange");

// @ts-ignore see https://github.com/Microsoft/TypeScript/issues/28357
expect(evt.detail).toStrictEqual({ matches, media });
};

global.addEventListener("DuskMediaQueryMatchesChange", handler);

changeMediaQueryMatches(media, matches);

global.removeEventListener("DuskMediaQueryMatchesChange", handler);

expect.assertions(3);
});
});
14 changes: 14 additions & 0 deletions explorer/src/lib/dusk/test-helpers/changeMediaQueryMatches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Helper to fire "DuskMediaQueryMatchesChange" custom
* events that are listened by our `MediaQueryList` mock.
*
* @param {string} media
* @param {boolean} matches
*/
export default function changeMediaQueryMatches(media, matches) {
dispatchEvent(
new CustomEvent("DuskMediaQueryMatchesChange", {
detail: { matches, media },
})
);
}
1 change: 1 addition & 0 deletions explorer/src/lib/dusk/test-helpers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as changeMediaQueryMatches } from "./changeMediaQueryMatches";
export { default as mockReadableStore } from "./mockReadableStore";
export { default as renderWithSimpleContent } from "./renderWithSimpleContent";
export { default as renderWithSlots } from "./renderWithSlots";
Expand Down
Loading
Loading