cdui-js 1.0.25 → 1.0.27

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,75 +1,75 @@
1
- .mobile-date-picker {
2
- display: flex;
3
- flex-direction: row;
4
- width: 100%;
5
- min-height: calc(44px * 5);
6
- position: relative;
7
- box-sizing: border-box;
8
- user-select: none;
9
- }
10
-
11
- .mobile-date-picker-column {
12
- flex: 1;
13
- position: relative;
14
- min-width: 0;
15
- }
16
-
17
- .mobile-date-picker-column::before {
18
- content: '';
19
- pointer-events: none;
20
- position: absolute;
21
- left: 0;
22
- right: 0;
23
- top: 0;
24
- bottom: 0;
25
- z-index: 1;
26
- background: linear-gradient(
27
- to bottom,
28
- rgba(255, 255, 255, 0.95) 0%,
29
- rgba(255, 255, 255, 0) calc(50% - 22px)
30
- ),
31
- linear-gradient(
32
- to top,
33
- rgba(255, 255, 255, 0.95) 0%,
34
- rgba(255, 255, 255, 0) calc(50% - 22px)
35
- );
36
- }
37
-
38
- .mobile-date-picker-column::after {
39
- content: '';
40
- pointer-events: none;
41
- position: absolute;
42
- left: 0;
43
- right: 0;
44
- top: 50%;
45
- transform: translateY(-50%);
46
- height: 44px;
47
- box-sizing: border-box;
48
- border-top: 1px solid #e4e4e4;
49
- border-bottom: 1px solid #e4e4e4;
50
- z-index: 2;
51
- }
52
-
53
- .mobile-date-picker-wheel {
54
- --mdp-item-h: 44px;
55
- height: calc(var(--mdp-item-h) * 5);
56
- overflow-y: auto;
57
- touch-action: pan-y;
58
- -webkit-overflow-scrolling: touch;
59
- }
60
-
61
- .mobile-date-picker-wheel-inner {
62
- position: relative;
63
- width: 100%;
64
- }
65
-
66
- .mobile-date-picker-item {
67
- position: absolute;
68
- left: 0;
69
- right: 0;
70
- height: var(--mdp-item-h);
71
- line-height: var(--mdp-item-h);
72
- text-align: center;
73
- font-size: 16px;
74
- color: #1b212d;
75
- }
1
+ .mobile-date-picker {
2
+ display: flex;
3
+ flex-direction: row;
4
+ width: 100%;
5
+ min-height: calc(44px * 5);
6
+ position: relative;
7
+ box-sizing: border-box;
8
+ user-select: none;
9
+ }
10
+
11
+ .mobile-date-picker-column {
12
+ flex: 1;
13
+ position: relative;
14
+ min-width: 0;
15
+ }
16
+
17
+ .mobile-date-picker-column::before {
18
+ content: '';
19
+ pointer-events: none;
20
+ position: absolute;
21
+ left: 0;
22
+ right: 0;
23
+ top: 0;
24
+ bottom: 0;
25
+ z-index: 1;
26
+ background: linear-gradient(
27
+ to bottom,
28
+ rgba(255, 255, 255, 0.95) 0%,
29
+ rgba(255, 255, 255, 0) calc(50% - 22px)
30
+ ),
31
+ linear-gradient(
32
+ to top,
33
+ rgba(255, 255, 255, 0.95) 0%,
34
+ rgba(255, 255, 255, 0) calc(50% - 22px)
35
+ );
36
+ }
37
+
38
+ .mobile-date-picker-column::after {
39
+ content: '';
40
+ pointer-events: none;
41
+ position: absolute;
42
+ left: 0;
43
+ right: 0;
44
+ top: 50%;
45
+ transform: translateY(-50%);
46
+ height: 44px;
47
+ box-sizing: border-box;
48
+ border-top: 1px solid #e4e4e4;
49
+ border-bottom: 1px solid #e4e4e4;
50
+ z-index: 2;
51
+ }
52
+
53
+ .mobile-date-picker-wheel {
54
+ --mdp-item-h: 44px;
55
+ height: calc(var(--mdp-item-h) * 5);
56
+ overflow-y: auto;
57
+ touch-action: pan-y;
58
+ -webkit-overflow-scrolling: touch;
59
+ }
60
+
61
+ .mobile-date-picker-wheel-inner {
62
+ position: relative;
63
+ width: 100%;
64
+ }
65
+
66
+ .mobile-date-picker-item {
67
+ position: absolute;
68
+ left: 0;
69
+ right: 0;
70
+ height: var(--mdp-item-h);
71
+ line-height: var(--mdp-item-h);
72
+ text-align: center;
73
+ font-size: 16px;
74
+ color: #1b212d;
75
+ }
package/demo/src/App.tsx CHANGED
@@ -1,3 +1,5 @@
1
+ import { onMount, reactive } from '../../src/reactive';
2
+ import { For } from '../../src/components/For';
1
3
  import { showPopup } from '../../src/popup';
