react-solidlike 2.2.2 → 2.2.4

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/README.en.md CHANGED
@@ -58,6 +58,27 @@ import { For } from "react-solidlike";
58
58
  <For each={items} fallback={<EmptyState />}>
59
59
  {(item, index) => <ListItem item={item} index={index} />}
60
60
  </For>
61
+
62
+ // With wrapper element
63
+ <For each={items} wrapper={<ul className="list" />}>
64
+ {(item) => <li>{item.name}</li>}
65
+ </For>
66
+
67
+ // Reverse rendering
68
+ <For each={messages} reverse>
69
+ {(msg) => <Message {...msg} />}
70
+ </For>
71
+
72
+ // Using array parameter for context
73
+ <For each={steps}>
74
+ {(step, index, array) => (
75
+ <Step
76
+ data={step}
77
+ isFirst={index === 0}
78
+ isLast={index === array.length - 1}
79
+ />
80
+ )}
81
+ </For>
61
82
  ```
62
83
 
63
84
  ### `<Switch>` / `<Match>` / `<Default>` - Multi-branch Rendering
@@ -126,6 +147,23 @@ import { Repeat } from "react-solidlike";
126
147
  <Repeat times={3}>
127
148
  {(i) => <SkeletonCard key={i} />}
128
149
  </Repeat>
150
+
151
+ // With wrapper element
152
+ <Repeat times={5} wrapper={<div className="stars" />}>
153
+ {(i) => <Star key={i} />}
154
+ </Repeat>
155
+
156
+ // Reverse rendering
157
+ <Repeat times={5} reverse>
158
+ {(i) => <div key={i}>Reversed {i}</div>}
159
+ </Repeat>
160
+
161
+ // Using length parameter for progress
162
+ <Repeat times={totalSteps}>
163
+ {(i, length) => (
164
+ <Step key={i} current={i + 1} total={length} />
165
+ )}
166
+ </Repeat>
129
167
  ```
130
168
 
131
169
  ### `<Dynamic>` - Dynamic Component
package/README.md CHANGED
@@ -58,6 +58,27 @@ import { For } from "react-solidlike";
58
58
  <For each={items} fallback={<EmptyState />}>
59
59
  {(item, index) => <ListItem item={item} index={index} />}
60
60
  </For>
61
+
62
+ // 使用 wrapper 包装元素
63
+ <For each={items} wrapper={<ul className="list" />}>
64
+ {(item) => <li>{item.name}</li>}
65
+ </For>
66
+
67
+ // 倒序渲染
68
+ <For each={messages} reverse>
69
+ {(msg) => <Message {...msg} />}
70
+ </For>
71
+
72
+ // 使用 array 参数获取上下文信息
73
+ <For each={steps}>
74
+ {(step, index, array) => (
75
+ <Step
76
+ data={step}
77
+ isFirst={index === 0}
78
+ isLast={index === array.length - 1}
79
+ />
80
+ )}
81
+ </For>
61
82
  ```
62
83
 
63
84
  ### `<Switch>` / `<Match>` / `<Default>` - 多分支渲染
@@ -126,6 +147,23 @@ import { Repeat } from "react-solidlike";
126
147
  <Repeat times={3}>
127
148
  {(i) => <SkeletonCard key={i} />}
128
149
  </Repeat>
150
+
151
+ // 使用 wrapper 包装元素
152
+ <Repeat times={5} wrapper={<div className="stars" />}>
153
+ {(i) => <Star key={i} />}
154
+ </Repeat>
155
+
156
+ // 倒序渲染
157
+ <Repeat times={5} reverse>
158
+ {(i) => <div key={i}>倒序 {i}</div>}
159
+ </Repeat>
160
+
161
+ // 使用 length 参数显示进度
162
+ <Repeat times={totalSteps}>
163
+ {(i, length) => (
164
+ <Step key={i} current={i + 1} total={length} />
165
+ )}
166
+ </Repeat>
129
167
  ```
130
168
 
131
169
  ### `<Dynamic>` - 动态组件
package/dist/For.d.ts CHANGED
@@ -1,13 +1,17 @@
1
- import { type Key, type ReactNode } from "react";
1
+ import { type Key, type ReactElement, type ReactNode } from "react";
2
2
  export interface ForProps<T> {
3
3
  /** Array to iterate over | 要遍历的数组 */
4
4
  each: T[] | readonly T[] | null | undefined;
5
- /** Render function for each element | 渲染每个元素的函数 */
6
- children: (item: T, index: number) => ReactNode;
5
+ /** Render function for each element, receives item, index and original array | 渲染每个元素的函数,接收元素、索引和原数组 */
6
+ children: (item: T, index: number, array: T[] | readonly T[]) => ReactNode;
7
7
  /** Function to extract key from element, defaults to index | 从元素中提取 key 的函数,默认使用索引 */
8
8
  keyExtractor?: (item: T, index: number) => Key;
9
9
  /** Fallback content when array is empty | 数组为空时渲染的备选内容 */
10
10
  fallback?: ReactNode;
11
+ /** Wrapper element for all rendered elements | 包装所有渲染元素的元素 */
12
+ wrapper?: ReactElement;
13
+ /** Reverse the rendering order | 倒序渲染 */
14
+ reverse?: boolean;
11
15
  }
12
16
  /**
13
17
  * List rendering component, replaces array.map() in JSX
@@ -31,5 +35,11 @@ export interface ForProps<T> {
31
35
  * <For each={items} fallback={<EmptyState />}>
32
36
  * {(item, index) => <ListItem key={item.id} item={item} index={index} />}
33
37
  * </For>
38
+ *
39
+ * @example
40
+ * // With wrapper element | 使用包装元素
41
+ * <For each={items} wrapper={<ul className="list" />}>
42
+ * {(item) => <li>{item.name}</li>}
43
+ * </For>
34
44
  */
