quick-start-feature-box 1.0.0

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.
package/dist/index.css ADDED
@@ -0,0 +1,425 @@
1
+ /* src/FeatureBox/index.less */
2
+ .FeatureBox {
3
+ flex: 1 1 auto;
4
+ .FeatureItem {
5
+ width: 100%;
6
+ margin-bottom: 30px;
7
+ border-radius: 12px;
8
+ border-radius: 8px;
9
+ border: 1px solid #ebebeb;
10
+ background-color: #FFFFFF;
11
+ box-shadow: 3px 3px 4px 0px rgba(0, 0, 0, 0.05);
12
+ .header {
13
+ color: #333333;
14
+ display: flex;
15
+ justify-content: space-between;
16
+ align-items: center;
17
+ padding: 20px 28px;
18
+ .headerLeft {
19
+ display: flex;
20
+ align-items: flex-start;
21
+ gap: 12px;
22
+ .iconBox {
23
+ width: 20px;
24
+ height: 20px;
25
+ }
26
+ .title {
27
+ font-size: 15px;
28
+ font-weight: 500;
29
+ :global {
30
+ .iconfont {
31
+ font-size: 13px;
32
+ color: #7f7f7f;
33
+ cursor: pointer;
34
+ margin-left: 16px;
35
+ &:hover {
36
+ color: var(--color-primary);
37
+ }
38
+ }
39
+ }
40
+ }
41
+ .summary {
42
+ margin-top: 12px;
43
+ }
44
+ }
45
+ .btn {
46
+ font-size: 14px;
47
+ border-radius: 5px;
48
+ padding: 5px 18px;
49
+ color: #333333;
50
+ border: 1px solid #d9d9d9;
51
+ transition: all 0.3s ease;
52
+ }
53
+ &:hover {
54
+ text-decoration: none;
55
+ .btn {
56
+ color: var(--color-primary);
57
+ border-color: var(--color-primary);
58
+ }
59
+ }
60
+ }
61
+ .wrapper {
62
+ border-top: 1px solid #ebebeb;
63
+ padding: 20px 28px;
64
+ .contentBox {
65
+ padding: 14px 20px;
66
+ border-radius: 10px;
67
+ display: flex;
68
+ align-items: flex-start;
69
+ background-color: #fafafa;
70
+ border-radius: 10px;
71
+ gap: 8px;
72
+ margin-bottom: 28px;
73
+ :global {
74
+ .iconfont {
75
+ color: #f59a23;
76
+ font-size: 18px;
77
+ }
78
+ }
79
+ .contentRight {
80
+ .title {
81
+ font-weight: 500;
82
+ }
83
+ .content {
84
+ line-height: 1.8em;
85
+ margin-top: 8px;
86
+ :global {
87
+ li::before {
88
+ content: "\2022";
89
+ font-size: 1em;
90
+ font-weight: 300;
91
+ margin-right: 10px;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
97
+ .remark {
98
+ color: #7f7f7f;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ :global {
104
+ .pgant-tooltip-inner {
105
+ min-height: unset;
106
+ }
107
+ .pgant-image-preview-img {
108
+ max-width: 80vw;
109
+ max-height: 80vh;
110
+ }
111
+ }
112
+
113
+ /* src/StepAndQuote/index.less */
114
+ .StepAndQuote {
115
+ display: block;
116
+ position: relative;
117
+ color: #333333;
118
+ .tail {
119
+ position: absolute;
120
+ top: 24px;
121
+ left: 12px;
122
+ height: 100%;
123
+ border-left: 1px solid #e1e1e1;
124
+ }
125
+ .circle {
126
+ position: absolute;
127
+ width: 24px;
128
+ height: 24px;
129
+ left: 0px;
130
+ z-index: 1;
131
+ background-color: #FFFFFF;
132
+ border: 1px solid #e1e1e1;
133
+ border-radius: 100px;
134
+ display: flex;
135
+ align-items: center;
136
+ justify-content: center;
137
+ font-size: 12px;
138
+ }
139
+ .content {
140
+ margin-left: 60px;
141
+ position: relative;
142
+ word-break: break-all;
143
+ }
144
+ &.Step {
145
+ padding-bottom: 32px;
146
+ .title {
147
+ font-size: 15px;
148
+ font-weight: 650;
149
+ margin-bottom: 5px;
150
+ cursor: pointer;
151
+ display: inline-block;
152
+ :global {
153
+ .iconfont {
154
+ font-weight: normal;
155
+ opacity: 0;
156
+ width: 13px;
157
+ height: 13px;
158
+ color: #7f7f7f;
159
+ cursor: pointer;
160
+ padding: 0 8px;
161
+ font-size: 13px;
162
+ transition: opacity 0.3s ease-in-out;
163
+ }
164
+ }
165
+ &:hover {
166
+ :global {
167
+ .iconfont {
168
+ opacity: 100;
169
+ color: var(--color-primary);
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ &.Quote {
176
+ padding-bottom: 56px;
177
+ position: relative;
178
+ .line {
179
+ width: 100%;
180
+ height: 1px;
181
+ margin-top: 56px;
182
+ background-color: #e1e1e1;
183
+ }
184
+ .circle {
185
+ top: 18px;
186
+ }
187
+ .tail {
188
+ display: none;
189
+ }
190
+ .content {
191
+ margin-left: 0;
192
+ }
193
+ .title {
194
+ cursor: pointer;
195
+ padding: 12px;
196
+ border-radius: 5px;
197
+ margin-left: 60px;
198
+ border: 1px solid #e1e1e1;
199
+ display: flex;
200
+ align-items: center;
201
+ justify-content: space-between;
202
+ transition: all 0.3s ease-in-out;
203
+ .QuoteBoxLeft {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 8px;
207
+ .QuoteIcon {
208
+ width: 40px;
209
+ height: auto;
210
+ }
211
+ .QuoteText {
212
+ font-size: 15px;
213
+ font-weight: 650;
214
+ }
215
+ }
216
+ .QuoteBoxRight {
217
+ display: flex;
218
+ align-items: center;
219
+ gap: 12px;
220
+ }
221
+ &:hover {
222
+ box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.1);
223
+ }
224
+ }
225
+ }
226
+ &:last-child {
227
+ .tail {
228
+ display: none;
229
+ }
230
+ }
231
+ }
232
+
233
+ /* src/Tab/index.less */
234
+ .Tab {
235
+ display: flex;
236
+ gap: 16px;
237
+ padding: 10px 0 24px 0;
238
+ border-bottom: 1px solid #ebebeb;
239
+ .tabItem {
240
+ padding: 16px 28px;
241
+ border: 1px solid #e1e1e1;
242
+ border-radius: 5px;
243
+ transition: all 0.3s ease-in-out;
244
+ cursor: pointer;
245
+ display: flex;
246
+ flex-direction: column;
247
+ align-items: center;
248
+ justify-content: center;
249
+ gap: 5px;
250
+ .tabIcon {
251
+ width: 28px;
252
+ height: 28px;
253
+ color: #959595;
254
+ fill: currentColor;
255
+ transition: all 0.3s ease-in-out;
256
+ }
257
+ &:hover {
258
+ color: var(--color-primary, #fb9332);
259
+ .tabIcon {
260
+ color: var(--color-primary, #fb9332);
261
+ }
262
+ }
263
+ &.active {
264
+ color: var(--color-primary, #fb9332);
265
+ border-color: var(--color-primary, #fb9332);
266
+ .tabIcon {
267
+ color: var(--color-primary, #fb9332);
268
+ }
269
+ }
270
+ &.noFirstTabsItem {
271
+ padding: 10px 22px;
272
+ }
273
+ &.hasIcon {
274
+ padding: 10px 28px;
275
+ }
276
+ }
277
+ &.noFirstTab {
278
+ padding: 24px 0 24px 0;
279
+ }
280
+ &.isInternalChanged {
281
+ margin-bottom: 24px;
282
+ }
283
+ }
284
+ .Tab + .Tab {
285
+ margin-top: -24px;
286
+ }
287
+
288
+ /* src/Article/index.less */
289
+ .Article {
290
+ a {
291
+ text-decoration: underline;
292
+ text-decoration-color: var(--color-primary, #FB9332);
293
+ }
294
+ img {
295
+ border: 1px solid #eeeeee;
296
+ }
297
+ b {
298
+ color: #333333;
299
+ }
300
+ :first-child {
301
+ margin-top: 0 !important;
302
+ }
303
+ :global {
304
+ .title {
305
+ font-size: 14px;
306
+ margin-top: 16px;
307
+ margin-bottom: 8px;
308
+ font-weight: 650;
309
+ }
310
+ .desc {
311
+ color: #999999;
312
+ margin-top: var(--desc-margin-top, 16px);
313
+ margin-bottom: 8px;
314
+ }
315
+ .title + .desc {
316
+ --desc-margin-top: -6px;
317
+ }
318
+ .img-container {
319
+ position: relative;
320
+ cursor: pointer;
321
+ img {
322
+ width: 100%;
323
+ }
324
+ .iconfont {
325
+ display: none;
326
+ transition: all 0.3s ease;
327
+ opacity: 0;
328
+ position: absolute;
329
+ top: 5px;
330
+ right: 5px;
331
+ background-color: rgba(128, 128, 128, 0.92);
332
+ color: #ffffff;
333
+ border-radius: 4px;
334
+ padding: 2px 4px;
335
+ font-size: 16px;
336
+ }
337
+ &:hover {
338
+ .iconfont {
339
+ display: block;
340
+ opacity: 1;
341
+ }
342
+ }
343
+ }
344
+ .img-container + .img-container {
345
+ margin-top: 10px;
346
+ }
347
+ li::before {
348
+ content: "\2022";
349
+ font-size: 1em;
350
+ font-weight: 300;
351
+ margin-right: 8px;
352
+ }
353
+ }
354
+ }
355
+
356
+ /* src/Dictionary/index.less */
357
+ .Dictionary {
358
+ display: flex;
359
+ margin-top: 10px;
360
+ gap: 20px;
361
+ .item {
362
+ display: flex;
363
+ flex-direction: column;
364
+ align-items: center;
365
+ justify-content: center;
366
+ gap: 4px;
367
+ padding: 12px 20px 8px;
368
+ border: 1px solid #e1e1e1;
369
+ border-radius: 5px;
370
+ cursor: pointer;
371
+ text-decoration: none;
372
+ .dicIcon {
373
+ width: 16px;
374
+ height: 16px;
375
+ }
376
+ .title {
377
+ color: #333333;
378
+ }
379
+ &:hover {
380
+ border-color: var(--color-primary, #fb9332);
381
+ }
382
+ }
383
+ }
384
+
385
+ /* src/HelpModal/index.less */
386
+ .HelpModal {
387
+ top: 0;
388
+ bottom: 0;
389
+ padding: 40px;
390
+ height: 100vh;
391
+ :global {
392
+ .pgant-modal-content {
393
+ width: 100%;
394
+ height: 100%;
395
+ padding: 0;
396
+ .pgant-modal-body {
397
+ padding: 0;
398
+ height: 100%;
399
+ }
400
+ }
401
+ }
402
+ .HelpModalSkeleton {
403
+ padding: 40px;
404
+ width: 100%;
405
+ height: 100%;
406
+ box-sizing: border-box;
407
+ }
408
+ .HelpModalIframe {
409
+ width: 100%;
410
+ height: 100%;
411
+ border: none;
412
+ }
413
+ }
414
+
415
+ /* src/Extra/index.less */
416
+ .Extra {
417
+ position: absolute;
418
+ right: 0;
419
+ top: 0;
420
+ display: flex;
421
+ gap: 12px;
422
+ .ExtraButton {
423
+ border-radius: 3px;
424
+ }
425
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 国际化类型定义
3
+ */
4
+ type I18N = {
5
+ /**
6
+ * - 示例国际化方法
7
+ */
8
+ abc_name: (values: any) => any;
9
+ };
10
+ /**
11
+ * FeatureBox组件props类型定义
12
+ */
13
+ type FeatureBoxProps = {
14
+ /**
15
+ * - 国际化对象
16
+ */
17
+ i18n: I18N;
18
+ /**
19
+ * - 功能数据
20
+ */
21
+ data: any;
22
+ /**
23
+ * - 内容数据
24
+ */
25
+ content: any;
26
+ /**
27
+ * - 模块名称
28
+ */
29
+ module: string;
30
+ /**
31
+ * - 功能名称
32
+ */
33
+ feature: string;
34
+ /**
35
+ * - 设置功能方法
36
+ */
37
+ setFeature: Function;
38
+ /**
39
+ * - 链接列表
40
+ */
41
+ linkList: any[];
42
+ /**
43
+ * - 引用列表
44
+ */
45
+ quoteList: any[];
46
+ };
47
+ /**
48
+ * 国际化类型定义
49
+ * @typedef {Object} I18N
50
+ * @property {(values: any) => import('react').ReactNode} abc_name - 示例国际化方法
51
+ */
52
+ /**
53
+ * FeatureBox组件props类型定义
54
+ * @typedef {Object} FeatureBoxProps
55
+ * @property {I18N} i18n - 国际化对象
56
+ * @property {any} data - 功能数据
57
+ * @property {any} content - 内容数据
58
+ * @property {string} module - 模块名称
59
+ * @property {string} feature - 功能名称
60
+ * @property {Function} setFeature - 设置功能方法
61
+ * @property {Array} linkList - 链接列表
62
+ * @property {Array} quoteList - 引用列表
63
+ */
64
+ /**
65
+ * FeatureBox组件
66
+ * @param {FeatureBoxProps} props - 组件props
67
+ * @returns {JSX.Element} - 返回React元素
68
+ */
69
+ declare function FeatureBox(props: FeatureBoxProps): JSX.Element;
70
+
71
+ export { FeatureBox };
package/dist/index.js ADDED
@@ -0,0 +1,523 @@
1
+ // src/FeatureBox/index.js
2
+ import React8, { useEffect, useMemo as useMemo4, useState as useState5 } from "react";
3
+
4
+ // src/FeatureBox/index.less
5
+ var FeatureBox_default = {};
6
+
7
+ // src/FeatureBox/index.js
8
+ import { Tooltip as Tooltip2, message as message2, Image } from "antd";
9
+
10
+ // src/FeatureContentBox/index.js
11
+ import React7, { useMemo as useMemo3, useState as useState4, useContext } from "react";
12
+
13
+ // src/StepAndQuote/index.js
14
+ import React6, { useMemo as useMemo2 } from "react";
15
+
16
+ // src/StepAndQuote/index.less
17
+ var StepAndQuote_default = {};
18
+
19
+ // src/Tab/index.js
20
+ import React from "react";
21
+
22
+ // src/Tab/index.less
23
+ var Tab_default = {};
24
+
25
+ // src/Tab/index.js
26
+ import classNames from "classnames";
27
+ function isPrefixArray(prefixArray, mainArray) {
28
+ return prefixArray.every((element, index) => element === mainArray[index]);
29
+ }
30
+ var Tab = (props) => {
31
+ const {
32
+ data,
33
+ idx,
34
+ stepChildrenLength,
35
+ tabNum,
36
+ currentLinkList,
37
+ setCurrentLinkList
38
+ } = props;
39
+ const getActive = (linkList, index) => {
40
+ if (linkList.length <= currentLinkList.length) {
41
+ return isPrefixArray(linkList, currentLinkList);
42
+ }
43
+ return index == 0;
44
+ };
45
+ return /* @__PURE__ */ React.createElement("div", { className: classNames(Tab_default.Tab, {
46
+ [Tab_default.noFirstTab]: tabNum != 1,
47
+ [Tab_default.isInternalChanged]: idx < stepChildrenLength - 1
48
+ }) }, (data?.children ?? []).map((item, index) => {
49
+ if (item.type !== "tabItem") {
50
+ return null;
51
+ }
52
+ return /* @__PURE__ */ React.createElement(
53
+ "div",
54
+ {
55
+ key: item.id,
56
+ className: classNames(Tab_default.tabItem, {
57
+ [Tab_default.active]: getActive(item.linkList, index),
58
+ [Tab_default.noFirstTabsItem]: tabNum != 1,
59
+ [Tab_default.hasIcon]: item.icon
60
+ }),
61
+ onClick: () => {
62
+ setCurrentLinkList(item.linkList);
63
+ }
64
+ },
65
+ item.icon && /* @__PURE__ */ React.createElement("div", { className: Tab_default.tabIcon, dangerouslySetInnerHTML: { __html: item.icon } }),
66
+ item.text
67
+ );
68
+ }));
69
+ };
70
+ var Tab_default2 = Tab;
71
+
72
+ // src/Article/index.js
73
+ import React2, { useMemo } from "react";
74
+
75
+ // src/Article/index.less
76
+ var Article_default = {};
77
+
78
+ // src/Article/index.js
79
+ var Article = (props) => {
80
+ const {
81
+ data
82
+ } = props;
83
+ const modifiedText = useMemo(() => {
84
+ return data?.text?.replace(/<img([^>]+)>/g, (match) => {
85
+ return `<div class="img-container">${match}<i class="iconfont img-preview">&#x11bc7;</i></div>`;
86
+ }) ?? "";
87
+ }, [data]);
88
+ return /* @__PURE__ */ React2.createElement("div", { className: Article_default.Article, dangerouslySetInnerHTML: { __html: modifiedText } });
89
+ };
90
+ var Article_default2 = Article;
91
+
92
+ // src/Dictionary/index.js
93
+ import React4, { useState as useState2 } from "react";
94
+
95
+ // src/Dictionary/index.less
96
+ var Dictionary_default = {};
97
+
98
+ // src/HelpModal/index.js
99
+ import React3, { useState } from "react";
100
+
101
+ // src/HelpModal/index.less
102
+ var HelpModal_default = {};
103
+
104
+ // src/HelpModal/index.js
105
+ import { Modal } from "antd";
106
+ var HelpModal = (props) => {
107
+ const {
108
+ visible,
109
+ setVisible,
110
+ link
111
+ } = props;
112
+ const [loading, setLoading] = useState(true);
113
+ return /* @__PURE__ */ React3.createElement(
114
+ Modal,
115
+ {
116
+ className: HelpModal_default.HelpModal,
117
+ open: visible,
118
+ width: "90vw",
119
+ onCancel: () => setVisible(false),
120
+ destroyOnClose: true,
121
+ footer: null
122
+ },
123
+ /* @__PURE__ */ React3.createElement(
124
+ "iframe",
125
+ {
126
+ className: HelpModal_default.HelpModalIframe,
127
+ style: { display: loading ? "none" : "block" },
128
+ src: link,
129
+ onLoad: () => setLoading(false)
130
+ }
131
+ )
132
+ );
133
+ };
134
+ var HelpModal_default2 = HelpModal;
135
+
136
+ // src/Dictionary/index.js
137
+ var Dictionary = (props) => {
138
+ const {
139
+ data
140
+ } = props;
141
+ const [visible, setVisible] = useState2(false);
142
+ const [link, setLink] = useState2("");
143
+ const handleClick = (item) => {
144
+ setLink(item.link);
145
+ setVisible(true);
146
+ };
147
+ return /* @__PURE__ */ React4.createElement("div", { className: Dictionary_default.Dictionary }, (data?.children ?? []).map((item) => {
148
+ return item.type === "modal" ? /* @__PURE__ */ React4.createElement("div", { key: item.id, className: Dictionary_default.item, onClick: () => handleClick(item) }, item.icon && /* @__PURE__ */ React4.createElement("div", { className: Dictionary_default.dicIcon, dangerouslySetInnerHTML: { __html: item.icon } }), /* @__PURE__ */ React4.createElement("div", { className: Dictionary_default.title }, item.text)) : /* @__PURE__ */ React4.createElement("a", { className: Dictionary_default.item, href: item.link }, item.icon && /* @__PURE__ */ React4.createElement("div", { className: Dictionary_default.dicIcon, dangerouslySetInnerHTML: { __html: item.icon } }), /* @__PURE__ */ React4.createElement("div", { className: Dictionary_default.title }, item.text));
149
+ }), /* @__PURE__ */ React4.createElement(HelpModal_default2, { visible, setVisible, link }));
150
+ };
151
+ var Dictionary_default2 = Dictionary;
152
+
153
+ // src/Extra/index.js
154
+ import React5, { useState as useState3 } from "react";
155
+
156
+ // src/Extra/index.less
157
+ var Extra_default = {};
158
+
159
+ // src/Extra/index.js
160
+ import { Button } from "antd";
161
+ var Extra = (props) => {
162
+ const {
163
+ data
164
+ } = props;
165
+ const [visible, setVisible] = useState3(false);
166
+ const [currentLink, setCurrentLink] = useState3([]);
167
+ const handleClick = (item) => {
168
+ setCurrentLink(item.link);
169
+ setVisible(true);
170
+ };
171
+ return /* @__PURE__ */ React5.createElement("div", { className: Extra_default.Extra }, (data?.children ?? []).map((item, index) => {
172
+ return item.type === "link" ? /* @__PURE__ */ React5.createElement(Button, { className: Extra_default.ExtraButton, key: index, type: "primary", href: item.link }, item.text) : /* @__PURE__ */ React5.createElement(Button, { className: Extra_default.ExtraButton, key: index, onClick: () => handleClick(item) }, item.text);
173
+ }), /* @__PURE__ */ React5.createElement(
174
+ HelpModal_default2,
175
+ {
176
+ visible,
177
+ setVisible,
178
+ link: currentLink
179
+ }
180
+ ));
181
+ };
182
+ var Extra_default2 = Extra;
183
+
184
+ // src/StepAndQuote/index.js
185
+ import classNames2 from "classnames";
186
+ import { Tooltip, message } from "antd";
187
+ var STEP_CHILD_COMPONENTS = {
188
+ tab: Tab_default2,
189
+ article: Article_default2,
190
+ dictionary: Dictionary_default2,
191
+ extra: Extra_default2,
192
+ default: ({ data }) => /* @__PURE__ */ React6.createElement("div", { style: { color: "red", fontSize: 20, textAlign: "center" } }, "uniqueName: ", data.uniqueName, "\uFF0Ctype: ", data.type, "\u4E0D\u7B26\u5408\u89C4\u5219")
193
+ };
194
+ var Step = (props) => {
195
+ const {
196
+ data,
197
+ module,
198
+ feature,
199
+ currentLinkList,
200
+ currentQuoteList,
201
+ index,
202
+ ...rest
203
+ } = props;
204
+ const copyLink = () => {
205
+ const linkListStr = (currentLinkList || []).join("-");
206
+ const linkListPath = linkListStr != "" ? `&linkList=${linkListStr}` : "";
207
+ const currentQuoteListStr = (currentQuoteList || []).join("-");
208
+ const currentQuoteListPath = currentQuoteListStr != "" ? `&quoteList=${currentQuoteListStr}` : "";
209
+ const copyText = `${window.location.origin}/quickstart/detail?module=${module}&feature=${feature}${linkListPath}${currentQuoteListPath}#step-${index + 1}`;
210
+ if (navigator.clipboard && navigator.clipboard.writeText) {
211
+ navigator.clipboard.writeText(copyText);
212
+ message.success(i18n.rebate_copy_share_success);
213
+ } else {
214
+ fallbackCopyTextToClipboard(copyText);
215
+ }
216
+ };
217
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(Tooltip, { title: i18n.rebate_copy_share }, /* @__PURE__ */ React6.createElement("span", { className: StepAndQuote_default.title, onClick: copyLink }, data.text, /* @__PURE__ */ React6.createElement("i", { className: "iconfont" }, "\uE63E"))), (data?.children ?? []).map((item, idx) => {
218
+ const Comp = STEP_CHILD_COMPONENTS[item?.type] || STEP_CHILD_COMPONENTS.default;
219
+ const tabNum = (data?.children ?? []).slice(0, idx + 1).filter((child) => child?.type === "tab").length;
220
+ return /* @__PURE__ */ React6.createElement(
221
+ Comp,
222
+ {
223
+ key: idx,
224
+ idx,
225
+ stepChildrenLength: data?.children?.length ?? 0,
226
+ data: item,
227
+ tabNum,
228
+ currentLinkList,
229
+ ...rest
230
+ }
231
+ );
232
+ }));
233
+ };
234
+ var Quote = (props) => {
235
+ const {
236
+ data,
237
+ currentQuoteList,
238
+ setCurrentQuoteList
239
+ } = props;
240
+ const handleClick = (quoteID) => {
241
+ if (currentQuoteList.includes(quoteID)) {
242
+ setCurrentQuoteList(currentQuoteList.filter((id) => id !== quoteID));
243
+ } else {
244
+ setCurrentQuoteList([...currentQuoteList, quoteID]);
245
+ }
246
+ };
247
+ const isOpen = useMemo2(() => currentQuoteList.includes(data.id), [currentQuoteList, data.id]);
248
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.title, onClick: () => handleClick(data.id) }, /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.QuoteBoxLeft }, (() => {
249
+ if (!data.icon) {
250
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null);
251
+ }
252
+ if (data.icon.startsWith("<svg")) {
253
+ return /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.QuoteIcon, dangerouslySetInnerHTML: { __html: data.icon } });
254
+ } else {
255
+ return /* @__PURE__ */ React6.createElement("img", { className: StepAndQuote_default.QuoteIcon, src: data.icon, alt: "quote" });
256
+ }
257
+ })(), /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.QuoteText }, data.text)), /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.QuoteBoxRight }, /* @__PURE__ */ React6.createElement("div", null, isOpen ? i18n.order_close_product : i18n.common_view_short), /* @__PURE__ */ React6.createElement("i", { className: "iconfont", style: { color: "#888888", ...isOpen ? { transform: "rotate(180deg)" } : {} } }, "\uE611"))), isOpen && /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.line }));
258
+ };
259
+ var StepAndQuote = (props) => {
260
+ const {
261
+ data,
262
+ index,
263
+ ...rest
264
+ } = props;
265
+ return /* @__PURE__ */ React6.createElement("div", { id: `step-${index + 1}`, className: classNames2(StepAndQuote_default.StepAndQuote, data.type === "step" ? StepAndQuote_default.Step : StepAndQuote_default.Quote) }, /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.tail }), /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.circle }, index + 1), /* @__PURE__ */ React6.createElement("div", { className: StepAndQuote_default.content }, data.type === "step" ? /* @__PURE__ */ React6.createElement(Step, { data, index, ...rest }) : /* @__PURE__ */ React6.createElement(Quote, { data, ...rest })));
266
+ };
267
+ var StepAndQuote_default2 = StepAndQuote;
268
+
269
+ // src/FeatureContentBox/index.js
270
+ function processContentData(node, data, link = []) {
271
+ if (!Array.isArray(node)) return;
272
+ return node.map((item) => {
273
+ const tempLink = [...link];
274
+ item = {
275
+ ...item,
276
+ ...data[item.u]
277
+ };
278
+ if (["tab", "tabItem"].includes(item.type)) {
279
+ tempLink.push(item.id);
280
+ }
281
+ if (item.c) {
282
+ item.children = processContentData(item.c, data, tempLink);
283
+ }
284
+ return {
285
+ ...item,
286
+ linkList: tempLink
287
+ };
288
+ });
289
+ }
290
+ function dealStepWithTab(stepNode, childrenNode, newChildren, linkList, quoteList, result) {
291
+ const isExternalChanged = childrenNode.some((item) => item.type === "step" || item.type === "quote");
292
+ if (isExternalChanged) {
293
+ childrenNode.forEach((item) => {
294
+ if (item.type != "step" && item.type != "quote") {
295
+ newChildren.push(item);
296
+ }
297
+ });
298
+ result.push({
299
+ ...stepNode,
300
+ children: newChildren
301
+ });
302
+ getRealRenderData(childrenNode, linkList, quoteList, result);
303
+ } else {
304
+ const hasTab = childrenNode.some((item) => item.type === "tab");
305
+ if (hasTab) {
306
+ childrenNode.some((item) => {
307
+ newChildren.push(item);
308
+ if (item.type != "tab") {
309
+ return false;
310
+ }
311
+ const tabItemID = linkList.findIndex((id) => id == item.id) > -1 ? linkList[linkList.findIndex((id) => id == item.id) + 1] : item.children?.[0]?.id ?? -1;
312
+ const tabItem = item.children.find((child) => child.id == tabItemID);
313
+ dealStepWithTab(stepNode, tabItem?.children || [], newChildren, linkList, quoteList, result);
314
+ return true;
315
+ });
316
+ } else {
317
+ result.push({
318
+ ...stepNode,
319
+ children: [...newChildren, ...childrenNode]
320
+ });
321
+ }
322
+ }
323
+ }
324
+ function getRealRenderData(node, linkList, quoteList, result = []) {
325
+ if (!Array.isArray(node)) return;
326
+ (node || []).forEach((item) => {
327
+ if (item.type === "step") {
328
+ const { children } = item;
329
+ dealStepWithTab(item, children, [], linkList, quoteList, result);
330
+ } else if (item.type === "quote") {
331
+ result.push(item);
332
+ if (quoteList.includes(item.id)) {
333
+ getRealRenderData(item.children, linkList, quoteList, result);
334
+ }
335
+ }
336
+ });
337
+ return result;
338
+ }
339
+ var FeatureContentBox = (props) => {
340
+ const {
341
+ structure,
342
+ linkList,
343
+ quoteList,
344
+ content,
345
+ ...rest
346
+ } = props;
347
+ const [currentLinkList, setCurrentLinkList] = useState4(linkList);
348
+ const [currentQuoteList, setCurrentQuoteList] = useState4(quoteList);
349
+ const completeData = useMemo3(() => {
350
+ return processContentData(structure, content);
351
+ }, [structure]);
352
+ const realRenderData = useMemo3(() => {
353
+ return getRealRenderData(completeData, currentLinkList, currentQuoteList);
354
+ }, [completeData, currentLinkList, currentQuoteList]);
355
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, realRenderData.map((item, index) => {
356
+ return /* @__PURE__ */ React7.createElement(
357
+ StepAndQuote_default2,
358
+ {
359
+ key: item.id,
360
+ data: item,
361
+ index,
362
+ currentLinkList,
363
+ setCurrentLinkList,
364
+ currentQuoteList,
365
+ setCurrentQuoteList,
366
+ ...rest
367
+ }
368
+ );
369
+ }));
370
+ };
371
+ var FeatureContentBox_default = React7.memo(FeatureContentBox, (prevProps, nextProps) => {
372
+ return prevProps.structure === nextProps.structure;
373
+ });
374
+
375
+ // src/FeatureBox/index.js
376
+ import { Link, useLocation } from "react-router-dom";
377
+ function fallbackCopyTextToClipboard(text) {
378
+ const textarea = document.createElement("textarea");
379
+ textarea.value = text;
380
+ document.body.appendChild(textarea);
381
+ textarea.select();
382
+ try {
383
+ document.execCommand("copy");
384
+ message2.success(i18n.rebate_copy_share_success);
385
+ } catch (err) {
386
+ message2.error(i18n.rebate_copy_share_failed);
387
+ } finally {
388
+ document.body.removeChild(textarea);
389
+ }
390
+ }
391
+ var FeatureItem = (props) => {
392
+ const {
393
+ feature,
394
+ data,
395
+ content,
396
+ linkList,
397
+ quoteList,
398
+ module
399
+ } = props;
400
+ const active = useMemo4(() => {
401
+ return feature === data.alias;
402
+ }, [feature, data]);
403
+ const location = useLocation();
404
+ const [imgSrc, setImgSrc] = useState5("");
405
+ const [imgVisible, setImgVisible] = useState5(false);
406
+ useEffect(() => {
407
+ const hash = location.hash;
408
+ setTimeout(() => {
409
+ let offsetPosition = 0;
410
+ if (hash) {
411
+ const element = document.querySelector(hash);
412
+ const topOffset = 50;
413
+ const elementPosition = element.getBoundingClientRect().top + window.scrollY;
414
+ offsetPosition = elementPosition - topOffset;
415
+ }
416
+ window.scrollTo({
417
+ top: offsetPosition
418
+ });
419
+ }, 0);
420
+ }, [location]);
421
+ const copyLink = (e) => {
422
+ e.preventDefault();
423
+ e.stopPropagation();
424
+ const copyText = `${window.location.origin}/quickstart/detail?module=${module}&feature=${data.alias}#${data.alias}`;
425
+ if (navigator.clipboard && navigator.clipboard.writeText) {
426
+ navigator.clipboard.writeText(copyText);
427
+ message2.success(i18n.rebate_copy_share_success);
428
+ } else {
429
+ fallbackCopyTextToClipboard(copyText);
430
+ }
431
+ };
432
+ const imgClick = (e) => {
433
+ let target = e.target;
434
+ let imgElement = null;
435
+ if (target.tagName === "IMG") {
436
+ imgElement = target;
437
+ } else if (target.className === "iconfont img-preview") {
438
+ imgElement = target.parentElement.querySelector("img");
439
+ }
440
+ if (imgElement) {
441
+ setImgSrc(imgElement.src);
442
+ setImgVisible(true);
443
+ }
444
+ };
445
+ return /* @__PURE__ */ React8.createElement("div", { id: data.alias, className: FeatureBox_default.FeatureItem }, /* @__PURE__ */ React8.createElement(
446
+ Link,
447
+ {
448
+ className: FeatureBox_default.header,
449
+ to: {
450
+ pathname: "/quickstart/detail",
451
+ search: new URLSearchParams({ module, ...data.alias == feature ? {} : { feature: data.alias } }).toString(),
452
+ ...data.alias == feature ? {} : { hash: data.alias }
453
+ }
454
+ },
455
+ /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.headerLeft }, data.icon && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.iconBox, dangerouslySetInnerHTML: { __html: data.icon } }), /* @__PURE__ */ React8.createElement("div", null, /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.title }, data.name, /* @__PURE__ */ React8.createElement(Tooltip2, { title: i18n.rebate_copy_share }, /* @__PURE__ */ React8.createElement("i", { className: "iconfont", onClick: copyLink }, "\uE63E"))), !active && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.summary }, data.summary))),
456
+ /* @__PURE__ */ React8.createElement(
457
+ "div",
458
+ {
459
+ className: FeatureBox_default.btn
460
+ },
461
+ active ? i18n.order_close_product : i18n.read
462
+ )
463
+ ), active && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.wrapper, onClick: imgClick }, data.content && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.contentBox }, /* @__PURE__ */ React8.createElement("i", { className: "iconfont" }, "\uE649"), /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.contentRight }, /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.title }, i18n.function_purpose), /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.content, dangerouslySetInnerHTML: { __html: data.content } }))), data.remark && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.remark }, data.remark), /* @__PURE__ */ React8.createElement(
464
+ Image,
465
+ {
466
+ style: { display: "none" },
467
+ src: imgSrc,
468
+ preview: {
469
+ visible: imgVisible,
470
+ src: imgSrc,
471
+ onVisibleChange: (value) => {
472
+ setImgVisible(value);
473
+ }
474
+ }
475
+ }
476
+ ), /* @__PURE__ */ React8.createElement(
477
+ FeatureContentBox_default,
478
+ {
479
+ structure: data.contentRelative,
480
+ content,
481
+ module,
482
+ feature,
483
+ linkList: active ? linkList : [],
484
+ quoteList: active ? quoteList : []
485
+ }
486
+ )));
487
+ };
488
+ var FeatureBox = (props) => {
489
+ const {
490
+ data,
491
+ content,
492
+ module,
493
+ feature,
494
+ setFeature,
495
+ linkList,
496
+ quoteList,
497
+ i18n: i18n2
498
+ } = props;
499
+ const featureData = useMemo4(() => {
500
+ let tempModule = module;
501
+ if (!tempModule) {
502
+ tempModule = data?.[0]?.alias ?? "platform_post";
503
+ }
504
+ return data.find((item) => item.alias === tempModule);
505
+ }, [data, module]);
506
+ return featureData && /* @__PURE__ */ React8.createElement("div", { className: FeatureBox_default.FeatureBox, style: { marginBottom: feature ? 0 : 200 } }, i18n2["abc_name"](123), (featureData.features || []).map((item) => /* @__PURE__ */ React8.createElement(
507
+ FeatureItem,
508
+ {
509
+ key: `${module}-${item.alias}`,
510
+ feature,
511
+ data: item,
512
+ content,
513
+ setFeature,
514
+ linkList,
515
+ quoteList,
516
+ module
517
+ }
518
+ )));
519
+ };
520
+ var FeatureBox_default2 = FeatureBox;
521
+ export {
522
+ FeatureBox_default2 as FeatureBox
523
+ };
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "quick-start-feature-box",
3
+ "version": "1.0.0",
4
+ "keywords": ["react", "components"],
5
+ "author": "",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "module": "dist/index.js",
9
+ "files": [
10
+ "dist/**"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsup"
14
+ },
15
+ "peerDependencies": {
16
+ "classnames": "^2.3.1 || ^2.5.1",
17
+ "react": "^18.0.0 || ^18.2.0",
18
+ "react-dom": "^18.0.0 || ^18.2.0",
19
+ "react-router": "^6.3.0 || ^6.23.0",
20
+ "react-router-dom": "^6.3.0 || ^6.23.0"
21
+ },
22
+ "devDependencies": {
23
+ "less": "^4.2.2",
24
+ "less-loader": "^12.2.0",
25
+ "tsup": "^8.3.5",
26
+ "typescript": "^5.0.0"
27
+ },
28
+ "exports": {
29
+ "./package.json": "./package.json",
30
+ ".": {
31
+ "import": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ }
35
+ }
36
+ }
37
+ }