2
4
  import { CanlendarPage } from './pages/Canlendar';
3
5
  import { CarouselPage } from './pages/Carousel';
@@ -5,21 +7,87 @@ import { ComboBoxPage } from './pages/ComboBox';
5
7
  import { DatePickerPage } from './pages/DatePicker';
6
8
  import { FormPage } from './pages/Form';
7
9
 
8
- let objects = [];
9
- for (let i = 0; i < 1000000; i++) {
10
- objects[i] = {};
11
- }
10
+ // 方法1: SolidJS 的直接引用
11
+ const getSolidStyle = (root) => {
12
+ const a = root.firstChild.firstChild.nextSibling.nextSibling;
13
+ const b = a.nextSibling.nextSibling.nextSibling;
14
+ return [a, b];
15
+ };
16
+
17
+ const enter = (node, count) => {
18
+ let child = node.firstChild;
19
+
20
+ while (--count) {
21
+ child = child.firstChild;
22
+ }
23
+
24
+ return child;
25
+ };
26
+
27
+ const next = (node, count) => {
28
+ node = node.nextSibling;
29
+
30
+ while (--count) {
31
+ node = node.nextSibling;
32
+ }
33
+
34
+ return node;
35
+ };
36
+
37
+ (Node.prototype as any).ENTER = function (count) {
38
+ let child = this.firstChild;
39
+
40
+ while (--count) {
41
+ child = child.firstChild;
42
+ }
43
+
44
+ return child;
45
+ };
46
+
47
+ const getChildren = (root) => {
48
+ const a = next(enter(root, 2), 2);
49
+ const b = next(a, 3);
50
+
51
+ return [a, b];
52
+ };
53
+
54
+ // 方法2: querySelectorAll
55
+ const getQueryStyle = (root) => {
56
+ return root.querySelectorAll('[dynamic]');
57
+ };
58
+
59
+ // 方法3: TreeWalker
60
+ const getWalkerStyle = (root) => {
61
+ const walker = document.createNodeIterator(root, NodeFilter.SHOW_COMMENT);
62
+ let node;
12
63
 
13
- let map = new WeakMap();
14
- let now = performance.now();
64
+ while ((node = walker.nextNode())) {
65
+ if (node.nodeType === 'dd') {
66
+ }
67
+ }
68
+ };
69
+
70
+ // 测试代码
71
+ const template = document.createElement('div');
72
+ template.innerHTML = `<div><span>Static</span><!><!-- dynamic1 --><span>Middle</span><!><!-- dynamic2 --></div>`;
15
73
 
16
- for (let i = 0; i < 1000000; i++) {
17
- map.set(objects[i], i);
18
- }
74
+ console.log(template);
75
+ const printTime = (name: string, fn: Function) => {
76
+ let now = performance.now();
19
77
 
20
- console.log(performance.now() - now);
78
+ for (let i = 0; i < 1000000; i++) {
79
+ fn();
80
+ }
81
+
82
+ console.log(name, performance.now() - now);
83
+ };
21
84
 
