@blocklet/pages-kit-block-studio 0.5.56 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -208,20 +208,24 @@ const ComparisonPreviewDialog = ({ open, title, leftTitle, leftContent, rightTit
208
208
  Toast.error(t('themeTranslations.operationFailed'));
209
209
  }
210
210
  };
211
- return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [_jsx(DialogTitle, { children: title }), _jsx(DialogContent, { children: _jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', flexDirection: 'row', mb: 2 }, children: [_jsxs(Box, { sx: { flex: 1, mr: 1 }, children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: leftTitle }), _jsx(TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
212
- readOnly: true,
213
- }, value: leftContent, sx: {
211
+ return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [_jsx(DialogTitle, { children: title }), _jsx(DialogContent, { children: _jsxs(Box, { children: [_jsxs(Box, { sx: { display: 'flex', flexDirection: 'row', mb: 2 }, children: [_jsxs(Box, { sx: { flex: 1, mr: 1 }, children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: leftTitle }), _jsx(TextField, { multiline: true, fullWidth: true, rows: 10, value: leftContent, sx: {
214
212
  '& .MuiOutlinedInput-root': {
215
213
  fontFamily: 'monospace',
216
214
  fontSize: '0.875rem',
217
215
  },
218
- } })] }), _jsxs(Box, { sx: { flex: 1, ml: 1 }, children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: rightTitle }), _jsx(TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
219
- readOnly: true,
220
- }, value: rightContent, sx: {
216
+ }, slotProps: {
217
+ input: {
218
+ readOnly: true,
219
+ },
220
+ } })] }), _jsxs(Box, { sx: { flex: 1, ml: 1 }, children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: rightTitle }), _jsx(TextField, { multiline: true, fullWidth: true, rows: 10, value: rightContent, sx: {
221
221
  '& .MuiOutlinedInput-root': {
222
222
  fontFamily: 'monospace',
223
223
  fontSize: '0.875rem',
224
224
  },
225
+ }, slotProps: {
226
+ input: {
227
+ readOnly: true,
228
+ },
225
229
  } })] })] }), _jsx(Typography, { variant: "body2", sx: { mt: 2, color: 'text.secondary' }, children: description })] }) }), _jsxs(Box, { sx: { display: 'flex', justifyContent: 'flex-end', p: 2 }, children: [_jsx(Button, { variant: "outlined", onClick: onClose, sx: { mr: 1 }, children: t('themeTranslations.cancel') }), _jsx(Button, { variant: "contained", onClick: handleConfirm, disabled: loading, children: loading ? _jsx(CircularProgress, { size: 24 }) : t('themeTranslations.confirmUpdate') })] })] }));
226
230
  };
227
231
  function Layout({ loadState, loadedData }) {
@@ -483,7 +487,11 @@ function Layout({ loadState, loadedData }) {
483
487
  triggerRerender();
484
488
  }, [JSON.stringify(mergedPropertiesValues), JSON.stringify(mergedAllBlocks), state.metadata.id, locale]);
485
489
  const DraggingSplitPlaceholder = useMemo(() => {
486
- return (_jsx(Box, { p: 1.5, width: "100%", height: "100%", children: _jsx(Skeleton, { variant: "rectangular", height: "100%", sx: { borderRadius: 1 } }) }));
490
+ return (_jsx(Box, { sx: {
491
+ p: 1.5,
492
+ width: '100%',
493
+ height: '100%',
494
+ }, children: _jsx(Skeleton, { variant: "rectangular", height: "100%", sx: { borderRadius: 1 } }) }));
487
495
  }, []);
488
496
  // Move item function for drag and drop
