diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index cf094ffc2..3e88ae961 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,24 +1,146 @@
import type { Preview } from '@storybook/react';
+import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
import React from 'react';
-import ExtensionRoot from 'src/views/components/common/ExtensionRoot/ExtensionRoot';
const preview: Preview = {
- parameters: {
- actions: { argTypesRegex: '^on[A-Z].*' },
- controls: {
- matchers: {
- color: /(background|color)$/i,
- date: /Date$/i,
- },
+ parameters: {
+ actions: { argTypesRegex: '^on[A-Z].*' },
+ controls: {
+ matchers: {
+ color: /(background|color)$/i,
+ date: /Date$/i,
+ },
+ },
},
- },
- decorators: [
- Story => (
-
-
-
- ),
- ],
+ decorators: [
+ Story => (
+
+
+
+
+
+ ),
+ ],
};
+let localData = {};
+type ListenerFunction = (
+ changes: { [key: string]: chrome.storage.StorageChange },
+ areaName: chrome.storage.AreaName
+) => void;
+const localDataListeners = new Map<
+ ListenerFunction, // key to remove listener
+ (changes: { [key: string]: chrome.storage.StorageChange }) => void
+>();
+
+// mock chrome api
+globalThis.chrome = {
+ storage: {
+ local: {
+ /**
+ * Removes all items from storage.
+ * @param callback Optional.
+ * Callback on success, or on failure (in which case runtime.lastError will be set).
+ */
+ async clear() {
+ localData = {};
+ },
+ /**
+ * Gets one or more items from storage.
+ * @param keys A single key to get, list of keys to get, or a dictionary specifying default values.
+ * An empty list or object will return an empty result object. Pass in null to get the entire contents of storage.
+ * @return A Promise that resolves with an object containing items
+ */
+ async get(keys?: string | string[] | { [key: string]: any } | null) {
+ if (keys === null) {
+ return localData;
+ }
+ if (Array.isArray(keys)) {
+ return keys.reduce((acc, key) => {
+ acc[key] = localData[key];
+ return acc;
+ }, {} as string); // funny types
+ }
+ if (typeof keys === 'string') {
+ return { [keys]: localData[keys] };
+ }
+ return keys;
+ },
+ /**
+ * Gets the amount of space (in bytes) being used by one or more items.
+ * @param keys Optional. A single key or list of keys to get the total usage for. An empty list will return 0. Pass in null to get the total usage of all of storage.
+ * @param callback Callback with the amount of space being used by storage, or on failure (in which case runtime.lastError will be set).
+ * Parameter bytesInUse: Amount of space being used in storage, in bytes.
+ */
+ async getBytesInUse() {
+ return 0;
+ },
+ /**
+ * Removes one or more items from storage.
+ * @param keys A single key or a list of keys for items to remove.
+ * @param callback Optional.
+ * Callback on success, or on failure (in which case runtime.lastError will be set).
+ */
+ async remove(keys: string | string[]) {
+ if (Array.isArray(keys)) {
+ keys.forEach(key => {
+ for (const listener of localDataListeners.values()) {
+ listener({ [key]: { oldValue: localData[key], newValue: undefined } });
+ }
+
+ delete localData[key];
+ });
+ } else {
+ for (const listener of localDataListeners.values()) {
+ listener({ [keys]: { oldValue: localData[keys], newValue: undefined } });
+ }
+
+ delete localData[keys];
+ }
+ },
+ /**
+ * Sets multiple items.
+ * @param items An object which gives each key/value pair to update storage with. Any other key/value pairs in storage will not be affected.
+ * Primitive values such as numbers will serialize as expected. Values with a typeof "object" and "function" will typically serialize to {}, with the exception of Array (serializes as expected), Date, and Regex (serialize using their String representation).
+ * @param callback Optional.
+ * Callback on success, or on failure (in which case runtime.lastError will be set).
+ */
+ async set(items: { [key: string]: any }) {
+ for (const key in items) {
+ const oldValue = localData[key];
+ localData[key] = JSON.parse(JSON.stringify(items[key]));
+
+ for (const listener of localDataListeners.values()) {
+ listener({ [key]: { oldValue: oldValue, newValue: localData[key] } });
+ }
+ }
+ },
+ },
+ onChanged: {
+ /**
+ * Registers an event listener callback to an event.
+ * @param callback Called when an event occurs. The parameters of this function depend on the type of event.
+ */
+ addListener(
+ listener: (
+ changes: { [key: string]: chrome.storage.StorageChange },
+ areaName: chrome.storage.AreaName
+ ) => void
+ ) {
+ localDataListeners.set(listener, (changes: { [key: string]: chrome.storage.StorageChange }) => {
+ listener(changes, 'local');
+ });
+ },
+
+ /**
+ * Deregisters an event listener callback from an event.
+ * @param callback Listener that shall be unregistered.
+ */
+ removeListener(listener: ListenerFunction) {
+ localDataListeners.delete(listener);
+ },
+ },
+ },
+} as typeof chrome;
+
export default preview;