lupine.components 1.0.5 → 1.0.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lupine.components",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "license": "MIT",
5
5
  "author": "uuware.com",
6
6
  "homepage": "https://uuware.com/",
@@ -33,8 +33,5 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "lupine.web": "^1.0.0"
36
- },
37
- "devDependencies": {
38
- "@types/node": "^22.10.5"
39
36
  }
40
37
  }
@@ -1,4 +1,4 @@
1
- import { CssProps, RefProps } from '../jsx';
1
+ import { CssProps, RefProps } from 'lupine.web';
2
2
  import { Spinner02, SpinnerSize } from './spinner';
3
3
 
4
4
  export type DragRefreshCloseProps = () => void;
@@ -1,4 +1,4 @@
1
- import { CssProps, RefProps } from '../jsx';
1
+ import { CssProps, RefProps } from 'lupine.web';
2
2
 
3
3
  export type EditableLabelHookProps = {
4
4
  updateValue?: (value: string) => void;
@@ -1,6 +1,7 @@
1
1
  import { RefProps, VNode, mountComponents } from 'lupine.web';
2
2
 
3
- export const HtmlVar = (initial?: string | VNode<any>) => {
3
+ export type HtmlVarResult = { value: string | VNode<any>; ref: RefProps; node: VNode<any> };
4
+ export const HtmlVar = (initial?: string | VNode<any>): HtmlVarResult => {
4
5
  let _value: string | VNode<any> = initial || '';
5
6
  let _dirty = false;
6
7
  const waitUpdate = async (value: string | VNode<any>) => {
@@ -11,10 +12,12 @@ export const HtmlVar = (initial?: string | VNode<any>) => {
11
12
  ref.current.innerHTML = value;
12
13
  }
13
14
  _dirty = false;
14
- }
15
- const ref: RefProps = { onLoad: async (el: Element) => {
16
- _dirty && waitUpdate(_value);
17
- } };
15
+ };
16
+ const ref: RefProps = {
17
+ onLoad: async (el: Element) => {
18
+ _dirty && waitUpdate(_value);
19
+ },
20
+ };
18
21
  const FragmentRef = (props: any) => {
19
22
  return <>{props.children}</>;
20
23
  };
@@ -1,4 +1,4 @@
1
- import { CssProps } from '../jsx';
1
+ import { CssProps } from 'lupine.web';
2
2
 
3
3
  export type PanelProps = {
4
4
  children: any;
@@ -1,4 +1,4 @@
1
- import { RefProps } from '../jsx';
1
+ import { RefProps } from 'lupine.web';
2
2
  import { HtmlVar } from './html-var';
3
3
 
4
4
  export type ProgressHookProps = {
@@ -1,4 +1,4 @@
1
- import { RefProps } from '../jsx';
1
+ import { RefProps } from 'lupine.web';
2
2
 
3
3
  export type RedirectProps = {
4
4
  title?: string;
@@ -1,4 +1,4 @@
1
- import { CssProps } from '../jsx';
1
+ import { CssProps } from 'lupine.web';
2
2
 
3
3
  export type SelectOptionProps = {
4
4
  option: string;
@@ -1,4 +1,4 @@
1
- import { CssProps } from '../jsx';
1
+ import { CssProps } from 'lupine.web';
2
2
 
3
3
  export type TextGlowProps = {
4
4
  text: string;
@@ -1,4 +1,4 @@
1
- import { CssProps } from "../jsx";
1
+ import { CssProps } from "lupine.web";
2
2
 
3
3
  export type TextLoadingProps = {
4
4
  text: string;
@@ -0,0 +1,118 @@
1
+ /*
2
+ const moveFn = createDragUtil();
3
+ moveFn.setOnMoveCallback((clientX: number, clientY: number, movedX: number, movedY: number) => {
4
+ const dragDom = moveFn.getDraggingDom();
5
+ if (dragDom?.classList.contains('xxx')) {
6
+ updateRangeMMove(clientX, true, dragDom, _saved.stopDoms);
7
+ } else if (dragDom?.classList.contains('yyy')) {
8
+ updatePicMMove(clientX);
9
+ }
10
+ });
11
+ <div
12
+ onMouseMove={moveFn.onMouseMove}
13
+ onMouseUp={moveFn.onMouseUp}
14
+ onTouchMove={moveFn.onTouchMove}
15
+ onTouchEnd={moveFn.onTouchEnd}
16
+ >
17
+ <div onMouseDown={moveFn.onMouseDown} onTouchStart={moveFn.onTouchStart}></div>
18
+ </div>
19
+
20
+ // when zooming an image, the way to scale slowly
21
+ const slowDelta = 1 + (scale - 1) * 0.2;
22
+ tempScale = lastScale * slowDelta;
23
+ */
24
+ export const createDragUtil = () => {
25
+ let isDragging = false;
26
+ let initialX = 0;
27
+ let initialY = 0;
28
+ let draggingDom: HTMLDivElement | null = null;
29
+ let onMoveCallback: (clientX: number, clientY: number, movedX: number, movedY: number) => void = () => {};
30
+ let onScaleCallback: (scale: number) => void = () => {};
31
+
32
+ let isZooming = false;
33
+ let initialDistance = 0;
34
+
35
+ const getDistance = (t1: Touch, t2: Touch) => {
36
+ const dx = t2.clientX - t1.clientX;
37
+ const dy = t2.clientY - t1.clientY;
38
+ return Math.sqrt(dx * dx + dy * dy);
39
+ };
40
+ return {
41
+ setOnMoveCallback: (callback: (clientX: number, clientY: number, movedX: number, movedY: number) => void) => {
42
+ onMoveCallback = callback;
43
+ },
44
+ setOnScaleCallback: (callback: (scale: number) => void) => {
45
+ onScaleCallback = callback;
46
+ },
47
+ getDistance,
48
+ getDraggingDom: () => draggingDom,
49
+ onMouseDown: (event: MouseEvent) => {
50
+ event.preventDefault();
51
+ if (event.buttons !== 1) {
52
+ isDragging = false;
53
+ draggingDom = null;
54
+ return;
55
+ }
56
+ isDragging = true;
57
+ draggingDom = event.currentTarget as HTMLDivElement;
58
+ initialX = event.clientX;
59
+ initialY = event.clientY;
60
+ },
61
+ onMouseMove: (event: MouseEvent) => {
62
+ if (event.buttons === 0 || !draggingDom) {
63
+ isDragging = false;
64
+ draggingDom = null;
65
+ return;
66
+ }
67
+ onMoveCallback(event.clientX, event.clientY, event.clientX - initialX, event.clientY - initialY);
68
+ },
69
+ onMouseUp: () => {
70
+ isDragging = false;
71
+ isZooming = false;
72
+ draggingDom = null;
73
+ },
74
+
75
+ onTouchStart: (event: TouchEvent) => {
76
+ if (event.touches.length === 1) {
77
+ isDragging = true;
78
+ draggingDom = event.currentTarget as HTMLDivElement;
79
+ initialX = event.touches[0].clientX;
80
+ initialY = event.touches[0].clientY;
81
+ } else if (event.touches.length === 2) {
82
+ initialDistance = getDistance(event.touches[0], event.touches[1]);
83
+ isZooming = true;
84
+ } else {
85
+ isDragging = false;
86
+ draggingDom = null;
87
+ }
88
+ },
89
+ onTouchMove: (event: TouchEvent) => {
90
+ if (isZooming) {
91
+ if (event.touches.length === 2) {
92
+ event.preventDefault(); // 防止页面滚动
93
+ const newDistance = getDistance(event.touches[0], event.touches[1]);
94
+ const delta = newDistance / initialDistance;
95
+ // const newScale = Math.min(Math.max(1, scale * delta), 4); // 限制缩放范围
96
+ onScaleCallback(delta);
97
+ return;
98
+ }
99
+ }
100
+ if (!isDragging || event.touches.length === 0 || !draggingDom) {
101
+ isDragging = false;
102
+ draggingDom = null;
103
+ return;
104
+ }
105
+ onMoveCallback(
106
+ event.touches[0].clientX,
107
+ event.touches[0].clientY,
108
+ event.touches[0].clientX - initialX,
109
+ event.touches[0].clientY - initialY
110
+ );
111
+ },
112
+ onTouchEnd: () => {
113
+ isDragging = false;
114
+ isZooming = false;
115
+ draggingDom = null;
116
+ },
117
+ };
118
+ };
package/src/lib/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './dom';
2
2
  export * from './date-utils';
3
3
  export * from './deep-merge';
4
4
  export * from './document-ready';
5
+ export * from './drag-util';
5
6
  export * from './dynamical-load';
6
7
  export * from './format-bytes';
7
8
  export * from './lite-dom';
@@ -1,3 +1,5 @@
1
+ import { getRenderPageProps } from "lupine.web";
2
+
1
3
  const _saveChunkSize = {
2
4
  size: 1024 * 500,
3
5
  };
@@ -8,10 +10,11 @@ export const getChunkSize = () => {
8
10
  return _saveChunkSize.size;
9
11
  };
10
12
  export const checkUploadedFileSize = async (uploadUrl: string) => {
11
- const response = await fetch(uploadUrl + '?check-size=1', {
12
- method: 'POST',
13
- });
14
- const json = await response.json();
13
+ // const response = await fetch(uploadUrl + '?check-size=1', {
14
+ // method: 'POST',
15
+ // });
16
+ // const json = await response.json();
17
+ const json = await getRenderPageProps().renderPageFunctions.fetchData(uploadUrl + '?check-size=1');
15
18
  return json && json.size ? json.size : 0;
16
19
  };
17
20
 
@@ -30,30 +33,33 @@ export const uploadFileChunk = async (
30
33
  if (key) {
31
34
  url += `&key=${key}`;
32
35
  }
33
- const response = await fetch(url, {
34
- method: 'POST',
35
- body: chunk,
36
- });
37
- const json = await response.json();
36
+ // const response = await fetch(url, {
37
+ // method: 'POST',
38
+ // body: chunk,
39
+ // });
40
+ // const json = await response.json();
41
+ console.log(`uploadFileChunk, ${uploadUrl}, index: ${chunkNumber}, total: ${totalChunks}, len: ${chunk.length}`);
42
+ const json = await getRenderPageProps().renderPageFunctions.fetchData(url, chunk);
38
43
  return json;
39
44
  };
40
45
 
41
46
  export const uploadFile = async (
42
- file: File,
47
+ file: File | string,
43
48
  uploadUrl: string,
44
49
  progressFn?: (percentage: number, chunkNumber: number, totalChunks: number) => void,
45
50
  chunkSize = _saveChunkSize.size
46
51
  ) => {
47
52
  // const uploadedSize = await checkUploadedFileSize(uploadUrl);
48
53
  let key = '';
49
- if (file.size <= chunkSize) {
54
+ const len = file instanceof File ? file.size : file.length;
55
+ if (len <= chunkSize) {
50
56
  return await uploadFileChunk(file, 0, 1, uploadUrl, key);
51
57
  }
52
58
 
53
- const totalChunks = Math.ceil(file.size / chunkSize);
59
+ const totalChunks = Math.ceil(len / chunkSize);
54
60
  for (let i = 0; i < totalChunks; i++) {
55
61
  const start = i * chunkSize;
56
- const end = Math.min((i + 1) * chunkSize, file.size);
62
+ const end = Math.min((i + 1) * chunkSize, len);
57
63
  const chunk = file.slice(start, end);
58
64
  const uploaded = await uploadFileChunk(chunk, i, totalChunks, uploadUrl, key);
59
65
  if (!uploaded || uploaded.chunkNumber === i.toString() || !uploaded.key) {
@@ -9,18 +9,20 @@ export const darkThemes: ThemeProps = {
9
9
  '--scrollbar-thumb-bg': '#373636',
10
10
  '--scrollbar-active-thumb-bg': '#5b5b5b',
11
11
 
12
- '--primary-color': '#aeaeae',
12
+ '--primary-color': '#e5e5e5',
13
13
  '--primary-color-disabled': '#7d7d7d',
14
14
  '--primary-bg-color': '#000000',
15
15
  '--primary-border-color': '#aeaeae',
16
16
  '--primary-border': '1px solid var(--primary-border-color)',
17
- // '--secondary-color': '#b3b3b3',
18
- // '--secondary-bg-color': '#151515',
19
- // '--secondary-border': '1px solid #303030',
20
17
  '--primary-opacity': '0.5', // used for dark theme
21
18
  '--primary-disabled-opacity': '0.7', // used for dark theme
22
19
  '--primary-accent-color': '#1a588a', // used for radio and checkbox's background color
23
20
 
21
+ '--secondary-color': '#747474',
22
+ '--secondary-bg-color': '#1c1c1c',
23
+ '--secondary-border-color': '#494949',
24
+ '--secondary-border': '1px solid var(--secondary-border-color)',
25
+
24
26
  // including menus, tabs
25
27
  '--activatable-color-normal': 'var(--primary-color)',
26
28
  '--activatable-bg-color-normal': 'var(--primary-bg-color)',
@@ -15,13 +15,15 @@ export const lightThemes: ThemeProps = {
15
15
  '--primary-bg-color': '#ffffff',
16
16
  '--primary-border-color': '#858585',
17
17
  '--primary-border': '1px solid var(--primary-border-color)',
18
- // '--secondary-color': '#505050',
19
- // '--secondary-bg-color': '#ffffff',
20
- // '--secondary-border': '1px solid #858585',
21
18
  '--primary-opacity': 'unset', // used for dark theme
22
19
  '--primary-disabled-opacity': '0.5', // used for dark theme
23
20
  '--primary-accent-color': '#0a74c9', // used for radio and checkbox's background color
24
21
 
22
+ '--secondary-color': '#818181',
23
+ '--secondary-bg-color': '#eeeeee',
24
+ '--secondary-border-color': '#a0a0a0',
25
+ '--secondary-border': '1px solid var(--secondary-border-color)',
26
+
25
27
  // including menus, tabs, sidebars
26
28
  '--activatable-color-normal': 'var(--primary-color)',
27
29
  '--activatable-bg-color-normal': 'var(--primary-bg-color)',