@blocklet/pages-kit 0.4.108 → 0.4.110

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.
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.ConfigColorDialog = void 0;
30
+ exports.ColorItem = ColorItem;
31
+ exports.ColorPicker = ColorPicker;
32
+ const jsx_runtime_1 = require("react/jsx-runtime");
33
+ const Empty_1 = __importDefault(require("@arcblock/ux/lib/Empty"));
34
+ const context_1 = require("@arcblock/ux/lib/Locale/context");
35
+ const material_1 = require("@mui/material");
36
+ const ahooks_1 = require("ahooks");
37
+ const react_1 = require("react");
38
+ const tinycolor2_1 = __importDefault(require("tinycolor2"));
39
+ const color_1 = require("../contexts/color");
40
+ const style_1 = require("../utils/style");
41
+ const ColorPickerLib = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('react-best-gradient-color-picker'))));
42
+ const HEIGHT = 400;
43
+ const WIDTH = 270;
44
+ function ColorItem({ color, sx = {}, ...props }) {
45
+ (0, style_1.isColorString)(color);
46
+ const styleMap = {};
47
+ if ((0, style_1.isGradient)(color)) {
48
+ styleMap.backgroundImage = color;
49
+ }
50
+ else {
51
+ styleMap.backgroundColor = color;
52
+ }
53
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
54
+ ...sx,
55
+ width: '100%',
56
+ paddingBottom: '100%',
57
+ cursor: 'pointer',
58
+ transition: 'opacity 0.2s',
59
+ border: '1px solid #ccc',
60
+ borderRadius: 0.5,
61
+ '&:hover': {
62
+ opacity: 0.75,
63
+ },
64
+ ...styleMap,
65
+ }, ...props }));
66
+ }
67
+ function ColorPicker({ value, onChange, style = {}, sx = {} }) {
68
+ const refDialog = (0, react_1.useRef)(null);
69
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ColorItem, { color: value, style: { width: '1rem', height: '1rem', padding: 0, marginRight: '0.25rem', ...style }, sx: { ...sx }, onClick: () => {
70
+ refDialog.current?.open({ value });
71
+ } }), (0, jsx_runtime_1.jsx)(exports.ConfigColorDialog, { ref: refDialog, onSave: ({ value }, close) => {
72
+ onChange(value);
73
+ close();
74
+ } })] }));
75
+ }
76
+ exports.default = ColorPicker;
77
+ exports.ConfigColorDialog = (0, react_1.forwardRef)(function ConfigColorDialog({ onSave, enableMuiPalette = true }, ref) {
78
+ const state = (0, ahooks_1.useReactive)({
79
+ value: '',
80
+ originalMuiKey: null,
81
+ });
82
+ const { t } = (0, context_1.useLocaleContext)();
83
+ const [activeTab, setActiveTab] = (0, ahooks_1.useLocalStorageState)('pages-kit:color-picker-active-tab', {
84
+ defaultValue: 0,
85
+ });
86
+ const muiPalette = (0, color_1.useMuiColorPalette)();
87
+ const previewStyle = {};
88
+ if (state.value) {
89
+ if ((0, style_1.isGradient)(state.value)) {
90
+ previewStyle.backgroundImage = state.value;
91
+ }
92
+ else {
93
+ previewStyle.backgroundColor = state.value;
94
+ }
95
+ }
96
+ else {
97
+ previewStyle.border = '1px solid #ccc';
98
+ }
99
+ const [open, { setFalse, setTrue }] = (0, ahooks_1.useBoolean)(false);
100
+ const handleClose = (0, react_1.useCallback)(() => {
101
+ setFalse();
102
+ }, [setFalse]);
103
+ const isActiveMuiTab = enableMuiPalette && activeTab === 0;
104
+ (0, react_1.useImperativeHandle)(ref, () => {
105
+ return {
106
+ open({ value } = { value: '' }) {
107
+ // 处理 MUI 色板键
108
+ if (enableMuiPalette && muiPalette.isMuiColorKey(value)) {
109
+ state.originalMuiKey = value;
110
+ const colorValue = muiPalette.getColorByMuiKey(value);
111
+ state.value = (0, style_1.getSafeGradient)(colorValue || value);
112
+ // 如果是 MUI 颜色键,再切换到 MUI Theme 标签
113
+ setActiveTab(0);
114
+ }
115
+ else {
116
+ state.originalMuiKey = null;
117
+ state.value = (0, style_1.getSafeGradient)(value);
118
+ // 不自动切换标签,尊重用户上一次的选择
119
+ // 只有在 MUI 不可用时才强制切换到自定义
120
+ if (!enableMuiPalette) {
121
+ setActiveTab(1);
122
+ }
123
+ }
124
+ setTrue();
125
+ },
126
+ close() {
127
+ handleClose();
128
+ },
129
+ };
130
+ });
131
+ const handleSave = () => {
132
+ // 启用 MUI 预设时,检查是否为 MUI 颜色
133
+ if (enableMuiPalette && muiPalette) {
134
+ // 只有当前在 MUI Theme 标签页时才尝试自动转换为 MUI 色键
135
+ if (isActiveMuiTab) {
136
+ const muiKey = muiPalette.getMuiKeyByColor(state.value);
137
+ onSave({ value: muiKey || state.value }, handleClose);
138
+ }
139
+ else {
140
+ // 在自定义色彩标签页时,保持原始值
141
+ onSave({ value: state.value }, handleClose);
142
+ }
143
+ }
144
+ else {
145
+ onSave({ value: state.value }, handleClose);
146
+ }
147
+ };
148
+ // 直接从 hook 获取分组
149
+ const { groupedMuiColors } = muiPalette;
150
+ return ((0, jsx_runtime_1.jsxs)(material_1.Dialog, { disableEnforceFocus: true, open: open, onClose: handleClose, children: [(0, jsx_runtime_1.jsxs)(material_1.DialogTitle, { sx: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "inherit", component: "div", children: t('maker.configColor') }), enableMuiPalette && ((0, jsx_runtime_1.jsxs)(material_1.ButtonGroup, { size: "small", "aria-label": "color mode selector", children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: isActiveMuiTab ? 'contained' : 'outlined', onClick: () => setActiveTab(0), sx: {
151
+ fontWeight: 500,
152
+ textTransform: 'none',
153
+ minWidth: 'unset',
154
+ }, children: t('maker.configColorMuiTheme') || 'Theme Color' }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: activeTab === 1 ? 'contained' : 'outlined', onClick: () => setActiveTab(1), sx: {
155
+ fontWeight: 500,
156
+ textTransform: 'none',
157
+ minWidth: 'unset',
158
+ }, children: t('maker.configColorCustomColor') || 'Custom Color' })] }))] }), (0, jsx_runtime_1.jsxs)(material_1.DialogContent, { sx: { width: 600, display: 'flex', flexDirection: 'row', gap: 2, overflowX: 'hidden' }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
159
+ ...previewStyle,
160
+ flex: '0 0 270px',
161
+ borderRadius: 1,
162
+ display: 'flex',
163
+ alignItems: 'center',
164
+ justifyContent: 'center',
165
+ position: 'sticky',
166
+ top: 0,
167
+ }, children: [!state.value && (0, jsx_runtime_1.jsx)(Empty_1.default, { children: t('error.notConfig') }), state.originalMuiKey && isActiveMuiTab && ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", sx: {
168
+ bgcolor: 'rgba(255,255,255,0.7)',
169
+ px: 2,
170
+ py: 1,
171
+ borderRadius: 1,
172
+ color: '#000',
173
+ maxWidth: '90%',
174
+ textAlign: 'center',
175
+ }, children: state.originalMuiKey }))] }, "color-preview"), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { flex: 1 }, children: isActiveMuiTab ? (
176
+ // MUI 主题色面板
177
+ (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { height: HEIGHT }, children: Object.entries(groupedMuiColors).map(([palette, paletteColors]) => ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { pb: 1.5 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", gutterBottom: true, sx: { textTransform: 'capitalize', mb: 0.5, lineHeight: 1 }, children: palette }), (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: paletteColors.map((item) => {
178
+ let selectedColor = '';
179
+ if (state.originalMuiKey === item.colorKey) {
180
+ if (item.colorValue === 'transparent') {
181
+ selectedColor = 'rgba(0,0,0,0.7)';
182
+ }
183
+ else if ((0, tinycolor2_1.default)(item.colorValue).isDark()) {
184
+ selectedColor = 'rgba(255,255,255,0.8)';
185
+ }
186
+ else {
187
+ selectedColor = 'rgba(0,0,0,0.7)';
188
+ }
189
+ }
190
+ return ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: item.colorKey, children: (0, jsx_runtime_1.jsx)(material_1.Box, { onClick: () => {
191
+ state.value = item.colorValue;
192
+ state.originalMuiKey = item.colorKey;
193
+ }, sx: {
194
+ width: 28,
195
+ height: 28,
196
+ bgcolor: item.colorValue,
197
+ border: state.originalMuiKey === item.colorKey
198
+ ? `2px solid ${selectedColor}`
199
+ : '1px solid #ccc',
200
+ borderRadius: 0.5,
201
+ cursor: 'pointer',
202
+ '&:hover': { opacity: 0.8 },
203
+ display: 'flex',
204
+ alignItems: 'center',
205
+ justifyContent: 'center',
206
+ // 透明色时显示棋盘背景
207
+ ...(item.colorValue === 'transparent'
208
+ ? {
209
+ background: 'repeating-conic-gradient(#CCCCCC 0% 25%, #FFFFFF 0% 50%) 50% / 10px 10px',
210
+ }
211
+ : {}),
212
+ }, children: state.originalMuiKey === item.colorKey && ((0, jsx_runtime_1.jsx)("i", { className: "i-mdi:check", style: {
213
+ color: selectedColor,
214
+ fontSize: '1.2rem',
215
+ } })) }) }, item.colorKey));
216
+ }) })] }, palette))) })) : (
217
+ // 自定义颜色选择器
218
+ (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { overflowY: 'auto', overflowX: 'hidden' }, children: (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: (0, jsx_runtime_1.jsx)(material_1.Skeleton, { variant: "rectangular", width: WIDTH, height: HEIGHT }), children: (0, jsx_runtime_1.jsx)(ColorPickerLib, { disableDarkMode: true, width: WIDTH,
219
+ // menu color picker height
220
+ height: WIDTH, value: state.value, onChange: (value) => {
221
+ state.value = value;
222
+ state.originalMuiKey = null;
223
+ }, hidePresets: true, hideAdvancedSliders: true, hideColorGuide: true, hideInputType: true }) }) })) })] }), (0, jsx_runtime_1.jsxs)(material_1.DialogActions, { children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", size: "small", onClick: handleClose, children: t('common.cancel') }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", size: "small", onClick: handleSave, children: t('maker.save') })] })] }));
224
+ });
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useUploader = void 0;
7
+ exports.UploaderButton = UploaderButton;
8
+ exports.UploaderProvider = UploaderProvider;
9
+ exports.getVideoSize = getVideoSize;
10
+ exports.getImageSize = getImageSize;
11
+ const jsx_runtime_1 = require("react/jsx-runtime");
12
+ const react_1 = require("@blocklet/uploader/react");
13
+ const Upload_1 = __importDefault(require("@mui/icons-material/Upload"));
14
+ const material_1 = require("@mui/material");
15
+ exports.useUploader = react_1.useUploaderContext;
16
+ function UploaderButton({ onChange }) {
17
+ const uploaderRef = (0, exports.useUploader)();
18
+ const handleOpen = () => {
19
+ // @ts-ignore
20
+ const uploader = uploaderRef?.current?.getUploader();
21
+ uploader?.open();
22
+ if (onChange) {
23
+ // rewrite default emitter
24
+ uploader.onceUploadSuccess((...args) => {
25
+ onChange(...args);
26
+ });
27
+ }
28
+ };
29
+ return ((0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: handleOpen, children: (0, jsx_runtime_1.jsx)(Upload_1.default, {}) }, "uploader-trigger"));
30
+ }
31
+ function UploaderProvider({ children }) {
32
+ return ((0, jsx_runtime_1.jsx)(react_1.UploaderProvider, { popup: true,
33
+ // @ts-ignore
34
+ coreProps: {
35
+ restrictions: {
36
+ allowedFileTypes: [
37
+ 'image/png',
38
+ 'image/jpeg',
39
+ 'image/gif',
40
+ 'image/webp',
41
+ 'image/svg+xml',
42
+ 'video/mp4',
43
+ 'video/webm',
44
+ 'audio/mpeg',
45
+ ],
46
+ maxNumberOfFiles: 1,
47
+ },
48
+ }, children: children }, "uploader"
49
+ // @ts-ignore
50
+ ));
51
+ }
52
+ exports.default = UploaderProvider;
53
+ function getVideoSize(url) {
54
+ return new Promise((resolve, reject) => {
55
+ const video = document.createElement('video');
56
+ video.src = url;
57
+ video.onloadedmetadata = () => {
58
+ const { videoWidth: naturalWidth, videoHeight: naturalHeight } = video;
59
+ resolve({ naturalWidth, naturalHeight });
60
+ };
61
+ video.onerror = (e) => reject(e);
62
+ });
63
+ }
64
+ function getImageSize(url) {
65
+ return new Promise((resolve, reject) => {
66
+ const img = new Image();
67
+ img.src = url;
68
+ img.onload = () => {
69
+ const { naturalWidth, naturalHeight } = img;
70
+ resolve({ naturalWidth, naturalHeight });
71
+ };
72
+ img.onerror = (e) => reject(e);
73
+ });
74
+ }