Skip to content
Open
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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
},
"dependencies": {
"caniuse-lite": "~1.0.30001335",
"dompurify": "^2.3.8",
"dompurify": "~3.2.4",
"path-to-regexp": "^8.2.0",
"qs": "^6.13.0",
"setimmediate": "^1.0.5"
Expand Down
8 changes: 5 additions & 3 deletions packages/venia-concept/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@
},
"homepage": "https://github.com/magento/pwa-studio/tree/main/packages/venia-concept#readme",
"dependencies": {
"@magento/pwa-buildpack": "~11.5.3",
"dompurify": "~3.2.4"
"@magento/experience-platform-connector": "~1.0.9",
"@magento/pwa-buildpack": "~11.5.3"
},
"devDependencies": {
"@adobe/apollo-link-mutation-queue": "~1.0.2",
"@adobe/magento-storefront-events-sdk": "~1.13.0",
"@apollo/client": "~3.5.0",
"@babel/core": "~7.15.0",
"@babel/plugin-proposal-class-properties": "~7.14.5",
Expand All @@ -56,7 +57,7 @@
"@magento/pagebuilder": "~9.3.3",
"@magento/peregrine": "~14.5.1",
"@magento/pwa-theme-venia": "~2.4.0",
"@magento/upward-security-headers": "~1.0.14",
"@magento/upward-security-headers": "1.1.18-alpha9",
"@magento/venia-ui": "~11.6.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.1",
"@storybook/react": "~6.3.7",
Expand All @@ -73,6 +74,7 @@
"braintree-web-drop-in": "~1.43.0",
"compression": "~1.7.4",
"css-loader": "~5.2.7",
"dompurify": "~3.2.4",
"dotenv": "~6.2.0",
"eslint": "~7.32.0",
"eslint-plugin-babel": "~5.3.0",
Expand Down
30 changes: 0 additions & 30 deletions packages/venia-concept/src/.storybook/config.js

This file was deleted.

109 changes: 109 additions & 0 deletions packages/venia-concept/src/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
module.exports = {
stories: [
'../../node_modules/@magento/venia-ui/lib/**/__stories__/*.js',
'../**/__stories__/*.js'
],
addons: [],

// Fix for Manager webpack build (Storybook UI)
managerWebpack: async (config, options) => {

// Add babel rule for react-draggable in manager build
config.module.rules.push({
test: /\.js$/,
include: /node_modules\/react-draggable/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['last 2 versions', 'ie >= 11']
}
}]
]
}
}
});

return config;
},

// Fix for Preview webpack build (Story iframe)
webpackFinal: async (config, { configType }) => {
// Import the existing webpack config logic
const path = require('path');
const {
graphQL: {
getPossibleTypes,
getStoreConfigData,
getAvailableStoresConfigData
},
Utilities: { loadEnvironment }
} = require('@magento/pwa-buildpack');
const baseWebpackConfig = require('../../webpack.config');
const { DefinePlugin, EnvironmentPlugin } = require('webpack');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

const projectConfig = await loadEnvironment(
path.resolve(__dirname, '../..')
);

if (projectConfig.error) {
throw projectConfig.error;
}

const possibleTypes = await getPossibleTypes();
const storeConfigData = await getStoreConfigData();
const { availableStores } = await getAvailableStoresConfigData();
global.LOCALE = storeConfigData.locale.replace('_', '-');

const [webpackConfig] = await baseWebpackConfig(configType);

config.module = webpackConfig.module;
config.resolve = webpackConfig.resolve;

// Add babel rule for react-draggable in preview build too
config.module.rules.push({
test: /\.js$/,
include: /node_modules\/react-draggable/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', {
targets: {
browsers: ['last 2 versions', 'ie >= 11']
}
}]
]
}
}
});

