lupine.components 1.0.27 → 1.1.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.
- package/package.json +1 -1
- package/src/components/action-sheet.tsx +1 -1
- package/src/components/drag-refresh.tsx +20 -1
- package/src/components/float-window.tsx +1 -1
- package/src/components/html-var.tsx +0 -5
- package/src/components/index.ts +1 -0
- package/src/components/menu-sidebar.tsx +2 -2
- package/src/components/notice-message.tsx +2 -2
- package/src/components/paging-link.tsx +2 -2
- package/src/components/resizable-splitter.tsx +2 -2
- package/src/components/tabs.tsx +48 -25
- package/src/components/text-glow.tsx +3 -2
- package/src/components/text-scale.tsx +42 -0
- package/src/components/text-wave.tsx +6 -5
- package/src/components/theme-selector.tsx +4 -7
- package/src/components/toggle-base.tsx +25 -16
- package/src/components/toggle-switch.tsx +13 -9
- package/src/lib/base62.ts +23 -0
- package/src/lib/index.ts +1 -0
package/package.json
CHANGED
|
@@ -42,7 +42,7 @@ export class ActionSheet {
|
|
|
42
42
|
handleClose();
|
|
43
43
|
};
|
|
44
44
|
const onClickContainer = (event: any) => {
|
|
45
|
-
if (closeWhenClickOutside !== false && event.target.
|
|
45
|
+
if (closeWhenClickOutside !== false && event.target.classList.contains('act-sheet-box')) {
|
|
46
46
|
handleClose();
|
|
47
47
|
}
|
|
48
48
|
};
|
|
@@ -3,11 +3,18 @@ import { Spinner02, SpinnerSize } from './spinner';
|
|
|
3
3
|
|
|
4
4
|
export type DragRefreshCloseProps = () => void;
|
|
5
5
|
|
|
6
|
+
export type DragRefreshHookProps = {
|
|
7
|
+
setEnable: (enable: boolean) => void;
|
|
8
|
+
updateOnDragRefresh: (onDragRefresh: (close: DragRefreshCloseProps) => Promise<void>) => void;
|
|
9
|
+
};
|
|
10
|
+
|
|
6
11
|
export type DragRefreshProps = {
|
|
7
12
|
container: string;
|
|
8
13
|
onDragRefresh: (close: DragRefreshCloseProps) => Promise<void>;
|
|
14
|
+
hook?: DragRefreshHookProps;
|
|
9
15
|
};
|
|
10
16
|
|
|
17
|
+
// globally there should be only one DragFresh
|
|
11
18
|
export const DragFresh = (props: DragRefreshProps) => {
|
|
12
19
|
const css: CssProps = {
|
|
13
20
|
display: 'flex',
|
|
@@ -20,7 +27,7 @@ export const DragFresh = (props: DragRefreshProps) => {
|
|
|
20
27
|
top: '0',
|
|
21
28
|
left: '0',
|
|
22
29
|
width: '100%',
|
|
23
|
-
zIndex:
|
|
30
|
+
zIndex: 'var(--layer-dragged-item)',
|
|
24
31
|
display: 'none',
|
|
25
32
|
justifyContent: 'center',
|
|
26
33
|
transition: 'opacity 0.5s ease',
|
|
@@ -32,6 +39,15 @@ export const DragFresh = (props: DragRefreshProps) => {
|
|
|
32
39
|
},
|
|
33
40
|
};
|
|
34
41
|
|
|
42
|
+
let isEnabled = true;
|
|
43
|
+
if (props.hook) {
|
|
44
|
+
props.hook.setEnable = (enable: boolean) => {
|
|
45
|
+
isEnabled = enable;
|
|
46
|
+
};
|
|
47
|
+
props.hook.updateOnDragRefresh = (onDragRefresh: (close: DragRefreshCloseProps) => Promise<void>) => {
|
|
48
|
+
props.onDragRefresh = onDragRefresh;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
35
51
|
const closeSpin = () => {
|
|
36
52
|
const spinnerDom = ref.$('.drag-spinner') as HTMLDivElement;
|
|
37
53
|
if (!spinnerDom) return;
|
|
@@ -53,12 +69,14 @@ export const DragFresh = (props: DragRefreshProps) => {
|
|
|
53
69
|
let needRefresh = false;
|
|
54
70
|
const maxHeight = 150;
|
|
55
71
|
container.addEventListener('touchstart', (e: any) => {
|
|
72
|
+
if (!isEnabled) return;
|
|
56
73
|
touchstartY = e.touches[0].clientY;
|
|
57
74
|
touchstartX = e.touches[0].clientX;
|
|
58
75
|
direction = '';
|
|
59
76
|
needRefresh = false;
|
|
60
77
|
});
|
|
61
78
|
container.addEventListener('touchmove', (e: any) => {
|
|
79
|
+
if (!isEnabled) return;
|
|
62
80
|
const touchY = e.touches[0].clientY;
|
|
63
81
|
const touchX = e.touches[0].clientX;
|
|
64
82
|
const movedY = touchY - touchstartY;
|
|
@@ -89,6 +107,7 @@ export const DragFresh = (props: DragRefreshProps) => {
|
|
|
89
107
|
}
|
|
90
108
|
});
|
|
91
109
|
container.addEventListener('touchend', (e) => {
|
|
110
|
+
if (!isEnabled) return;
|
|
92
111
|
if (direction === 'Y') {
|
|
93
112
|
if (needRefresh) {
|
|
94
113
|
props.onDragRefresh(closeSpin);
|
|
@@ -49,7 +49,7 @@ export class FloatWindow {
|
|
|
49
49
|
contentOverflowY = 'auto', // set to unset for having popup menu inside
|
|
50
50
|
}: FloatWindowShowProps): Promise<FloatWindowCloseProps> {
|
|
51
51
|
const onClickContainer = (event: any) => {
|
|
52
|
-
if (closeWhenClickOutside !== false && event.target.
|
|
52
|
+
if (closeWhenClickOutside !== false && event.target.classList.contains('fwin-box')) {
|
|
53
53
|
handleClose();
|
|
54
54
|
}
|
|
55
55
|
};
|
package/src/components/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bindGlobalStyle, CssProps, getRenderPageProps, RefProps } from 'lupine.web';
|
|
2
2
|
import { stopPropagation } from '../lib';
|
|
3
3
|
import { MediaQueryMaxWidth } from '../styles';
|
|
4
4
|
import { NestMenuItemProps } from './menu-item-props';
|
|
@@ -283,7 +283,7 @@ export const MenuSidebar = ({
|
|
|
283
283
|
};
|
|
284
284
|
|
|
285
285
|
// if this component is used twice, then the Global styles is only set at the first time
|
|
286
|
-
|
|
286
|
+
bindGlobalStyle('menu-sidebar-box', css);
|
|
287
287
|
|
|
288
288
|
// show the menu on both mobile and desktop
|
|
289
289
|
const newCss: CssProps =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps,
|
|
1
|
+
import { CssProps, bindGlobalStyle } from 'lupine.web';
|
|
2
2
|
/**
|
|
3
3
|
How to use:
|
|
4
4
|
Notification.sendMessage(message);
|
|
@@ -71,7 +71,7 @@ export class NotificationMessage {
|
|
|
71
71
|
color: 'black',
|
|
72
72
|
},
|
|
73
73
|
};
|
|
74
|
-
|
|
74
|
+
bindGlobalStyle('lj_notification', css);
|
|
75
75
|
|
|
76
76
|
let container = document.querySelector('.lj_notification');
|
|
77
77
|
if (!container) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps, RefProps,
|
|
1
|
+
import { CssProps, RefProps, bindGlobalStyle, getRenderPageProps } from 'lupine.web';
|
|
2
2
|
|
|
3
3
|
let _DEFAULT_PAGE_LIMIT = 10;
|
|
4
4
|
export const getDefaultPageLimit = () => {
|
|
@@ -70,7 +70,7 @@ export const PagingLink = ({
|
|
|
70
70
|
},
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
bindGlobalStyle('paging-link-box', css);
|
|
74
74
|
pageIndex = pageIndex ?? (Number.parseInt(getRenderPageProps().query['pg_i'] || '') || 0);
|
|
75
75
|
pageLimit = pageLimit || _DEFAULT_PAGE_LIMIT;
|
|
76
76
|
let maxPages = Math.floor(itemsCount / pageLimit);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bindGlobalStyle, CssProps } from 'lupine.web';
|
|
2
2
|
import { stopPropagation } from '../lib';
|
|
3
3
|
/**
|
|
4
4
|
How to use:
|
|
@@ -63,7 +63,7 @@ export class ResizableSplitter {
|
|
|
63
63
|
backgroundColor: '#ccc',
|
|
64
64
|
},
|
|
65
65
|
};
|
|
66
|
-
|
|
66
|
+
bindGlobalStyle('resizable-splitter', css);
|
|
67
67
|
|
|
68
68
|
window.addEventListener('mousemove', ResizableSplitter.onMousemove.bind(ResizableSplitter), false);
|
|
69
69
|
document.documentElement.addEventListener('mouseup', ResizableSplitter.onMouseup.bind(ResizableSplitter), false);
|
package/src/components/tabs.tsx
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
CssProps,
|
|
3
|
+
RefProps,
|
|
4
|
+
VNode,
|
|
5
|
+
bindGlobalStyle,
|
|
6
|
+
domUniqueId,
|
|
7
|
+
getGlobalStylesId,
|
|
8
|
+
mountInnerComponent,
|
|
9
|
+
} from 'lupine.web';
|
|
2
10
|
import { stopPropagation } from '../lib';
|
|
3
11
|
|
|
4
12
|
export type TabsHookProps = {
|
|
@@ -24,31 +32,30 @@ export type TabsProps = {
|
|
|
24
32
|
};
|
|
25
33
|
// For CSS or query selectors, please pay attention to that Tabs can be nested
|
|
26
34
|
export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: refUpdate }: TabsProps) => {
|
|
27
|
-
const ref: RefProps = {};
|
|
28
35
|
let newIndex = typeof defaultIndex === 'number' ? defaultIndex : 0;
|
|
29
36
|
const clearIndex = () => {
|
|
30
|
-
const header = ref.$(
|
|
37
|
+
const header = ref.$(`.&tabs > div > .tab.active`);
|
|
31
38
|
header && header.classList.remove('active');
|
|
32
|
-
const page = ref.$(
|
|
39
|
+
const page = ref.$(`.&pages > .page.active`);
|
|
33
40
|
page && page.classList.remove('active');
|
|
34
41
|
};
|
|
35
42
|
const updateIndex = (index: number) => {
|
|
36
43
|
clearIndex();
|
|
37
|
-
const doms = ref.$all(
|
|
44
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
38
45
|
if (index >= 0 && index < doms.length) {
|
|
39
46
|
doms[index].classList.add('active');
|
|
40
|
-
const pages = ref.$all(
|
|
47
|
+
const pages = ref.$all(`.&pages > .page`);
|
|
41
48
|
pages[index].classList.add('active');
|
|
42
49
|
refUpdate?.indexChanged && refUpdate?.indexChanged(index);
|
|
43
50
|
}
|
|
44
51
|
};
|
|
45
52
|
const removePage = (index: number) => {
|
|
46
|
-
const doms = ref.$all(
|
|
53
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
47
54
|
if (index >= 0 && index < doms.length) {
|
|
48
55
|
const newIndex = index === doms.length - 1 ? index - 1 : index;
|
|
49
56
|
const isAct = doms[index].classList.contains('active');
|
|
50
57
|
doms[index].parentNode.remove();
|
|
51
|
-
const pages = ref.$all(
|
|
58
|
+
const pages = ref.$all(`.&pages > .page`);
|
|
52
59
|
pages[index].remove();
|
|
53
60
|
|
|
54
61
|
if (isAct) {
|
|
@@ -65,7 +72,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
65
72
|
};
|
|
66
73
|
|
|
67
74
|
const newPage = async (title: string, page: VNode<any>, index?: number) => {
|
|
68
|
-
const allTabs = ref.$all(
|
|
75
|
+
const allTabs = ref.$all(`.&tabs > div > .tab`);
|
|
69
76
|
let newPageIndex = allTabs.length;
|
|
70
77
|
if (typeof index === 'number' && index >= 0 && index < allTabs.length) {
|
|
71
78
|
newPageIndex = index;
|
|
@@ -78,12 +85,12 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
78
85
|
const newPage = document.createElement('div');
|
|
79
86
|
newPage.className = 'page';
|
|
80
87
|
if (newPageIndex === allTabs.length) {
|
|
81
|
-
ref.$(
|
|
82
|
-
ref.$(
|
|
88
|
+
ref.$(`.&tabs`).appendChild(newTab);
|
|
89
|
+
ref.$(`.&pages`).appendChild(newPage);
|
|
83
90
|
} else {
|
|
84
|
-
ref.$(
|
|
85
|
-
const pages = ref.$all(
|
|
86
|
-
ref.$(
|
|
91
|
+
ref.$(`.&tabs`).insertBefore(newTab, allTabs[newPageIndex]);
|
|
92
|
+
const pages = ref.$all(`.&pages > .page`);
|
|
93
|
+
ref.$(`.&pages`).insertBefore(newPage, pages[newPageIndex]);
|
|
87
94
|
}
|
|
88
95
|
|
|
89
96
|
await mountInnerComponent(newTab, newTab2);
|
|
@@ -108,7 +115,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
108
115
|
updateIndex(index);
|
|
109
116
|
};
|
|
110
117
|
const flashTitle = (index: number) => {
|
|
111
|
-
const doms = ref.$all(
|
|
118
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
112
119
|
if (index >= 0 && index < doms.length) {
|
|
113
120
|
doms[index].classList.add('flash');
|
|
114
121
|
setTimeout(() => {
|
|
@@ -118,7 +125,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
118
125
|
};
|
|
119
126
|
if (refUpdate) {
|
|
120
127
|
refUpdate.updateTitle = (index: number, title: string) => {
|
|
121
|
-
const doms = ref.$all(
|
|
128
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
122
129
|
if (index >= 0 && index < doms.length) {
|
|
123
130
|
doms[index].innerHTML = title;
|
|
124
131
|
}
|
|
@@ -127,15 +134,15 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
127
134
|
refUpdate.removePage = removePage;
|
|
128
135
|
refUpdate.newPage = newPage;
|
|
129
136
|
refUpdate.getIndex = () => {
|
|
130
|
-
const header = ref.$(
|
|
137
|
+
const header = ref.$(`.&tabs > div > .tab.active`);
|
|
131
138
|
return header ? Array.prototype.indexOf.call(header.parentNode.parentNode.children, header.parentNode) : -1;
|
|
132
139
|
};
|
|
133
140
|
refUpdate.getCount = () => {
|
|
134
|
-
const doms = ref.$all(
|
|
141
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
135
142
|
return doms.length;
|
|
136
143
|
};
|
|
137
144
|
refUpdate.findAndActivate = (title: string) => {
|
|
138
|
-
const doms = ref.$all(
|
|
145
|
+
const doms = ref.$all(`.&tabs > div > .tab`);
|
|
139
146
|
for (let i = 0; i < doms.length; i++) {
|
|
140
147
|
if (doms[i].innerText === title) {
|
|
141
148
|
updateIndex(i);
|
|
@@ -148,7 +155,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
// pay attention to nest tabs
|
|
151
|
-
const
|
|
158
|
+
const css: CssProps = {
|
|
152
159
|
display: 'flex',
|
|
153
160
|
'flex-direction': 'column',
|
|
154
161
|
width: '100%',
|
|
@@ -158,7 +165,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
158
165
|
// hide tabs when there is no tabs (not need to show borders)
|
|
159
166
|
display: 'none',
|
|
160
167
|
},
|
|
161
|
-
'>
|
|
168
|
+
'> .&tabs': {
|
|
162
169
|
display: 'flex',
|
|
163
170
|
height: 'auto',
|
|
164
171
|
'border-bottom': '1px solid grey',
|
|
@@ -212,7 +219,7 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
212
219
|
color: '#ff0000',
|
|
213
220
|
},
|
|
214
221
|
},
|
|
215
|
-
'>
|
|
222
|
+
'> .&pages': {
|
|
216
223
|
display: 'flex',
|
|
217
224
|
flex: '1',
|
|
218
225
|
position: 'relative',
|
|
@@ -232,16 +239,32 @@ export const Tabs = ({ pages, defaultIndex, topClassName, pagePadding, hook: ref
|
|
|
232
239
|
},
|
|
233
240
|
},
|
|
234
241
|
};
|
|
242
|
+
// we want to put all common styles in the header
|
|
243
|
+
const tabGlobalCssId = getGlobalStylesId(css);
|
|
244
|
+
bindGlobalStyle(tabGlobalCssId, css);
|
|
235
245
|
|
|
246
|
+
const ref: RefProps = {
|
|
247
|
+
globalCssId: tabGlobalCssId,
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
// but we also want to create unique id for the current tab
|
|
251
|
+
const cssTab: CssProps = {
|
|
252
|
+
'&tabs': {
|
|
253
|
+
display: 'flex',
|
|
254
|
+
},
|
|
255
|
+
'&pages': {
|
|
256
|
+
display: 'flex',
|
|
257
|
+
},
|
|
258
|
+
};
|
|
236
259
|
return (
|
|
237
|
-
<div ref={ref} css={
|
|
238
|
-
<div class='tabs'
|
|
260
|
+
<div ref={ref} css={cssTab} class={topClassName ? ' ' + topClassName : ''}>
|
|
261
|
+
<div class='&tabs tabs'>
|
|
239
262
|
{pages.map((i, index) => {
|
|
240
263
|
const className = index === newIndex ? ' active' : '';
|
|
241
264
|
return <div>{createTabHeader(i.title, className)}</div>;
|
|
242
265
|
})}
|
|
243
266
|
</div>
|
|
244
|
-
<div class='pages'
|
|
267
|
+
<div class='&pages pages'>
|
|
245
268
|
{pages.map((i, index) => {
|
|
246
269
|
const className = index === newIndex ? ' active' : '';
|
|
247
270
|
return <div class={'page' + className}>{i.page}</div>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps } from 'lupine.web';
|
|
1
|
+
import { bindGlobalStyle, CssProps } from 'lupine.web';
|
|
2
2
|
|
|
3
3
|
export type TextGlowProps = {
|
|
4
4
|
text: string;
|
|
@@ -28,8 +28,9 @@ export const TextGlow = (props: TextGlowProps) => {
|
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
};
|
|
31
|
+
bindGlobalStyle('text-glow-top', css);
|
|
31
32
|
return (
|
|
32
|
-
<div
|
|
33
|
+
<div class='text-glow-top'>
|
|
33
34
|
<div class='text-glow'>{props.text}</div>
|
|
34
35
|
</div>
|
|
35
36
|
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { bindGlobalStyle, CssProps } from 'lupine.web';
|
|
2
|
+
|
|
3
|
+
export type TextScaleProps = {
|
|
4
|
+
text: string;
|
|
5
|
+
color?: string;
|
|
6
|
+
backgroundColor?: string;
|
|
7
|
+
padding?: string;
|
|
8
|
+
fontSize?: string;
|
|
9
|
+
fontWeight?: string;
|
|
10
|
+
};
|
|
11
|
+
export const TextScale = (props: TextScaleProps) => {
|
|
12
|
+
const css: CssProps = {
|
|
13
|
+
width: `100%`,
|
|
14
|
+
height: `100%`,
|
|
15
|
+
display: 'flex',
|
|
16
|
+
justifyContent: 'center',
|
|
17
|
+
alignItems: 'center',
|
|
18
|
+
color: props.color || '#22b8ff',
|
|
19
|
+
fontSize: props.fontSize || '30px',
|
|
20
|
+
fontWeight: props.fontWeight || '500',
|
|
21
|
+
'.text-scale': {
|
|
22
|
+
animation: 'text-scale 1.5s infinite alternate',
|
|
23
|
+
backgroundColor: props.backgroundColor || '#a1ffe8',
|
|
24
|
+
padding: props.padding || '10px',
|
|
25
|
+
borderRadius: '5px',
|
|
26
|
+
},
|
|
27
|
+
'@keyframes text-scale': {
|
|
28
|
+
'0%, 100%': {
|
|
29
|
+
transform: 'scale(1)',
|
|
30
|
+
},
|
|
31
|
+
'40%': {
|
|
32
|
+
transform: 'scale(0.7)',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
bindGlobalStyle('text-scale-top', css);
|
|
37
|
+
return (
|
|
38
|
+
<div class='text-scale-top'>
|
|
39
|
+
<div class='text-scale'>{props.text}</div>
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CssProps } from "lupine.web";
|
|
1
|
+
import { bindGlobalStyle, CssProps } from "lupine.web";
|
|
2
2
|
|
|
3
3
|
export type TextLoadingProps = {
|
|
4
4
|
text: string;
|
|
@@ -21,12 +21,12 @@ export const TextWave = (props: TextLoadingProps) => {
|
|
|
21
21
|
fontSize: props.fontSize || '20px',
|
|
22
22
|
fontWeight: props.fontWeight,
|
|
23
23
|
textShadow: '1px -1px #ffffff, -2px 2px #999, -6px 7px 3px #131f5be6',
|
|
24
|
-
'.text-
|
|
24
|
+
'.text-wave.wave-animetion span': {
|
|
25
25
|
display: 'inline-block',
|
|
26
26
|
padding: '0 4px',
|
|
27
27
|
animation: 'wave-text 1s ease-in-out infinite',
|
|
28
28
|
},
|
|
29
|
-
'.text-
|
|
29
|
+
'.text-wave.wave-animetion': {
|
|
30
30
|
marginTop: '0.6em',
|
|
31
31
|
...cssMap,
|
|
32
32
|
},
|
|
@@ -42,9 +42,10 @@ export const TextWave = (props: TextLoadingProps) => {
|
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
44
|
};
|
|
45
|
+
bindGlobalStyle('text-wave-top', css);
|
|
45
46
|
return (
|
|
46
|
-
<div
|
|
47
|
-
<div class='text-
|
|
47
|
+
<div class='text-wave-top'>
|
|
48
|
+
<div class='text-wave wave-animetion'>
|
|
48
49
|
{props.text.split('').map((char, index) => (
|
|
49
50
|
<span class={`span${index}`}>{char}</span>
|
|
50
51
|
))}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import { CssProps,
|
|
1
|
+
import { CssProps, getCurrentTheme, updateTheme } from 'lupine.web';
|
|
2
2
|
import { PopupMenu } from './popup-menu';
|
|
3
3
|
|
|
4
4
|
export type ThemeSelectorProps = {
|
|
5
5
|
className?: string;
|
|
6
|
-
css?: CssProps;
|
|
7
6
|
};
|
|
8
7
|
|
|
9
|
-
export const ThemeSelector = ({ className
|
|
10
|
-
const
|
|
8
|
+
export const ThemeSelector = ({ className }: ThemeSelectorProps) => {
|
|
9
|
+
const css: CssProps = {
|
|
11
10
|
display: 'flex',
|
|
12
11
|
flexDirection: 'column',
|
|
13
12
|
alignSelf: 'end',
|
|
14
|
-
...css,
|
|
15
13
|
};
|
|
16
14
|
|
|
17
|
-
bindGlobalStyles('theme-switch', '.theme-switch', newCss);
|
|
18
15
|
const handleSelected = (themeName: string) => {
|
|
19
16
|
updateTheme(themeName);
|
|
20
17
|
};
|
|
@@ -24,7 +21,7 @@ export const ThemeSelector = ({ className, css }: ThemeSelectorProps) => {
|
|
|
24
21
|
list.push(themeName);
|
|
25
22
|
}
|
|
26
23
|
return (
|
|
27
|
-
<div css={
|
|
24
|
+
<div css={css} class={['theme-switch', className].join(' ')} title='Select theme'>
|
|
28
25
|
<PopupMenu list={list} defaultValue={currentTheme.themeName} handleSelected={handleSelected}></PopupMenu>
|
|
29
26
|
</div>
|
|
30
27
|
);
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { CssProps, RefProps, VNode } from 'lupine.web';
|
|
1
|
+
import { bindGlobalStyle, CssProps, RefProps, VNode } from 'lupine.web';
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const TogglePlayButtonSize = {
|
|
4
4
|
Small: { w: 50, h: 50 },
|
|
5
5
|
Medium: { w: 70, h: 70 },
|
|
6
6
|
Large: { w: 90, h: 90 },
|
|
7
7
|
};
|
|
8
|
-
export type
|
|
8
|
+
export type TogglePlayButtonSizeProps = {
|
|
9
9
|
w: number;
|
|
10
10
|
h: number;
|
|
11
11
|
};
|
|
12
|
-
export type
|
|
13
|
-
size:
|
|
12
|
+
export type TogglePlayButtonProps = {
|
|
13
|
+
size: TogglePlayButtonSizeProps;
|
|
14
14
|
disabled?: boolean;
|
|
15
15
|
checked?: boolean;
|
|
16
16
|
onClick?: (checked: boolean) => void;
|
|
17
17
|
hook?: ToggleBaseHookProps;
|
|
18
18
|
};
|
|
19
|
-
export const
|
|
19
|
+
export const TogglePlayButton = (props: TogglePlayButtonProps) => {
|
|
20
20
|
const css: CssProps = {
|
|
21
21
|
width: `100%`,
|
|
22
22
|
height: `100%`,
|
|
@@ -45,12 +45,12 @@ export const PlayButton = (props: PlayButtonProps) => {
|
|
|
45
45
|
backgroundColor: '#5d578b',
|
|
46
46
|
},
|
|
47
47
|
};
|
|
48
|
+
bindGlobalStyle('toggle-play-button-component', css);
|
|
48
49
|
return (
|
|
49
50
|
<ToggleBase {...props}>
|
|
50
51
|
<ToggleWaveFrame>
|
|
51
52
|
<div
|
|
52
|
-
|
|
53
|
-
class={`toggle-button-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
|
|
53
|
+
class={`toggle-play-button-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
|
|
54
54
|
props.disabled ? ' disabled' : ''
|
|
55
55
|
}`}
|
|
56
56
|
>
|
|
@@ -62,7 +62,7 @@ export const PlayButton = (props: PlayButtonProps) => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
export type ToggleButtonProps = {
|
|
65
|
-
size: ToggleBaseSizeProps;
|
|
65
|
+
// size: ToggleBaseSizeProps;
|
|
66
66
|
onText: string;
|
|
67
67
|
offText: string;
|
|
68
68
|
disabled?: boolean;
|
|
@@ -85,7 +85,7 @@ export const ToggleButton = (props: ToggleButtonProps) => {
|
|
|
85
85
|
},
|
|
86
86
|
};
|
|
87
87
|
return (
|
|
88
|
-
<ToggleBase {...props}>
|
|
88
|
+
<ToggleBase {...props} size={{ w: 'auto', h: 'auto' }}>
|
|
89
89
|
<div
|
|
90
90
|
css={css}
|
|
91
91
|
class={`toggle-button-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
|
|
@@ -120,12 +120,11 @@ export const ToggleWaveFrame = (props: ToggleWaveFrameProps) => {
|
|
|
120
120
|
position: 'absolute',
|
|
121
121
|
width: `100%`,
|
|
122
122
|
height: `100%`,
|
|
123
|
-
top: '
|
|
123
|
+
top: '0',
|
|
124
124
|
left: '0',
|
|
125
125
|
borderRadius: '50%',
|
|
126
126
|
backgroundColor: '#eb205580',
|
|
127
127
|
opacity: 0,
|
|
128
|
-
zIndex: -1,
|
|
129
128
|
animation: 'pulse-border 3s ease-in-out infinite',
|
|
130
129
|
},
|
|
131
130
|
'.toggle-waves-1': {
|
|
@@ -143,16 +142,20 @@ export const ToggleWaveFrame = (props: ToggleWaveFrameProps) => {
|
|
|
143
142
|
'animation-delay': '2s',
|
|
144
143
|
},
|
|
145
144
|
'.toggle-waves-box': {
|
|
145
|
+
position: 'absolute',
|
|
146
146
|
width: `100%`,
|
|
147
147
|
height: `100%`,
|
|
148
|
+
top: '0',
|
|
149
|
+
left: '0',
|
|
148
150
|
padding: `18%`,
|
|
149
151
|
},
|
|
150
152
|
'&.disabled .toggle-waves': {
|
|
151
153
|
backgroundColor: '#5d578b',
|
|
152
154
|
},
|
|
153
155
|
};
|
|
156
|
+
bindGlobalStyle('toggle-waves-box', css);
|
|
154
157
|
return (
|
|
155
|
-
<div
|
|
158
|
+
<div class='toggle-waves-box toggle-placeholder'>
|
|
156
159
|
<div class='toggle-waves toggle-waves-1'></div>
|
|
157
160
|
<div class='toggle-waves toggle-waves-2'></div>
|
|
158
161
|
<div class='toggle-waves toggle-waves-3'></div>
|
|
@@ -230,8 +233,6 @@ export const ToggleBase = (props: ToggleBaseProps) => {
|
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
const css: CssProps = {
|
|
233
|
-
width: `${typeof props.size.w === 'number' ? props.size.w + 'px' : props.size.w}`,
|
|
234
|
-
height: `${typeof props.size.h === 'number' ? props.size.h + 'px' : props.size.h}`,
|
|
235
236
|
'.toggle-base-box, .toggle-base-container': {
|
|
236
237
|
position: 'relative',
|
|
237
238
|
width: `100%`,
|
|
@@ -243,8 +244,16 @@ export const ToggleBase = (props: ToggleBaseProps) => {
|
|
|
243
244
|
pointerEvents: 'none',
|
|
244
245
|
},
|
|
245
246
|
};
|
|
247
|
+
bindGlobalStyle('toggle-base-component', css);
|
|
246
248
|
return (
|
|
247
|
-
<div
|
|
249
|
+
<div
|
|
250
|
+
ref={ref}
|
|
251
|
+
css={{
|
|
252
|
+
width: `${typeof props.size.w === 'number' ? props.size.w + 'px' : props.size.w}`,
|
|
253
|
+
height: `${typeof props.size.h === 'number' ? props.size.h + 'px' : props.size.h}`,
|
|
254
|
+
}}
|
|
255
|
+
class='toggle-base-component'
|
|
256
|
+
>
|
|
248
257
|
<label class='toggle-base-box'>
|
|
249
258
|
<div class='toggle-base-container'>{props.children}</div>
|
|
250
259
|
<input
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { bindGlobalStyle, CssProps } from 'lupine.web';
|
|
2
2
|
import { ToggleBase, ToggleBaseHookProps } from './toggle-base';
|
|
3
3
|
|
|
4
4
|
export enum ToggleSwitchSize {
|
|
@@ -25,7 +25,7 @@ export const ToggleSwitch = (props: ToggleSwitchProps) => {
|
|
|
25
25
|
: props.size === ToggleSwitchSize.Large
|
|
26
26
|
? 42
|
|
27
27
|
: 34;
|
|
28
|
-
const
|
|
28
|
+
const classSize =
|
|
29
29
|
props.size === ToggleSwitchSize.SmallSmall
|
|
30
30
|
? 'smallsmall'
|
|
31
31
|
: props.size === ToggleSwitchSize.Small
|
|
@@ -93,10 +93,6 @@ export const ToggleSwitch = (props: ToggleSwitchProps) => {
|
|
|
93
93
|
bottom: '2px',
|
|
94
94
|
},
|
|
95
95
|
|
|
96
|
-
'& .ts-on-text, & .ts-off-text': {
|
|
97
|
-
display: 'none',
|
|
98
|
-
width: props.textWidth,
|
|
99
|
-
},
|
|
100
96
|
'&.toggle-on .ts-on-text': {
|
|
101
97
|
display: 'block',
|
|
102
98
|
},
|
|
@@ -136,14 +132,22 @@ export const ToggleSwitch = (props: ToggleSwitchProps) => {
|
|
|
136
132
|
},
|
|
137
133
|
};
|
|
138
134
|
|
|
139
|
-
|
|
135
|
+
bindGlobalStyle('toggle-switch-theme', cssTheme, false, true);
|
|
136
|
+
bindGlobalStyle('toggle-switch-component', css);
|
|
137
|
+
|
|
138
|
+
const cssSize: CssProps = {
|
|
139
|
+
'& .ts-on-text, & .ts-off-text': {
|
|
140
|
+
display: 'none',
|
|
141
|
+
width: props.textWidth,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
140
144
|
return (
|
|
141
145
|
<ToggleBase {...props} size={{ w: 'auto', h: sizeH }}>
|
|
142
146
|
<div
|
|
143
|
-
css={
|
|
147
|
+
css={cssSize}
|
|
144
148
|
class={`toggle-switch-component toggle-placeholder ${props.checked ? 'toggle-on' : 'toggle-off'}${
|
|
145
149
|
props.disabled ? ' disabled' : ''
|
|
146
|
-
} ${
|
|
150
|
+
} ${classSize}`}
|
|
147
151
|
>
|
|
148
152
|
<span class='ts-slider'>
|
|
149
153
|
<span class='ts-on-text'>{props.text?.on}</span>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class Base62 {
|
|
2
|
+
private static ALPHABET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
3
|
+
private static BASE = 62;
|
|
4
|
+
static toString(num: number) {
|
|
5
|
+
if (num === 0) return Base62.ALPHABET[0];
|
|
6
|
+
|
|
7
|
+
let result = '';
|
|
8
|
+
while (num > 0) {
|
|
9
|
+
const rem = num % Base62.BASE;
|
|
10
|
+
result = Base62.ALPHABET[rem] + result;
|
|
11
|
+
num = Math.floor(num / Base62.BASE);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static fromString(str: string) {
|
|
17
|
+
let result = 0;
|
|
18
|
+
for (let i = 0; i < str.length; i++) {
|
|
19
|
+
result = result * Base62.BASE + Base62.ALPHABET.indexOf(str[i]);
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/lib/index.ts
CHANGED