489
497
  const moveItem = useCallback((dragIndex, hoverIndex) => {
@@ -570,7 +578,16 @@ function Layout({ loadState, loadedData }) {
570
578
  if (state.draggingSplitPane) {
571
579
  return DraggingSplitPlaceholder;
572
580
  }
573
- return (_jsxs(Stack, { height: "100%", children: [_jsxs(Stack, { gap: 1, direction: "row", alignItems: "center", sx: { pt: 2, pr: 1, pl: 0.5, pb: 1 }, children: [_jsx(TextField, { placeholder: t('themeTranslations.search'), sx: { minWidth: 60, flex: 1 }, onChange: (e) => {
581
+ return (_jsxs(Stack, { sx: {
582
+ height: '100%',
583
+ }, children: [_jsxs(Stack, { direction: "row", sx: {
584
+ gap: 1,
585
+ alignItems: 'center',
586
+ pt: 2,
587
+ pr: 1,
588
+ pl: 0.5,
589
+ pb: 1,
590
+ }, children: [_jsx(TextField, { placeholder: t('themeTranslations.search'), sx: { minWidth: 60, flex: 1 }, onChange: (e) => {
574
591
  state.searchValue = e.target.value;
575
592
  } }), hasCustomSort && (_jsx(Tooltip, { title: t('themeTranslations.resetToAlphabeticalSort'), children: _jsx(IconButton, { size: "small", onClick: () => {
576
593
  setCustomSortOrder([]);
@@ -605,12 +622,27 @@ function Layout({ loadState, loadedData }) {
605
622
  }
606
623
  }, onDelete: handleDeleteBlock, index: index, moveItem: moveItem, showDragHandle: true, routes: routes }, route));
607
624
  })
608
- .filter(Boolean) })) : (_jsx(Box, { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", sx: { p: 3 }, children: _jsxs(Stack, { alignItems: "center", spacing: 3, sx: { textAlign: 'center' }, children: [_jsx(Box, { component: "img", src: "https://api.iconify.design/material-symbols:folder-open-outline.svg", sx: {
625
+ .filter(Boolean) })) : (_jsx(Box, { sx: {
626
+ display: 'flex',
627
+ justifyContent: 'center',
628
+ alignItems: 'center',
629
+ height: '100%',
630
+ p: 3,
631
+ }, children: _jsxs(Stack, { spacing: 3, sx: {
632
+ alignItems: 'center',
633
+ textAlign: 'center',
634
+ }, children: [_jsx(Box, { component: "img", src: "https://api.iconify.design/material-symbols:folder-open-outline.svg", sx: {
609
635
  width: 48,
610
636
  height: 48,
611
637
  opacity: 0.5,
612
638
  filter: 'grayscale(100%)',
613
- }, alt: "No components" }), _jsx(Typography, { variant: "h6", color: "text.primary", sx: { fontWeight: 600 }, children: t('themeTranslations.noComponentsFound') }), _jsx(Typography, { variant: "body2", color: "text.secondary", sx: { maxWidth: 200 }, children: t('themeTranslations.createFirstComponent') }), _jsx(Button, { variant: "contained", startIcon: _jsx(AddIcon, {}), onClick: () => {
639
+ }, alt: "No components" }), _jsx(Typography, { variant: "h6", sx: {
640
+ color: 'text.primary',
641
+ fontWeight: 600,
642
+ }, children: t('themeTranslations.noComponentsFound') }), _jsx(Typography, { variant: "body2", sx: {
643
+ color: 'text.secondary',
644
+ maxWidth: 200,
645
+ }, children: t('themeTranslations.createFirstComponent') }), _jsx(Button, { variant: "contained", startIcon: _jsx(AddIcon, {}), onClick: () => {
614
646
  state.createBlockOpen = true;
615
647
  }, sx: { mt: 2 }, children: t('themeTranslations.createComponent') })] }) }))] }));
616
648
  }, [
@@ -635,7 +667,13 @@ function Layout({ loadState, loadedData }) {
635
667
  return null;
636
668
  }
637
669
  if (loadState.type === 'load-error') {
638
- return (_jsx(Box, { width: "100%", height: "100%", display: "flex", justifyContent: "center", alignItems: "center", children: _jsx(Alert, { severity: "error", variant: "filled", children: t('themeTranslations.failedLoadCode') }) }));
670
+ return (_jsx(Box, { sx: {
671
+ width: '100%',
672
+ height: '100%',
673
+ display: 'flex',
674
+ justifyContent: 'center',
675
+ alignItems: 'center',
676
+ }, children: _jsx(Alert, { severity: "error", variant: "filled", children: t('themeTranslations.failedLoadCode') }) }));
639
677
  }
640
678
  // 从 URL 获取初始组件 ID 和语言
641
679
  const url = new URL(window.location.href);
@@ -649,7 +687,13 @@ function Layout({ loadState, loadedData }) {
649
687
  }
650
688
  // 没有匹配到路由,使用欢迎页面
651
689
  if (notSelectedBlock) {
652
- return (_jsxs(Box, { width: "100%", height: "100%", display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", sx: {
690
+ return (_jsxs(Box, { sx: {
691
+ width: '100%',
692
+ height: '100%',
693
+ display: 'flex',
694
+ flexDirection: 'column',
695
+ justifyContent: 'center',
696
+ alignItems: 'center',
653
697
  backgroundColor: 'background.default',
654
698
  p: 3,
655
699
  textAlign: 'center',
@@ -841,12 +885,18 @@ function Layout({ loadState, loadedData }) {
841
885
  justifyContent: 'center',
842
886
  alignItems: 'center',
843
887
  p: 3,
844
- }, children: _jsxs(Stack, { alignItems: "center", spacing: 2, sx: {
888
+ }, children: _jsxs(Stack, { spacing: 2, sx: {
889
+ alignItems: 'center',
845
890
  textAlign: 'center',
846
891
  bgcolor: 'background.default',
847
892
  borderRadius: 2,
848
893
  p: 3,
849
- }, children: [_jsx(SettingsIcon, { sx: { fontSize: 48, color: 'primary.main' } }), _jsxs(Stack, { spacing: 1, children: [_jsx(Typography, { variant: "h6", color: "primary.main", sx: { fontWeight: 600 }, children: t('themeTranslations.componentPropertiesTitle') }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: t('themeTranslations.selectComponentToConfigureProperties') })] })] }) })), _jsx(ListItem, { children: _jsx(Box, { sx: { width: '100%' }, children: _jsx(BasicInfo, { config: state.metadata }) }) }), _jsx(ListItem, { children: _jsxs(Box, { sx: { width: '100%' }, children: [_jsx(PropertiesConfig, { config: state.metadata, currentLocale: locale, defaultLocale: defaultLocale, allComponents: mergedAllBlocks, onUpdateConfig: (updater) => {
894
+ }, children: [_jsx(SettingsIcon, { sx: { fontSize: 48, color: 'primary.main' } }), _jsxs(Stack, { spacing: 1, children: [_jsx(Typography, { variant: "h6", sx: {
895
+ color: 'primary.main',
896
+ fontWeight: 600,
897
+ }, children: t('themeTranslations.componentPropertiesTitle') }), _jsx(Typography, { variant: "body2", sx: {
898
+ color: 'text.secondary',
899
+ }, children: t('themeTranslations.selectComponentToConfigureProperties') })] })] }) })), _jsx(ListItem, { children: _jsx(Box, { sx: { width: '100%' }, children: _jsx(BasicInfo, { config: state.metadata }) }) }), _jsx(ListItem, { children: _jsxs(Box, { sx: { width: '100%' }, children: [_jsx(PropertiesConfig, { config: state.metadata, currentLocale: locale, defaultLocale: defaultLocale, allComponents: mergedAllBlocks, onUpdateConfig: (updater) => {
850
900
  updater(state.metadata);
851
901
  }, useI18nEditor: false }), _jsxs(Stack, { direction: "column", spacing: 1, sx: { mt: 1 }, children: [_jsx(Button, { variant: "contained", size: "small", color: "primary", onClick: async () => {
852
902
  try {
@@ -23,14 +23,35 @@ VIRTUAL_MODULE_ID, readHtmlFiles, generateComponent, } from './vite-plugin-html-
23
23
  import { importTransformPlugin } from './vite-plugin-import-transform';
24
24
  // const BUILTIN_MODULES_VAR = '__PAGES_KIT_BUILTIN_MODULES__';
25
25
  // logger.log('BUILTIN_MODULES_VAR', BUILTIN_MODULES_VAR);
26
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
- const isMatchAfterSlachExternals = (_id) => {
26
+ // 检查模块ID是否匹配外部依赖(包括子路径)
27
+ const isMatchAfterSlachExternals = (id, externals) => {
28
+ // 精确匹配
29
+ if (externals[id]) {
30
+ return true;
31
+ }
32
+ // 子路径匹配,特别处理 React 相关模块
33
+ const reactModules = ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom/client'];
34
+ // 检查是否是 React 相关模块的子路径
35
+ for (const reactModule of reactModules) {
36
+ if (id === reactModule || id.startsWith(`${reactModule}/`)) {
37
+ return true;
38
+ }
39
+ }
40
+ // 检查其他外部依赖的子路径
41
+ for (const externalModule of Object.keys(externals)) {
42
+ if (id.startsWith(`${externalModule}/`)) {
43
+ return true;
44
+ }
45
+ }
28
46
  return false;
29
47
  };
30
48
  const defaultBlockExternals = {
31
- // 核心 React 相关
49
+ // 核心 React 相关 - 确保完全外部化
32
50
  react: '@blocklet/pages-kit/builtin/react',
33
51
  'react-dom': '@blocklet/pages-kit/builtin/react-dom',
52
+ 'react-dom/client': '@blocklet/pages-kit/builtin/react-dom',
53
+ 'react/jsx-runtime': '@blocklet/pages-kit/builtin/react',
54
+ 'react/jsx-dev-runtime': '@blocklet/pages-kit/builtin/react',
34
55
  'react-router-dom': '@blocklet/pages-kit/builtin/react-router-dom',
35
56
  'react-hook-form': '@blocklet/pages-kit/builtin/react-hook-form',
36
57
  'react-wrap-balancer': '@blocklet/pages-kit/builtin/react-wrap-balancer',
@@ -102,14 +123,6 @@ export function initBlockStudioPlugins(options) {
102
123
  externalMappings = options.blockExternals;
103
124
  }
104
125
  setBlockEntryFilesPattern(entryFilesPattern);
105
- logger.log('initBlockStudioPlugins options: ', {
106
- cwd: workingDir,
107
- watchFilesDir,
108
- entryFilesPattern: getBlockEntryFilesPattern(),
109
- pagesDir,
110
- blockExternals: externalMappings, // 添加日志输出
111
- transpileBuiltinModule,
112
- });
113
126
  // 为 globals 创建一个无前缀的版本
114
127
  const pathMappings = Object.fromEntries(Object.entries(externalMappings).filter(([, value]) => !value.startsWith('window.') && value.length > 0));
115
128
  const externalGlobalMappings = Object.fromEntries(Object.entries(externalMappings).filter(([, value]) => value.startsWith('window.') && value.length > 0));
@@ -118,12 +131,32 @@ export function initBlockStudioPlugins(options) {
118
131
  if (!value?.length) {
119
132
  return [];
120
133
  }
134
+ // 特殊处理 React 相关模块
135
+ const reactGlobals = {
136
+ react: 'React',
137
+ 'react-dom': 'ReactDOM',
138
+ 'react/jsx-runtime': 'React',
139
+ 'react/jsx-dev-runtime': 'React',
140
+ 'react-dom/client': 'ReactDOM',
141
+ };
142
+ if (reactGlobals[key]) {
143
+ return [key, reactGlobals[key]];
144
+ }
121
145
  // 移除 "window." 前缀并转换为首字母大写的驼峰式
122
146
  const rawName = String(key);
123
147
  const globalName = upperFirst(camelCase(rawName));
124
148
  return [key, globalName];
125
149
  })
126
150
  .filter((item) => item.length > 0));
151
+ logger.log('initBlockStudioPlugins options: ', {
152
+ cwd: workingDir,
153
+ watchFilesDir,
154
+ entryFilesPattern: getBlockEntryFilesPattern(),
155
+ pagesDir,
156
+ blockExternals: externalMappings,
157
+ globalsMappings,
158
+ transpileBuiltinModule,
159
+ });
127
160
  const filterModules = process.argv.includes('--filter')
128
161
  ? process.argv[process.argv.indexOf('--filter') + 1]?.split(',')
129
162
  : null;
@@ -202,10 +235,14 @@ export function initBlockStudioPlugins(options) {
202
235
  ..._config?.build?.rollupOptions,
203
236
  external: _config?.build?.rollupOptions?.external ||
204
237
  ((id) => {
205
- // 是否匹配后缀
206
- const isMatchAfterSlash = isMatchAfterSlachExternals(id);
238
+ // 使用改进的外部依赖检查
239
+ const isExternal = isMatchAfterSlachExternals(id, externalMappings);
240
+ if (isExternal) {
241
+ return true;
242
+ }
243
+ // 兼容原有逻辑
207
244
  const skipList = [...Object.keys(externalMappings)];
208
- if (skipList.some((item) => (isMatchAfterSlash && id.startsWith(`${item}/`)) || id === item)) {
245
+ if (skipList.some((item) => id === item)) {
209
246
  return true;
210
247
  }
211
248
  return false;