35
- export declare function For<T>({ each, children, keyExtractor, fallback }: ForProps<T>): ReactNode;
45
+ export declare function For<T>({ each, children, keyExtractor, fallback, wrapper, reverse }: ForProps<T>): ReactNode;
package/dist/Repeat.d.ts CHANGED
@@ -1,9 +1,13 @@
1
- import { type ReactNode } from "react";
1
+ import { type ReactElement, type ReactNode } from "react";
2
2
  export interface RepeatProps {
3
3
  /** Number of times to repeat | 重复次数 */
4
4
  times: number;
5
- /** Render function, receives current index (starting from 0) | 渲染函数,接收当前索引(从 0 开始) */
6
- children: (index: number) => ReactNode;
5
+ /** Render function, receives current index and total length | 渲染函数,接收当前索引和总长度 */
6
+ children: (index: number, length: number) => ReactNode;
7
+ /** Wrapper element for all rendered elements | 包装所有渲染元素的元素 */
8
+ wrapper?: ReactElement;
9
+ /** Reverse the rendering order | 倒序渲染 */
10
+ reverse?: boolean;
7
11
  }
8
12
  /**
9
13
  * Repeat rendering component, replaces Array.from({ length: n }).map()
@@ -27,5 +31,11 @@ export interface RepeatProps {
27
31
  * <Repeat times={rating}>
28
32
  * {(i) => <FilledStar key={i} />}
29
33
  * </Repeat>
34
+ *
35
+ * @example
36
+ * // With wrapper element | 使用包装元素
37
+ * <Repeat times={5} wrapper={<div className="stars" />}>
38
+ * {(i) => <Star key={i} />}
39
+ * </Repeat>
30
40
  */
31
- export declare function Repeat({ times, children }: RepeatProps): ReactNode;
41
+ export declare function Repeat({ times, children, wrapper, reverse }: RepeatProps): ReactNode;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Children, Component, Fragment, createElement, useEffect, useState } from "react";
1
+ import { Children, Component, Fragment, cloneElement, createElement, isValidElement, useEffect, useState } from "react";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
 
4
4
  function Await({ promise, loading = null, error = null, children }) {
@@ -51,6 +51,9 @@ function Dynamic({ component, fallback = null, ...props }) {
51
51
  var ErrorBoundary = class extends Component {
52
52
  constructor(props) {
53
53
  super(props);
54
+ this.reset = () => {
55
+ this.setState({ error: null });
56
+ };
54
57
  this.state = { error: null };
55
58
  }
56
59
  static getDerivedStateFromError(error) {
@@ -62,9 +65,6 @@ var ErrorBoundary = class extends Component {
62
65
  componentDidUpdate(prevProps) {
63
66
  if (this.state.error && prevProps.resetKey !== this.props.resetKey) this.reset();
64
67
  }
65
- reset = () => {
66
- this.setState({ error: null });
67
- };
68
68
  render() {
69
69
  const { error } = this.state;
70
70
  const { fallback, children } = this.props;
@@ -76,12 +76,14 @@ var ErrorBoundary = class extends Component {
76
76
  }
77
77
  };
78
78
 
79
- function For({ each, children, keyExtractor, fallback = null }) {
79
+ function For({ each, children, keyExtractor, fallback = null, wrapper, reverse }) {
80
80
  if (!each || each.length === 0) return fallback;
81
- return each.map((item, index) => {
82
- const key = keyExtractor ? keyExtractor(item, index) : index;
83
- return /* @__PURE__ */ jsx(Fragment, { children: children(item, index) }, key);
81
+ const elements = (reverse ? [...each].reverse() : each).map((item, i) => {
82
+ const originalIndex = reverse ? each.length - 1 - i : i;
83
+ const key = keyExtractor ? keyExtractor(item, originalIndex) : originalIndex;
84
+ return /* @__PURE__ */ jsx(Fragment, { children: children(item, originalIndex, each) }, key);
84
85
  });
86
+ return wrapper && isValidElement(wrapper) ? cloneElement(wrapper, {}, elements) : elements;
85
87
  }
86
88
 
87
89
  function defaultIsEmpty(data) {
@@ -101,11 +103,12 @@ function QueryBoundary({ query, loading = null, error = null, empty = null, chil
101
103
  return children;
102
104
  }
103
105
 
104
- function Repeat({ times, children }) {
106
+ function Repeat({ times, children, wrapper, reverse }) {
105
107
  if (times <= 0) return null;
106
108
  const elements = [];
107
- for (let i = 0; i < times; i++) elements.push(/* @__PURE__ */ jsx(Fragment, { children: children(i) }, i));
108
- return elements;
109
+ if (reverse) for (let i = times - 1; i >= 0; i--) elements.push(/* @__PURE__ */ jsx(Fragment, { children: children(i, times) }, i));
110
+ else for (let i = 0; i < times; i++) elements.push(/* @__PURE__ */ jsx(Fragment, { children: children(i, times) }, i));
111
+ return wrapper && isValidElement(wrapper) ? cloneElement(wrapper, {}, elements) : elements;
109
112
  }
110
113
 
111
114
  function Show({ when, children, fallback = null }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-solidlike",
3
- "version": "2.2.2",
3
+ "version": "2.2.4",
4
4
  "description": "Declarative React control flow components inspired by Solid.js, replacing ternary expressions and array.map() in JSX",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "@types/react-dom": "^19.2.3",
51
51
  "react": "^19.2.3",
52
52
  "react-dom": "^19.2.3",
53
- "rolldown": "^1.0.0-beta.59",
53
+ "rolldown": "^1.0.0-rc.2",
54
54
  "typescript": "^5.9.3"
55
55
  }
56
56
  }