// Make sure to provide any plugins that UI code may depend on.
config.plugins = [
...config.plugins,
new DefinePlugin({
__fetchLocaleData__: async () => {
// no-op in storybook
},
POSSIBLE_TYPES: JSON.stringify(possibleTypes),
STORE_NAME: JSON.stringify('Storybook'),
STORE_VIEW_LOCALE: JSON.stringify(global.LOCALE),
STORE_VIEW_CODE: process.env.STORE_VIEW_CODE
? JSON.stringify(process.env.STORE_VIEW_CODE)
: JSON.stringify(storeConfigData.code),
AVAILABLE_STORE_VIEWS: JSON.stringify(availableStores),
DEFAULT_LOCALE: JSON.stringify(global.LOCALE),
DEFAULT_COUNTRY_CODE: JSON.stringify(
process.env.DEFAULT_COUNTRY_CODE || 'US'
)
}),
new EnvironmentPlugin(projectConfig.env),
new ReactRefreshWebpackPlugin()
];

return config;
},
};
143 changes: 143 additions & 0 deletions packages/venia-concept/src/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import Adapter from '@magento/venia-ui/lib/components/Adapter';
import { Form } from 'informed';
import store from '../store';
import '@magento/venia-ui/lib/index.module.css';
import 'tailwindcss/tailwind.css';

// Mock browser APIs that components might expect
if (typeof window !== 'undefined') {
// Ensure URLSearchParams is available with comprehensive methods
if (!window.URLSearchParams) {
window.URLSearchParams = class URLSearchParams {
constructor(search = '') {
this.params = new Map();
if (typeof search === 'string') {
if (search.startsWith('?')) search = search.slice(1);
if (search) {
search.split('&').forEach(param => {
const [key, value] = param.split('=');
if (key) this.params.set(decodeURIComponent(key), decodeURIComponent(value || ''));
});
}
}
}
get(key) { return this.params.get(key); }
set(key, value) { this.params.set(key, value); }
delete(key) { this.params.delete(key); }
has(key) { return this.params.has(key); }
append(key, value) { this.params.set(key, value); }
toString() {
const entries = Array.from(this.params.entries());
return entries.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join('&');
}
forEach(callback) { this.params.forEach(callback); }
keys() { return this.params.keys(); }
values() { return this.params.values(); }
entries() { return this.params.entries(); }
};
}

// Create comprehensive URL object mock
if (!window.URL) {
window.URL = class URL {
constructor(url, base) {
this.href = url || 'http://localhost:9001/?page=1';
this.origin = 'http://localhost:9001';
this.protocol = 'http:';
this.host = 'localhost:9001';
this.hostname = 'localhost';
this.port = '9001';
this.pathname = '/';
this.search = '?page=1';
this.hash = '';
}
toString() { return this.href; }
};
}

// Mock location.search and other properties that might be undefined
try {
if (!window.location.search || window.location.search === '') {
Object.defineProperty(window.location, 'search', {
value: '?page=1',
writable: true,
configurable: true
});
}
if (!window.location.pathname || window.location.pathname === '') {
Object.defineProperty(window.location, 'pathname', {
value: '/',
writable: true,
configurable: true
});
}
} catch (e) {
// Some browsers don't allow modifying location
console.warn('Could not mock location properties:', e);
}

// Global string replacement protection
const originalStringReplace = String.prototype.replace;
String.prototype.replace = function(...args) {
if (this == null || this === undefined) {
console.warn('Attempted to call replace on undefined/null value');
return '';
}
return originalStringReplace.apply(this, args);
};
}

const origin = process.env.MAGENTO_BACKEND_URL || 'https://master-7rqtwti-c5v7sxvquxwl4.eu-4.magentosite.cloud/';

// Form wrapper for components that need form context
const FormWrapper = ({ children }) => {
return (
<Form>
{children}
</Form>
);
};

// Router wrapper for components that need routing context
const RouterWrapper = ({ children }) => {
// Provide initial location with comprehensive data that components might expect
const initialEntries = [
{
pathname: '/',
search: '?page=1',
hash: '',
state: null,
key: 'default'
}
];

return (
<MemoryRouter initialEntries={initialEntries}>
{children}
</MemoryRouter>
);
};

export const decorators = [
(Story) => (
<RouterWrapper>
<Adapter origin={origin} store={store}>
<FormWrapper>
<Story />
</FormWrapper>
</Adapter>
</RouterWrapper>
),
];

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
61 changes: 0 additions & 61 deletions packages/venia-concept/src/.storybook/webpack.config.js

This file was deleted.

Loading