@blocklet/launcher-layout 2.3.20 → 2.3.22

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.
@@ -1,114 +0,0 @@
1
- import { useState, useEffect, useRef } from 'react';
2
- import styled from '@emotion/styled';
3
- import PropTypes from 'prop-types';
4
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
- function CompactLayout({
6
- children,
7
- bottom,
8
- onBottomFix
9
- }) {
10
- const mainCon = useRef(null);
11
- const childsCon = useRef(null);
12
- const compactCon = useRef(null);
13
- const isFix = useRef(null);
14
- const [scrollMode, setScrollMode] = useState(false);
15
- useEffect(() => {
16
- let inTimer;
17
- const fixSize = () => {
18
- if (inTimer) {
19
- return;
20
- }
21
- inTimer = setTimeout(() => {
22
- if (childsCon.current) {
23
- if (childsCon.current.scrollHeight > mainCon.current.clientHeight - compactCon.current.clientHeight) {
24
- if (isFix.current !== 'fix') {
25
- onBottomFix('fix');
26
- isFix.current = 'fix';
27
- }
28
- setScrollMode(true);
29
- } else {
30
- if (isFix.current !== 'scroll') {
31
- onBottomFix('scroll');
32
- isFix.current = 'scroll';
33
- }
34
- setScrollMode(false);
35
- }
36
- }
37
- inTimer = null;
38
- }, 50);
39
- };
40
- let resizeObs;
41
- if (window.ResizeObserver) {
42
- resizeObs = new ResizeObserver(fixSize);
43
- } else {
44
- window.addEventListener('resize', fixSize);
45
- }
46
- resizeObs.observe(mainCon.current);
47
- resizeObs.observe(childsCon.current);
48
- return () => {
49
- if (resizeObs) {
50
- resizeObs.disconnect();
51
- } else {
52
- window.removeEventListener('resize', fixSize);
53
- }
54
- if (inTimer) {
55
- clearTimeout(inTimer);
56
- }
57
- };
58
- }, [onBottomFix]);
59
- return /*#__PURE__*/_jsxs(Container, {
60
- ref: mainCon,
61
- className: `${scrollMode ? 'scroll-mode' : ''}`,
62
- children: [/*#__PURE__*/_jsx("div", {
63
- className: "compact-context",
64
- ref: childsCon,
65
- children: children
66
- }), /*#__PURE__*/_jsx("div", {
67
- className: "fix-container",
68
- ref: compactCon,
69
- children: bottom
70
- })]
71
- });
72
- }
73
- const Container = styled.div`
74
- display: flex;
75
- flex-direction: column;
76
- width: 100%;
77
- height: 100%;
78
- animation: fadein ease 0.5s;
79
-
80
- .fix-container {
81
- margin-top: auto;
82
- width: 100%;
83
- }
84
-
85
- &.scroll-mode {
86
- .compact-context {
87
- flex: 1;
88
- overflow-y: auto;
89
- }
90
- .fix-container {
91
- margin-top: auto;
92
- flex-shrink: 0;
93
- }
94
- }
95
-
96
- @keyframes fadein {
97
- 0% {
98
- opacity: 0;
99
- }
100
- 100% {
101
- opacity: 1;
102
- }
103
- }
104
- `;
105
- CompactLayout.propTypes = {
106
- children: PropTypes.any,
107
- bottom: PropTypes.element.isRequired,
108
- onBottomFix: PropTypes.func
109
- };
110
- CompactLayout.defaultProps = {
111
- children: [],
112
- onBottomFix: () => {}
113
- };
114
- export default CompactLayout;
package/es/content.js DELETED
@@ -1,72 +0,0 @@
1
- import styled from '@emotion/styled';
2
- import PropTypes from 'prop-types';
3
- import { jsx as _jsx } from "react/jsx-runtime";
4
- function Content({
5
- children
6
- }) {
7
- return /*#__PURE__*/_jsx(Container, {
8
- children: children
9
- });
10
- }
11
- Content.propTypes = {
12
- children: PropTypes.any.isRequired
13
- };
14
- export default Content;
15
- const Container = styled.div`
16
- display: flex;
17
- flex-direction: column;
18
- height: 100%;
19
- width: 100%;
20
-
21
- .center {
22
- display: flex;
23
- justify-content: center;
24
- }
25
-
26
- .page-title {
27
- text-align: center;
28
- }
29
-
30
- .toolbar {
31
- display: flex;
32
- justify-content: space-between;
33
- align-items: center;
34
-
35
- .toolbar_title {
36
- color: ${props => props.theme.palette.grey['900']};
37
- font-size: 16px;
38
- }
39
- }
40
-
41
- .page-footer {
42
- display: flex;
43
- justify-content: center;
44
- align-items: center;
45
-
46
- width: 100%;
47
- background: ${props => props.theme.palette.common.white};
48
-
49
- .create-button {
50
- margin-right: 32px;
51
- }
52
-
53
- & > button,
54
- .button {
55
- margin: 0 8px;
56
- }
57
-
58
- ${props => props.theme.breakpoints.up('md')} {
59
- padding: 24px;
60
- & > button,
61
- .button {
62
- margin: 0 12px;
63
- min-width: 200px;
64
- }
65
- }
66
-
67
- ${props => props.theme.breakpoints.down('md')} {
68
- margin-top: auto;
69
- padding: 16px;
70
- }
71
- }
72
- `;
@@ -1,137 +0,0 @@
1
- import { createContext, useContext, useEffect, useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { jsx as _jsx } from "react/jsx-runtime";
4
- const StepContext = /*#__PURE__*/createContext();
5
- const {
6
- Provider
7
- } = StepContext;
8
- const matchPath = (path, exact, currentPathname = window.location.pathname.replace(/\/$/, '/')) => {
9
- if (!path) {
10
- return false;
11
- }
12
- if (exact) {
13
- return path === currentPathname;
14
- }
15
- return new RegExp(path).test(currentPathname);
16
- };
17
- function StepProvider({
18
- children,
19
- steps,
20
- mode
21
- }) {
22
- const [activeStepKey, setActiveStepKey] = useState('');
23
- if (!activeStepKey && steps.length) {
24
- setActiveStepKey(steps[0].key);
25
- }
26
- const flatSteps = steps.map(item => {
27
- if (item.children) {
28
- return [{
29
- key: item.key,
30
- hasChild: true
31
- }, item.children.map(childItem => {
32
- return {
33
- parentKey: item.key,
34
- key: childItem.key
35
- };
36
- })];
37
- }
38
- return {
39
- key: item.key
40
- };
41
- }).flat(Infinity);
42
- const totalSteps = flatSteps.filter(e => !e.hasChild);
43
-
44
- // 根据 key 获取当前 step 处于的状态;before已超过该步骤;current处于当前步骤;after还未到这个步骤;
45
- const getStepStatus = key => {
46
- let activeParentStepKey;
47
- const activeIndex = flatSteps.findIndex(e => {
48
- if (e.key === activeStepKey) {
49
- activeParentStepKey = e.parentKey;
50
- return true;
51
- }
52
- return false;
53
- });
54
- if (activeParentStepKey === key) {
55
- return 'current';
56
- }
57
- const targetIndex = flatSteps.findIndex(e => e.key === key);
58
- if (targetIndex !== -1) {
59
- if (targetIndex === activeIndex) {
60
- return 'current';
61
- }
62
- if (targetIndex < activeIndex) {
63
- return 'before';
64
- }
65
- }
66
- return 'after';
67
- };
68
-
69
- // can use this to set the activeStep by key
70
- function setActiveStepByKey(key) {
71
- setActiveStepKey(key);
72
- }
73
-
74
- // TODO: setIndex模式很难定位到child step,尽量使用key方式去定位
75
- function setActiveStepByIndex(index) {
76
- if (typeof index === 'function') {
77
- const newIndex = index(totalSteps.findIndex(e => e.key === activeStepKey));
78
- setActiveStepKey(totalSteps[newIndex].key);
79
- } else {
80
- setActiveStepKey(totalSteps[index].key);
81
- }
82
- }
83
- const activeStep = totalSteps.findIndex(e => e.key === activeStepKey);
84
- useEffect(() => {
85
- if (mode === 'history') {
86
- let stepKey = '';
87
- steps.some(step => {
88
- if (step.children && step.children.length) {
89
- return step.children.some(childStep => {
90
- if (matchPath(childStep.path, childStep.exact)) {
91
- stepKey = childStep.key;
92
- return true;
93
- }
94
- return false;
95
- });
96
- }
97
- if (matchPath(step.path, step.exact)) {
98
- stepKey = step.key;
99
- return true;
100
- }
101
- return false;
102
- });
103
- if (stepKey) {
104
- setActiveStepKey(stepKey);
105
- }
106
- }
107
- return () => {};
108
- }, [steps, mode]);
109
- const value = {
110
- steps,
111
- totalStepsCount: totalSteps.length,
112
- getStepStatus,
113
- setActiveStepByKey,
114
- setActiveStepByIndex,
115
- activeStep,
116
- // judge node can be clicked to back if the mode is 'memory'
117
- canBackToStep: nodeIndex => {
118
- return mode === 'memory' && activeStep !== 0 && nodeIndex < activeStep;
119
- }
120
- };
121
- return /*#__PURE__*/_jsx(Provider, {
122
- value: value,
123
- children: children
124
- });
125
- }
126
- function useStepContext() {
127
- return useContext(StepContext);
128
- }
129
- StepProvider.propTypes = {
130
- children: PropTypes.any.isRequired,
131
- steps: PropTypes.array.isRequired,
132
- mode: PropTypes.string
133
- };
134
- StepProvider.defaultProps = {
135
- mode: 'history'
136
- };
137
- export { StepProvider, useStepContext };
package/es/header.js DELETED
@@ -1,337 +0,0 @@
1
- import Img from '@arcblock/ux/lib/Img';
2
- import { getBlockletDisplayName } from '@blocklet/launcher-util/es/util';
3
- import styled from '@emotion/styled';
4
- import Skeleton from '@mui/material/Skeleton';
5
- import useMediaQuery from '@mui/material/useMediaQuery';
6
- import isEmpty from 'is-empty';
7
- import PropTypes from 'prop-types';
8
- import { useEffect, useRef, useState } from 'react';
9
- import joinUrl from 'url-join';
10
- import defaultBlockletLogo from './assets/blocklet-default-logo.png';
11
- import { getLaunchingText } from './locale';
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- function AppHeader({
14
- blockletMeta,
15
- subTitle,
16
- logoUrl,
17
- locale,
18
- navLogo,
19
- loading
20
- }) {
21
- const isMobile = useMediaQuery(theme => theme.breakpoints.down('md'));
22
- const blockletSize = isMobile ? 18 : 48;
23
- const appNameRef = useRef(null);
24
- const [appNameSize, setAppNameSize] = useState('');
25
- useEffect(() => {
26
- if (appNameRef.current && appNameRef.current.offsetHeight > 34) {
27
- if (appNameSize === '') {
28
- setAppNameSize('middle');
29
- } else if (appNameSize === 'middle') {
30
- setAppNameSize('small');
31
- }
32
- }
33
- }, [appNameSize]);
34
- return /*#__PURE__*/_jsxs(Container, {
35
- className: appNameSize === 'small' ? 'center-mode' : '',
36
- children: [isMobile ? /*#__PURE__*/_jsx("div", {
37
- className: "app-icon",
38
- children: navLogo
39
- }) : /*#__PURE__*/_jsxs("div", {
40
- className: "app-icon",
41
- children: [loading && /*#__PURE__*/_jsx(AppIconSkeleton, {
42
- blockletSize: blockletSize,
43
- isMobile: isMobile
44
- }), !loading && /*#__PURE__*/_jsx(AppIcon, {
45
- blockletSize: blockletSize,
46
- logoUrl: logoUrl
47
- })]
48
- }), /*#__PURE__*/_jsxs("div", {
49
- className: "header-title",
50
- children: [isMobile && subTitle && /*#__PURE__*/_jsx("div", {
51
- className: "header-title-sub",
52
- children: subTitle
53
- }), /*#__PURE__*/_jsxs("div", {
54
- className: "app-name-content",
55
- children: [!isMobile && /*#__PURE__*/_jsx("div", {
56
- className: "launching-context",
57
- children: subTitle || getLaunchingText(locale)
58
- }), /*#__PURE__*/_jsx("div", {
59
- className: `header-title-name ${appNameSize === 'middle' || appNameSize === 'small' ? 'middle-size' : ''}`,
60
- ref: appNameRef,
61
- children: /*#__PURE__*/_jsx(AppTitle, {
62
- logoUrl: logoUrl,
63
- isMobile: isMobile,
64
- blockletMeta: blockletMeta,
65
- blockletSize: blockletSize,
66
- loading: loading
67
- })
68
- })]
69
- })]
70
- })]
71
- });
72
- }
73
- AppHeader.propTypes = {
74
- blockletMeta: PropTypes.object,
75
- subTitle: PropTypes.any,
76
- logoUrl: PropTypes.string,
77
- locale: PropTypes.string,
78
- navLogo: PropTypes.any,
79
- loading: PropTypes.bool
80
- };
81
- AppHeader.defaultProps = {
82
- subTitle: '',
83
- logoUrl: '',
84
- locale: '',
85
- navLogo: '',
86
- loading: false,
87
- blockletMeta: {}
88
- };
89
-
90
- // eslint-disable-next-line react/prop-types
91
- function AppIconSkeleton({
92
- blockletSize,
93
- isMobile
94
- }) {
95
- if (isMobile) {
96
- return /*#__PURE__*/_jsx(Skeleton, {
97
- variant: "rectangular",
98
- width: 100,
99
- height: 16,
100
- alt: "icon",
101
- style: {
102
- marginTop: 4
103
- }
104
- });
105
- }
106
- return /*#__PURE__*/_jsx(Skeleton, {
107
- variant: "rectangular",
108
- width: blockletSize,
109
- height: blockletSize
110
- });
111
- }
112
-
113
- // eslint-disable-next-line react/prop-types
114
- function AppIcon({
115
- logoUrl,
116
- blockletSize
117
- }) {
118
- return /*#__PURE__*/_jsx(Img, {
119
- // force update
120
- width: blockletSize,
121
- height: blockletSize,
122
- src: logoUrl,
123
- alt: "blocklet icon",
124
- fallback: defaultBlockletLogo,
125
- style: {
126
- verticalAlign: 'text-bottom'
127
- }
128
- }, `layout-app-icon-${logoUrl}`);
129
- }
130
-
131
- // eslint-disable-next-line react/prop-types
132
- function AppTitle({
133
- isMobile,
134
- logoUrl,
135
- blockletMeta,
136
- blockletSize,
137
- loading
138
- }) {
139
- const name = getBlockletDisplayName(blockletMeta);
140
- if (loading) {
141
- return /*#__PURE__*/_jsx(Skeleton, {
142
- variant: "rectangular",
143
- width: 100,
144
- height: 16,
145
- alt: "icon",
146
- style: {
147
- marginTop: 4
148
- }
149
- });
150
- }
151
- if (isEmpty(blockletMeta)) {
152
- return /*#__PURE__*/_jsx(Skeleton, {
153
- variant: "rectangular",
154
- animation: false,
155
- width: 100,
156
- height: 16,
157
- alt: "icon",
158
- style: {
159
- marginTop: 4
160
- }
161
- });
162
- }
163
- if (isMobile) {
164
- return /*#__PURE__*/_jsxs(MobileTitleStyle, {
165
- children: [/*#__PURE__*/_jsx(AppIcon, {
166
- blockletSize: blockletSize,
167
- logoUrl: logoUrl
168
- }), /*#__PURE__*/_jsx("span", {
169
- className: "ellipsis-title",
170
- children: getBlockletDisplayName(blockletMeta)
171
- })]
172
- });
173
- }
174
- return /*#__PURE__*/_jsx(AppLink, {
175
- target: "_blank",
176
- href: joinUrl(blockletMeta?.registryUrl || '', `/blocklets/${blockletMeta?.did}`),
177
- title: name,
178
- children: name
179
- });
180
- }
181
- const MobileTitleStyle = styled.div`
182
- .ellipsis-title {
183
- flex: 1;
184
- position: absolute;
185
- left: 0;
186
- top: 0;
187
- width: 100%;
188
- height: 100%;
189
- white-space: nowrap;
190
- overflow: hidden;
191
- text-overflow: ellipsis;
192
-
193
- ${props => props.theme.breakpoints.down('md')} {
194
- left: 26px;
195
- width: calc(100% - 26px);
196
- }
197
- }
198
- `;
199
- AppTitle.propTypes = {
200
- blockletMeta: PropTypes.object
201
- };
202
- AppTitle.defaultProps = {
203
- blockletMeta: {}
204
- };
205
- export default AppHeader;
206
- const AppLink = styled.a`
207
- color: ${props => props.theme.palette.common.black};
208
- text-decoration: none;
209
- overflow: hidden;
210
- text-overflow: ellipsis;
211
- display: -webkit-box;
212
- -webkit-line-clamp: 2;
213
- -webkit-box-orient: vertical;
214
- font-family: Lato, Avenir, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif,
215
- 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
216
- text-decoration: none;
217
- font-weight: 700;
218
- -webkit-font-smoothing: antialiased;
219
-
220
- ${props => props.theme.breakpoints.down('md')} {
221
- display: block;
222
- max-width: calc(100vw - 150px);
223
- white-space: nowrap;
224
- overflow: hidden;
225
- text-overflow: ellipsis;
226
- }
227
- `;
228
- const Container = styled.div`
229
- display: flex;
230
- justify-content: flex-start;
231
- align-items: flex-start;
232
- width: 100%;
233
- ${props => props.theme.breakpoints.up('md')} {
234
- min-height: 70px;
235
- }
236
- ${props => props.theme.breakpoints.down('md')} {
237
- align-items: center;
238
- }
239
- .app-name-content {
240
- width: 100%;
241
- display: flex;
242
- align-items: center;
243
- justify-content: center;
244
- ${props => props.theme.breakpoints.up('md')} {
245
- align-items: flex-start;
246
- flex-direction: column;
247
- }
248
- ${props => props.theme.breakpoints.down('md')} {
249
- justify-content: flex-start;
250
- height: 22px;
251
- }
252
- }
253
- .launching-context {
254
- flex-shrink: 0;
255
- font-size: 14px;
256
- font-weight: 600;
257
- color: ${props => props.theme.palette.grey[500]};
258
- ${props => props.theme.breakpoints.up('md')} {
259
- margin-bottom: 4px;
260
- }
261
- ${props => props.theme.breakpoints.down('md')} {
262
- font-size: 14px;
263
- line-height: 15px;
264
- &:after {
265
- display: inline-block;
266
- margin: 0 4px;
267
- content: ':';
268
- }
269
- }
270
- }
271
-
272
- &.center-mode {
273
- align-items: flex-start;
274
- .launching-context {
275
- ${props => props.theme.breakpoints.up('sm')} {
276
- margin-bottom: 0;
277
- }
278
- }
279
- }
280
-
281
- .app-icon {
282
- flex-shrink: 0;
283
- > * {
284
- display: block;
285
- vertical-align: middle;
286
- }
287
- }
288
-
289
- .header-title {
290
- flex: 1;
291
- display: flex;
292
- flex-direction: column;
293
- justify-content: space-around;
294
- align-items: flex-start;
295
- margin-left: 24px;
296
- ${props => props.theme.breakpoints.down('md')} {
297
- margin-left: 16px;
298
- }
299
- .header-title-name {
300
- position: relative;
301
- display: flex;
302
- justify-content: center;
303
- align-items: center;
304
- flex: 1;
305
- height: 100%;
306
- color: ${props => props.theme.palette.common.black};
307
- font-weight: 700;
308
- ${props => props.theme.breakpoints.up('sm')} {
309
- font-size: 18px;
310
-
311
- &.middle-size {
312
- font-size: 16px;
313
- }
314
- }
315
- ${props => props.theme.breakpoints.down('md')} {
316
- display: block;
317
- max-width: calc(100vw - 100px);
318
- font-size: 16px;
319
- white-space: nowrap;
320
- overflow: hidden;
321
- text-overflow: ellipsis;
322
- }
323
- }
324
-
325
- .header-title-sub {
326
- color: ${props => props.theme.palette.grey[700]};
327
- font-size: 12px;
328
- line-height: 16px;
329
-
330
- ${props => props.theme.breakpoints.down('md')} {
331
- white-space: nowrap;
332
- overflow: hidden;
333
- text-overflow: ellipsis;
334
- }
335
- }
336
- }
337
- `;