@lynx-js/web-elements 0.11.3 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @lynx-js/web-elements
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - feat: add `willchange` event to `x-viewpager-ng` ([#2305](https://github.com/lynx-family/lynx-stack/pull/2305))
8
+
9
+ ### Patch Changes
10
+
11
+ - fix: firefox `@supports(width:1rex)` ([#2288](https://github.com/lynx-family/lynx-stack/pull/2288))
12
+
13
+ - fix: check computed overflow style in `getTheMostScrollableKid` to avoid treating `overflow: visible` elements as scroll containers ([#2309](https://github.com/lynx-family/lynx-stack/pull/2309))
14
+
15
+ - fix: the inline-truncation should only work as a direct child of x-text ([#2287](https://github.com/lynx-family/lynx-stack/pull/2287))
16
+
17
+ - fix: getVisibleCells cannot work in firefox due to contentvisibilityautostatechange not propagate list-item ([#2308](https://github.com/lynx-family/lynx-stack/pull/2308))
18
+
19
+ - fix: foldview stuck issue ([#2304](https://github.com/lynx-family/lynx-stack/pull/2304))
20
+
3
21
  ## 0.11.3
4
22
 
5
23
  ### Patch Changes
@@ -25,9 +25,27 @@ export class XFoldviewSlotNgTouchEventsHandler {
25
25
  passive: false,
26
26
  });
27
27
  }
28
+ #isScrollContainer(element) {
29
+ let overflowY;
30
+ if (typeof element.computedStyleMap === 'function') {
31
+ try {
32
+ overflowY = element.computedStyleMap().get('overflow-y')?.toString()
33
+ ?? 'visible';
34
+ }
35
+ catch {
36
+ overflowY = getComputedStyle(element).overflowY || 'visible';
37
+ }
38
+ }
39
+ else {
40
+ overflowY = getComputedStyle(element).overflowY || 'visible';
41
+ }
42
+ return overflowY === 'auto' || overflowY === 'scroll'
43
+ || overflowY === 'hidden' || overflowY === 'overlay';
44
+ }
28
45
  #getTheMostScrollableKid(delta) {
29
46
  const scrollableKid = this.#elements?.find((element) => {
30
- if (element.scrollHeight > element.clientHeight) {
47
+ if (this.#isScrollContainer(element)
48
+ && element.scrollHeight > element.clientHeight) {
31
49
  const couldScrollNear = delta < 0
32
50
  && element.scrollTop !== 0;
33
51
  const couldScrollFar = delta > 0
@@ -74,7 +92,8 @@ export class XFoldviewSlotNgTouchEventsHandler {
74
92
  if (Math.abs(event.deltaY) <= Math.abs(event.deltaX)) {
75
93
  return;
76
94
  }
77
- const pathElements = event.composedPath().filter((element) => element instanceof Element && this.#dom.contains(element));
95
+ const pathElements = event.composedPath().filter((element) => element instanceof Element && this.#dom.contains(element)
96
+ && element !== this.#dom);
78
97
  const { clientX, clientY } = event;
79
98
  const pointElements = document.elementsFromPoint(clientX, clientY).filter(e => this.#dom.contains(e));
80
99
  this.#elements = [...new Set([...pathElements, ...pointElements])];
@@ -97,7 +116,7 @@ export class XFoldviewSlotNgTouchEventsHandler {
97
116
  }
98
117
  #touchStart = (event) => {
99
118
  const { pageX, pageY } = event.touches.item(0);
100
- this.#elements = document.elementsFromPoint(pageX, pageY).filter(e => this.#dom.contains(e));
119
+ this.#elements = document.elementsFromPoint(pageX, pageY).filter(e => this.#dom.contains(e) && e !== this.#dom);
101
120
  this.#previousPageY = pageY;
102
121
  this.#previousPageX = pageX;
103
122
  this.#parentScrollTop = this.#getParentElement()?.scrollTop ?? 0;
@@ -174,11 +174,22 @@ let XList = (() => {
174
174
  };
175
175
  }
176
176
  getVisibleCells = () => {
177
- const cells = Object.values(this.#cellsMap);
178
- const children = Array.from(this.children).filter(node => {
177
+ let cells = Object.values(this.#cellsMap);
178
+ const children = Array.from(this.children).filter((node) => {
179
179
  return node.tagName === 'LIST-ITEM';
180
180
  });
181
- return cells.map(cell => {
181
+ // firfox cannot triiger contentvisibilityautostatechange event of list-item
182
+ if (cells.length === 0) {
183
+ const listRect = this.#getListContainer().getBoundingClientRect();
184
+ cells = children.filter((cell) => {
185
+ const rect = cell.getBoundingClientRect();
186
+ return (rect.bottom >= listRect.top
187
+ && rect.top <= listRect.bottom
188
+ && rect.right >= listRect.left
189
+ && rect.left <= listRect.right);
190
+ });
191
+ }
192
+ return cells.map((cell) => {
182
193
  const rect = cell.getBoundingClientRect();
183
194
  return {
184
195
  id: cell.getAttribute('id'),
@@ -21,7 +21,7 @@ let InlineTruncation = (() => {
21
21
  }
22
22
  static XEnableCustomTruncation = 'x-text-custom-overflow';
23
23
  connectedCallback() {
24
- if (!CSS.supports('selector(:has(inline-truncation))')) {
24
+ if (!CSS.supports('selector(:has(>inline-truncation))')) {
25
25
  if (this.parentElement?.tagName === 'X-TEXT'
26
26
  && !this.matches('inline-truncation ~ inline-truncation')) {
27
27
  this.parentElement.setAttribute(InlineTruncation.XEnableCustomTruncation, '');
@@ -45,16 +45,10 @@ let XTextTruncation = (() => {
45
45
  return !this.#hasInlineTruncation && !this.#tailColorConvert;
46
46
  }
47
47
  get #hasInlineTruncation() {
48
- if (CSS.supports('selector(:has(inline-truncation))')) {
49
- return this.#dom.matches(':has(inline-truncation)');
50
- }
51
- else {
52
- const candidateElement = this.#dom.querySelector('inline-truncation');
53
- if (candidateElement?.parentElement === this.#dom) {
54
- return true;
55
- }
56
- }
57
- return false;
48
+ return !!this.#findValidInlineTruncation();
49
+ }
50
+ #findValidInlineTruncation() {
51
+ return this.#dom.querySelector(':scope > inline-truncation');
58
52
  }
59
53
  get #doExpensiveLineLayoutCalculation() {
60
54
  return (!isNaN(this.#maxLine)
@@ -139,7 +133,7 @@ let XTextTruncation = (() => {
139
133
  const currentLineText = end - start;
140
134
  if (this.#hasInlineTruncation) {
141
135
  this.#dom.setAttribute(XTextTruncation.showInlineTruncation, '');
142
- const inlineTruncation = this.#dom.querySelector('inline-truncation');
136
+ const inlineTruncation = this.#findValidInlineTruncation();
143
137
  const inlineTruncationBoundingRect = inlineTruncation
144
138
  .getBoundingClientRect();
145
139
  const parentWidth = parentBondingRect.width;
@@ -5,6 +5,7 @@ export declare class XViewpagerNgEvents implements InstanceType<AttributeReactiv
5
5
  static observedAttributes: never[];
6
6
  constructor(dom: XViewpagerNg);
7
7
  _enableChangeEvent(status: boolean): void;
8
+ _enableWillChangeEvent(status: boolean): void;
8
9
  _enableOffsetChangeEvent(status: boolean): void;
9
10
  connectedCallback(): void;
10
11
  dispose(): void;
@@ -11,13 +11,16 @@ import { registerEventEnableStatusChangeHandler } from '../../element-reactive/i
11
11
  let XViewpagerNgEvents = (() => {
12
12
  let _instanceExtraInitializers = [];
13
13
  let __enableChangeEvent_decorators;
14
+ let __enableWillChangeEvent_decorators;
14
15
  let __enableOffsetChangeEvent_decorators;
15
16
  return class XViewpagerNgEvents {
16
17
  static {
17
18
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
18
19
  __enableChangeEvent_decorators = [registerEventEnableStatusChangeHandler('change')];
20
+ __enableWillChangeEvent_decorators = [registerEventEnableStatusChangeHandler('willchange')];
19
21
  __enableOffsetChangeEvent_decorators = [registerEventEnableStatusChangeHandler('offsetchange')];
20
22
  __esDecorate(this, null, __enableChangeEvent_decorators, { kind: "method", name: "_enableChangeEvent", static: false, private: false, access: { has: obj => "_enableChangeEvent" in obj, get: obj => obj._enableChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
23
+ __esDecorate(this, null, __enableWillChangeEvent_decorators, { kind: "method", name: "_enableWillChangeEvent", static: false, private: false, access: { has: obj => "_enableWillChangeEvent" in obj, get: obj => obj._enableWillChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
21
24
  __esDecorate(this, null, __enableOffsetChangeEvent_decorators, { kind: "method", name: "_enableOffsetChangeEvent", static: false, private: false, access: { has: obj => "_enableOffsetChangeEvent" in obj, get: obj => obj._enableOffsetChangeEvent }, metadata: _metadata }, null, _instanceExtraInitializers);
22
25
  if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
23
26
  }
@@ -70,12 +73,29 @@ let XViewpagerNgEvents = (() => {
70
73
  };
71
74
  #touchEndHandler = () => {
72
75
  this.#isDragging = false;
76
+ if (this.#enableWillChange) {
77
+ const scrollContainer = this.#getScrollContainer();
78
+ const oneItemWidth = this.#dom.clientWidth;
79
+ if (oneItemWidth > 0) {
80
+ const scrollLeft = scrollContainer.scrollLeft;
81
+ let targetIndex = Math.round(scrollLeft / oneItemWidth);
82
+ targetIndex = Math.max(0, Math.min(targetIndex, this.#dom.children.length - 1));
83
+ this.#dom.dispatchEvent(new CustomEvent('willchange', {
84
+ ...commonComponentEventSetting,
85
+ detail: { index: targetIndex },
86
+ }));
87
+ }
88
+ }
73
89
  };
74
90
  #enableChange = false;
75
91
  _enableChangeEvent(status) {
76
92
  this.#enableChange = status;
77
93
  this.#enableScrollEventListener();
78
94
  }
95
+ #enableWillChange = false;
96
+ _enableWillChangeEvent(status) {
97
+ this.#enableWillChange = status;
98
+ }
79
99
  #enableOffsetChange = false;
80
100
  _enableOffsetChangeEvent(status) {
81
101
  this.#enableOffsetChange = status;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/web-elements",
3
- "version": "0.11.3",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  */
27
27
  @supports not
28
28
  ((content-visibility: auto) and (transition-behavior: allow-discrete) and
29
- (width: 1rex)) {
29
+ (-webkit-box-reflect: above)) {
30
30
  * {
31
31
  --lynx-display: linear;
32
32
  --lynx-linear-weight-sum: 1;
@@ -47,6 +47,7 @@
47
47
  --flex-wrap: nowrap;
48
48
  --align-self: auto;
49
49
  }
50
+
50
51
  [lynx-computed-display="linear"] {
51
52
  flex-wrap: nowrap !important;
52
53
  flex-direction: column;
@@ -61,11 +62,9 @@
61
62
 
62
63
  [lynx-computed-display="flex"] > *,
63
64
  [lynx-computed-display="flex"] > lynx-wrapper > * {
64
- flex: var(
65
- --flex,
66
- var(--flex-grow) var(--flex-shrink) var(--flex-basis)
67
- );
65
+ flex: var(--flex, var(--flex-grow) var(--flex-shrink) var(--flex-basis));
68
66
  }
67
+
69
68
  [lynx-computed-display="linear"] > *,
70
69
  [lynx-computed-display="linear"] > lynx-wrapper > * {
71
70
  flex-shrink: 0 !important;
@@ -111,6 +110,7 @@
111
110
  > * {
112
111
  align-self: var(--align-self-column);
113
112
  }
113
+
114
114
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal"] > *,
115
115
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal-reverse"],
116
116
  [lynx-computed-display="linear"][lynx-linear-orientation="horizontal"]
@@ -12,7 +12,8 @@ x-text {
12
12
  color: initial;
13
13
  }
14
14
 
15
- x-text > x-text, x-text > lynx-wrapper > x-text {
15
+ x-text > x-text,
16
+ x-text > lynx-wrapper > x-text {
16
17
  color: inherit;
17
18
  }
18
19
 
@@ -33,11 +34,17 @@ x-text > x-text::part(inner-box),
33
34
  x-text > lynx-wrapper > x-text::part(inner-box) {
34
35
  display: contents !important;
35
36
  }
36
- x-text::part(inner-box), inline-text, x-text::part(slot) {
37
+
38
+ x-text::part(inner-box),
39
+ inline-text,
40
+ x-text::part(slot) {
37
41
  background-clip: inherit;
38
42
  -webkit-background-clip: inherit;
39
43
  }
40
- inline-text, inline-image, inline-truncation {
44
+
45
+ inline-text,
46
+ inline-image,
47
+ inline-truncation {
41
48
  display: none;
42
49
  }
43
50
 
@@ -73,15 +80,19 @@ inline-text > lynx-wrapper > inline-image,
73
80
  inline-text > lynx-wrapper > x-image {
74
81
  display: contents !important;
75
82
  }
76
- x-text > x-view, x-text > lynx-wrapper > x-view {
83
+
84
+ x-text > x-view,
85
+ x-text > lynx-wrapper > x-view {
77
86
  display: inline-flex !important;
78
87
  }
88
+
79
89
  x-text > x-view,
80
90
  x-text[x-show-inline-truncation] > inline-truncation,
81
91
  x-text > lynx-wrapper > x-view,
82
92
  x-text[x-show-inline-truncation] > lynx-wrapper > inline-truncation {
83
93
  display: inline-flex;
84
94
  }
95
+
85
96
  x-text > inline-truncation:first-child,
86
97
  x-text > lynx-wrapper > inline-truncation:first-child {
87
98
  max-width: 100%;
@@ -125,7 +136,10 @@ inline-truncation > lynx-wrapper > x-image::part(img) {
125
136
 
126
137
  /* attribute text-selection */
127
138
 
128
- x-text, inline-text, inline-image, inline-truncation {
139
+ x-text,
140
+ inline-text,
141
+ inline-image,
142
+ inline-truncation {
129
143
  -webkit-user-select: none;
130
144
  user-select: none;
131
145
  }
@@ -154,6 +168,7 @@ x-text[text-selection] > lynx-wrapper > inline-truncation {
154
168
  -webkit-user-select: auto;
155
169
  user-select: auto;
156
170
  }
171
+
157
172
  x-text[x-text-clipped] > [x-text-clipped]:not(inline-truncation),
158
173
  x-text[x-text-clipped]
159
174
  > lynx-wrapper
@@ -166,9 +181,9 @@ x-text[x-text-clipped]:not([tail-color-convert="false"])::part(inner-box)::after
166
181
  content: "...";
167
182
  }
168
183
 
169
- x-text[x-text-clipped]:has(inline-truncation)::part(inner-box):after,
184
+ x-text[x-text-clipped]:has(> inline-truncation)::part(inner-box):after,
170
185
  x-text[x-text-clipped][x-text-custom-overflow]::part(inner-box):after,
171
- x-text[x-text-clipped]:has(inline-truncation)::part(inner-box)::after,
186
+ x-text[x-text-clipped]:has(> inline-truncation)::part(inner-box)::after,
172
187
  x-text[x-text-clipped][x-text-custom-overflow]::part(inner-box)::after {
173
188
  content: "" !important;
174
189
  }
@@ -198,41 +213,45 @@ x-text[text-maxline="0"] {
198
213
  display: none;
199
214
  }
200
215
 
201
- @supports not selector(:has(inline-truncation)) {
216
+ @supports not selector(:has(> inline-truncation)) {
202
217
  x-text[text-maxline="1"]:not([tail-color-convert="false"]):not([x-text-custom-overflow])::part(inner-box) {
203
218
  white-space: nowrap;
204
219
  text-overflow: ellipsis;
205
220
  }
206
221
  }
207
222
 
208
- @supports selector(:has(inline-truncation)) {
223
+ @supports selector(:has(> inline-truncation)) {
209
224
  /* text-wrap chrome 114, firefox 121, safari 17.4*/
210
- x-text[text-maxline="1"]:not([tail-color-convert="false"], :has(inline-truncation))::part(inner-box) {
225
+ x-text[text-maxline="1"]:not([tail-color-convert="false"], :has(> inline-truncation))::part(inner-box) {
211
226
  text-wrap: nowrap;
212
227
  white-space: nowrap;
213
228
  text-overflow: ellipsis;
214
229
  }
215
230
  }
231
+
216
232
  x-text[text-maxline="1"] {
217
233
  /* This is the stretch size */
218
234
  /* https://developer.mozilla.org/en-US/docs/Web/CSS/max-width */
219
235
  max-width: -moz-available;
220
236
  max-width: -webkit-fill-available;
221
237
  }
238
+
222
239
  x-text[text-maxline="1"]:not([tail-color-convert="false"])::part(inner-box) {
223
240
  display: block;
224
241
  }
225
242
 
226
243
  x-text[text-maxline][x-text-custom-overflow]::part(inner-box),
227
- x-text[text-maxline]:has(inline-truncation)::part(inner-box),
244
+ x-text[text-maxline]:has(> inline-truncation)::part(inner-box),
228
245
  x-text[text-maxline][tail-color-convert="false"]::part(inner-box) {
229
246
  display: block !important;
230
247
  }
231
248
 
232
249
  raw-text {
233
- display: none; /* raw-text only works in x-text */
250
+ display: none;
251
+ /* raw-text only works in x-text */
234
252
  white-space-collapse: preserve-breaks;
235
253
  }
254
+
236
255
  x-text > raw-text,
237
256
  inline-text > raw-text,
238
257
  x-text > lynx-wrapper > raw-text,
@@ -7,51 +7,61 @@
7
7
  inherits: false;
8
8
  initial-value: linear;
9
9
  }
10
+
10
11
  @property --lynx-linear-weight-sum {
11
12
  syntax: "<number>";
12
13
  inherits: false;
13
14
  initial-value: 1;
14
15
  }
16
+
15
17
  @property --lynx-linear-weight {
16
18
  syntax: "<number>";
17
19
  inherits: false;
18
20
  initial-value: 0;
19
21
  }
22
+
20
23
  @property --justify-content-column {
21
24
  syntax: "flex-start|flex-end|center|space-between|space-around";
22
25
  inherits: false;
23
26
  initial-value: flex-start;
24
27
  }
28
+
25
29
  @property --justify-content-column-reverse {
26
30
  syntax: "flex-start|flex-end|center|space-between|space-around";
27
31
  inherits: false;
28
32
  initial-value: flex-start;
29
33
  }
34
+
30
35
  @property --justify-content-row {
31
36
  syntax: "flex-start|flex-end|center|space-between|space-around";
32
37
  inherits: false;
33
38
  initial-value: flex-start;
34
39
  }
40
+
35
41
  @property --justify-content-row-reverse {
36
42
  syntax: "flex-start|flex-end|center|space-between|space-around";
37
43
  inherits: false;
38
44
  initial-value: flex-start;
39
45
  }
46
+
40
47
  @property --align-self-row {
41
48
  syntax: "start|end|center|stretch|auto";
42
49
  inherits: false;
43
50
  initial-value: auto;
44
51
  }
52
+
45
53
  @property --align-self-column {
46
54
  syntax: "start|end|center|stretch|auto";
47
55
  inherits: false;
48
56
  initial-value: auto;
49
57
  }
58
+
50
59
  @property --lynx-linear-weight-basis {
51
60
  syntax: "auto|<number>|<length>";
52
61
  inherits: false;
53
62
  initial-value: auto;
54
63
  }
64
+
55
65
  @property --lynx-linear-orientation {
56
66
  syntax: "<custom-ident>";
57
67
  inherits: false;
@@ -62,29 +72,35 @@
62
72
  syntax: "*";
63
73
  inherits: false;
64
74
  }
75
+
65
76
  @property --flex-wrap {
66
77
  syntax: "*";
67
78
  inherits: false;
68
79
  }
80
+
69
81
  @property --flex-grow {
70
82
  syntax: "<number>";
71
83
  inherits: false;
72
84
  initial-value: 0;
73
85
  }
86
+
74
87
  @property --flex-shrink {
75
88
  syntax: "<number>";
76
89
  inherits: false;
77
90
  initial-value: 1;
78
91
  }
92
+
79
93
  @property --flex-basis {
80
94
  syntax: "*";
81
95
  inherits: false;
82
96
  initial-value: auto;
83
97
  }
98
+
84
99
  @property --flex-value {
85
100
  syntax: "*";
86
101
  inherits: false;
87
102
  }
103
+
88
104
  @property --flex {
89
105
  syntax: "*";
90
106
  inherits: false;
@@ -189,6 +205,7 @@ list-item {
189
205
  var(--justify-content-column-reverse)
190
206
  );
191
207
  }
208
+
192
209
  x-view,
193
210
  x-foldview-header-ng,
194
211
  x-foldview-ng,
@@ -203,15 +220,9 @@ x-viewpager-item-ng,
203
220
  x-viewpager-ng,
204
221
  list-item {
205
222
  flex-wrap: var(--lynx-display-linear, nowrap)
206
- var(
207
- --lynx-display-flex,
208
- var(--flex-wrap)
209
- );
223
+ var(--lynx-display-flex, var(--flex-wrap));
210
224
  flex-direction: var(--lynx-display-linear, var(--linear-flex-direction))
211
- var(
212
- --lynx-display-flex,
213
- var(--flex-direction)
214
- );
225
+ var(--lynx-display-flex, var(--flex-direction));
215
226
  justify-content: var(--lynx-display-linear, var(--linear-justify-content));
216
227
  }
217
228
 
@@ -250,8 +261,8 @@ list-item {
250
261
  * it fixed in 116.0.5806.0, detail: https://issues.chromium.org/issues/40270007
251
262
  *
252
263
  * so we limit this feature to chrome 117, safari 18, firefox no:
253
- * rex unit: chrome 111, safari 17.2, firefox no
254
- * https://developer.mozilla.org/en-US/docs/Web/CSS/length
264
+ * -webkit-box-reflect: chrome 4, safari 4, firefox no
265
+ * https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/-webkit-box-reflect
255
266
  * transition-behavior:allow-discrete: chrome 117, safari 18, firefox 125
256
267
  * https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior
257
268
  * https://caniuse.com/mdn-css_properties_display_is_transitionable
@@ -260,7 +271,7 @@ list-item {
260
271
  *
261
272
  */
262
273
  @supports (content-visibility: auto) and
263
- (transition-behavior: allow-discrete) and (width: 1rex) {
274
+ (transition-behavior: allow-discrete) and (-webkit-box-reflect: above) {
264
275
  @container style(--lynx-display: linear) {
265
276
  x-view,
266
277
  x-blur-view,
@@ -333,10 +344,7 @@ list-item {
333
344
  x-textarea,
334
345
  x-list,
335
346
  list-item {
336
- flex: var(
337
- --flex,
338
- var(--flex-grow) var(--flex-shrink) var(--flex-basis)
339
- );
347
+ flex: var(--flex, var(--flex-grow) var(--flex-shrink) var(--flex-basis));
340
348
  }
341
349
  }
342
350