22
- const openDropdown = (align: HTMLElement) => {
85
+ printTime('solid', () => getSolidStyle(template));
86
+ printTime('children', () => getChildren(template));
87
+ printTime('querySelectorAll', () => getQueryStyle(template));
88
+ printTime('TreeWalker', () => getWalkerStyle(template));
89
+
90
+ const openPopup = (align: HTMLElement) => {
23
91
  const popup = showPopup(<div style={{ padding: '100px 0', background: 'silver' }}>11111111111111111111</div>, {
24
92
  align,
25
93
  transition: true,
@@ -27,13 +95,35 @@ const openDropdown = (align: HTMLElement) => {
27
95
  };
28
96
 
29
97
  export const App = () => {
98
+ let refButton: HTMLElement;
99
+ let ref;
100
+
101
+ let state = reactive([]);
102
+
103
+ onMount(() => {
104
+ let now = performance.now();
105
+ for (let i = 0; i < 10000; i++) {
106
+ let child = ref;
107
+
108
+ while ((child = child.nextSibling)) {}
109
+ }
110
+ console.log(performance.now() - now);
111
+ });
112
+
30
113
  return (
31
114
  <div style={{ 'min-height': '100%' }}>
32
- <CarouselPage></CarouselPage>
33
- <CanlendarPage></CanlendarPage>
115
+ <For each={state.value}>{(item) => <div>{item}</div>}</For>
116
+ <button ref={refButton as any} onclick={() => state.value.push(Math.random())}>
117
+ dropdown
118
+ </button>
119
+ <For each={state.value}>{(item) => <div>{item}</div>}</For>
120
+ <button onclick={() => state.value.push(Math.random())}>dropdown</button>
121
+
122
+ {/* <CarouselPage></CarouselPage> */}
123
+ {/* <CanlendarPage></CanlendarPage>
34
124
  <DatePickerPage></DatePickerPage>
35
125
  <ComboBoxPage></ComboBoxPage>
36
- <FormPage></FormPage>
126
+ <FormPage></FormPage> */}
37
127
  </div>
38
128
  );
39
129
  };
@@ -6,7 +6,7 @@ export const CanlendarPage = () => {
6
6
  return (
7
7
  <div>
8
8
  <Canlendar
9
- value={new Date()}
9
+ value="2026-04-04"
10
10
  onchange={(event) => {debugger
11
11
  console.log(event.detail);
12
12
  }}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdui-js",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -0,0 +1,2 @@
1
+ packages:
2
+ - 'packages/*'
@@ -21,8 +21,8 @@ export const Switch = (props: SwitchProps) => {
21
21
  let disposes = {};
22
22
 
23
23
  onCleanup(() => {
24
- for (let key in disposes) {
25
- disposes[key]();
24
+ for (let id in disposes) {
25
+ disposes[id]();
26
26
  }
27
27
 
28
28
  roots = disposes = null;
package/src/location.ts CHANGED
@@ -52,8 +52,10 @@ export const location: Location = reactive({
52
52
  query: {},
53
53
  paths: [],
54
54
  routeTo(url: string, scrollTo?: [number, number]) {
55
+ // 更新历史
55
56
  history.pushState(null, '', url || '');
56
- routeTo();
57
+ // 不能立即取 window.location.pathname,在夸克等浏览取不到最新值
58
+ updateURL(url || '');
57
59
 
58
60
  if (isBrowser && scrollTo) {
59
61
  window.scrollTo(scrollTo[0] | 0, scrollTo[1] | 0);
@@ -89,47 +91,56 @@ export const parseQuery = (search: string) => {
89
91
  /**
90
92
  * 更新地址
91
93
  *
92
- * @param path 路径
93
- * @param search 查询条件
94
- * @param hash hash
94
+ * @param url 当前 url
95
95
  */
96
- export const updateURL = (path: string, search?: string, hash?: string) => {
97
- location.url = path + (search || '') + (hash || '');
98
- location.hash = hash || '';
96
+ export const updateURL = (url: string) => {
97
+ if (location.url !== url || (url = '')) {
98
+ let path = url;
99
+ let search = '';
100
+ let hash = '';
101
+ let index;
102
+
103
+ if ((index = path.indexOf('#')) >= 0) {
104
+ hash = path.slice(index);
105
+ path = path.slice(0, index);
106
+ }
107
+
108
+ if ((index = path.indexOf('?')) >= 0) {
109
+ search = path.slice(index);
110
+ path = path.slice(0, index);
111
+ }
99
112
 
100
- if (location.path !== path || location.search !== search) {
101
113
  batch(() => {
114
+ location.url = url;
115
+ location.hash = hash;
102
116
  location.path = path;
103
117
  location.paths = path.match(/\/[^/]*/g) || [];
104
- location.search = search || '';
118
+ location.search = search;
105
119
  location.query = search ? parseQuery(search) : {};
106
120
  });
107
121
  }
108
122
  };
109
123
 
110
124
  // 浏览器环境
111
- const routeTo = isBrowser
112
- ? (() => {
113
- // 更新地址方法
114
- const routeTo = () => {
115
- let system = window.location;
116
-
117
- updateURL(system.pathname, system.search, system.hash);
118
- };
119
-
120
- // 立即更新
121
- routeTo();
122
-
123
- // 侦听地址变化
124
- window.addEventListener('popstate', () => routeTo(), true);
125
- // window.addEventListener(
126
- // 'hashchange',
127
- // () => {
128
- // location.hash = '';
129
- // },
130
- // true,
131
- // );
132
-
133
- return routeTo;
134
- })()
135
- : () => {};
125
+ if (isBrowser) {
126
+ (() => {
127
+ // 更新地址方法
128
+ const routeTo = () => {
129
+ let system = window.location;
130
+ updateURL(system.pathname + system.search + system.hash);
131
+ };
132
+
133
+ // 立即更新
134
+ routeTo();
135
+
136
+ // 侦听地址变化
137
+ window.addEventListener('popstate', () => routeTo(), true);
138
+ // window.addEventListener(
139
+ // 'hashchange',
140
+ // () => {
141
+ // location.hash = '';
142
+ // },
143
+ // true,
144
+ // );
145
+ })();
146
+ }