@wix/headless-stores 0.0.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.
Files changed (150) hide show
  1. package/astro/actions/package.json +4 -0
  2. package/cjs/dist/astro/actions/custom-checkout.d.ts +50 -0
  3. package/cjs/dist/astro/actions/custom-checkout.js +53 -0
  4. package/cjs/dist/astro/actions/index.d.ts +1 -0
  5. package/cjs/dist/astro/actions/index.js +1 -0
  6. package/cjs/dist/data-component-tags.d.ts +8 -0
  7. package/cjs/dist/data-component-tags.js +9 -0
  8. package/cjs/dist/enums/index.d.ts +2 -0
  9. package/cjs/dist/enums/index.js +2 -0
  10. package/cjs/dist/enums/social-platform-enums.d.ts +25 -0
  11. package/cjs/dist/enums/social-platform-enums.js +27 -0
  12. package/cjs/dist/enums/sort-enums.d.ts +17 -0
  13. package/cjs/dist/enums/sort-enums.js +18 -0
  14. package/cjs/dist/react/Category.d.ts +242 -0
  15. package/cjs/dist/react/Category.js +235 -0
  16. package/cjs/dist/react/CategoryList.d.ts +107 -0
  17. package/cjs/dist/react/CategoryList.js +91 -0
  18. package/cjs/dist/react/Choice.d.ts +211 -0
  19. package/cjs/dist/react/Choice.js +213 -0
  20. package/cjs/dist/react/Option.d.ts +242 -0
  21. package/cjs/dist/react/Option.js +346 -0
  22. package/cjs/dist/react/Product.d.ts +1065 -0
  23. package/cjs/dist/react/Product.js +1157 -0
  24. package/cjs/dist/react/ProductList.d.ts +400 -0
  25. package/cjs/dist/react/ProductList.js +368 -0
  26. package/cjs/dist/react/core/CategoryList.d.ts +194 -0
  27. package/cjs/dist/react/core/CategoryList.js +180 -0
  28. package/cjs/dist/react/core/Product.d.ts +225 -0
  29. package/cjs/dist/react/core/Product.js +190 -0
  30. package/cjs/dist/react/core/ProductList.d.ts +235 -0
  31. package/cjs/dist/react/core/ProductList.js +217 -0
  32. package/cjs/dist/react/core/ProductListFilters.d.ts +138 -0
  33. package/cjs/dist/react/core/ProductListFilters.js +242 -0
  34. package/cjs/dist/react/core/ProductListPagination.d.ts +49 -0
  35. package/cjs/dist/react/core/ProductListPagination.js +41 -0
  36. package/cjs/dist/react/core/ProductListSort.d.ts +19 -0
  37. package/cjs/dist/react/core/ProductListSort.js +52 -0
  38. package/cjs/dist/react/core/ProductModifiers.d.ts +416 -0
  39. package/cjs/dist/react/core/ProductModifiers.js +413 -0
  40. package/cjs/dist/react/core/ProductVariantSelector.d.ts +313 -0
  41. package/cjs/dist/react/core/ProductVariantSelector.js +291 -0
  42. package/cjs/dist/react/core/SelectedVariant.d.ts +230 -0
  43. package/cjs/dist/react/core/SelectedVariant.js +269 -0
  44. package/cjs/dist/react/index.d.ts +6 -0
  45. package/cjs/dist/react/index.js +6 -0
  46. package/cjs/dist/react/types.d.ts +8 -0
  47. package/cjs/dist/react/types.js +9 -0
  48. package/cjs/dist/server-actions/custom-checkout-action.d.ts +49 -0
  49. package/cjs/dist/server-actions/custom-checkout-action.js +64 -0
  50. package/cjs/dist/server-actions/index.d.ts +1 -0
  51. package/cjs/dist/server-actions/index.js +1 -0
  52. package/cjs/dist/services/buy-now-service.d.ts +346 -0
  53. package/cjs/dist/services/buy-now-service.js +197 -0
  54. package/cjs/dist/services/categories-list-service.d.ts +164 -0
  55. package/cjs/dist/services/categories-list-service.js +148 -0
  56. package/cjs/dist/services/index.d.ts +5 -0
  57. package/cjs/dist/services/index.js +5 -0
  58. package/cjs/dist/services/pay-now-service.d.ts +214 -0
  59. package/cjs/dist/services/pay-now-service.js +156 -0
  60. package/cjs/dist/services/product-modifiers-service.d.ts +34 -0
  61. package/cjs/dist/services/product-modifiers-service.js +107 -0
  62. package/cjs/dist/services/product-service.d.ts +177 -0
  63. package/cjs/dist/services/product-service.js +190 -0
  64. package/cjs/dist/services/products-list-search-service.d.ts +1 -0
  65. package/cjs/dist/services/products-list-search-service.js +1 -0
  66. package/cjs/dist/services/products-list-service.d.ts +429 -0
  67. package/cjs/dist/services/products-list-service.js +893 -0
  68. package/cjs/dist/services/selected-variant-service.d.ts +66 -0
  69. package/cjs/dist/services/selected-variant-service.js +527 -0
  70. package/cjs/dist/utils/index.d.ts +1 -0
  71. package/cjs/dist/utils/index.js +30 -0
  72. package/cjs/dist/utils/url-params.d.ts +73 -0
  73. package/cjs/dist/utils/url-params.js +114 -0
  74. package/cjs/package.json +3 -0
  75. package/dist/astro/actions/custom-checkout.d.ts +50 -0
  76. package/dist/astro/actions/custom-checkout.js +53 -0
  77. package/dist/astro/actions/index.d.ts +1 -0
  78. package/dist/astro/actions/index.js +1 -0
  79. package/dist/data-component-tags.d.ts +8 -0
  80. package/dist/data-component-tags.js +9 -0
  81. package/dist/enums/index.d.ts +2 -0
  82. package/dist/enums/index.js +2 -0
  83. package/dist/enums/social-platform-enums.d.ts +25 -0
  84. package/dist/enums/social-platform-enums.js +27 -0
  85. package/dist/enums/sort-enums.d.ts +17 -0
  86. package/dist/enums/sort-enums.js +18 -0
  87. package/dist/react/Category.d.ts +242 -0
  88. package/dist/react/Category.js +235 -0
  89. package/dist/react/CategoryList.d.ts +107 -0
  90. package/dist/react/CategoryList.js +91 -0
  91. package/dist/react/Choice.d.ts +211 -0
  92. package/dist/react/Choice.js +213 -0
  93. package/dist/react/Option.d.ts +242 -0
  94. package/dist/react/Option.js +346 -0
  95. package/dist/react/Product.d.ts +1065 -0
  96. package/dist/react/Product.js +1157 -0
  97. package/dist/react/ProductList.d.ts +400 -0
  98. package/dist/react/ProductList.js +368 -0
  99. package/dist/react/core/CategoryList.d.ts +194 -0
  100. package/dist/react/core/CategoryList.js +180 -0
  101. package/dist/react/core/Product.d.ts +225 -0
  102. package/dist/react/core/Product.js +190 -0
  103. package/dist/react/core/ProductList.d.ts +235 -0
  104. package/dist/react/core/ProductList.js +217 -0
  105. package/dist/react/core/ProductListFilters.d.ts +138 -0
  106. package/dist/react/core/ProductListFilters.js +242 -0
  107. package/dist/react/core/ProductListPagination.d.ts +49 -0
  108. package/dist/react/core/ProductListPagination.js +41 -0
  109. package/dist/react/core/ProductListSort.d.ts +19 -0
  110. package/dist/react/core/ProductListSort.js +52 -0
  111. package/dist/react/core/ProductModifiers.d.ts +416 -0
  112. package/dist/react/core/ProductModifiers.js +413 -0
  113. package/dist/react/core/ProductVariantSelector.d.ts +313 -0
  114. package/dist/react/core/ProductVariantSelector.js +291 -0
  115. package/dist/react/core/SelectedVariant.d.ts +230 -0
  116. package/dist/react/core/SelectedVariant.js +269 -0
  117. package/dist/react/index.d.ts +6 -0
  118. package/dist/react/index.js +6 -0
  119. package/dist/react/types.d.ts +8 -0
  120. package/dist/react/types.js +9 -0
  121. package/dist/server-actions/custom-checkout-action.d.ts +49 -0
  122. package/dist/server-actions/custom-checkout-action.js +64 -0
  123. package/dist/server-actions/index.d.ts +1 -0
  124. package/dist/server-actions/index.js +1 -0
  125. package/dist/services/buy-now-service.d.ts +346 -0
  126. package/dist/services/buy-now-service.js +197 -0
  127. package/dist/services/categories-list-service.d.ts +164 -0
  128. package/dist/services/categories-list-service.js +148 -0
  129. package/dist/services/index.d.ts +5 -0
  130. package/dist/services/index.js +5 -0
  131. package/dist/services/pay-now-service.d.ts +214 -0
  132. package/dist/services/pay-now-service.js +156 -0
  133. package/dist/services/product-modifiers-service.d.ts +34 -0
  134. package/dist/services/product-modifiers-service.js +107 -0
  135. package/dist/services/product-service.d.ts +177 -0
  136. package/dist/services/product-service.js +190 -0
  137. package/dist/services/products-list-search-service.d.ts +0 -0
  138. package/dist/services/products-list-search-service.js +1 -0
  139. package/dist/services/products-list-service.d.ts +429 -0
  140. package/dist/services/products-list-service.js +893 -0
  141. package/dist/services/selected-variant-service.d.ts +66 -0
  142. package/dist/services/selected-variant-service.js +527 -0
  143. package/dist/utils/index.d.ts +1 -0
  144. package/dist/utils/index.js +30 -0
  145. package/dist/utils/url-params.d.ts +73 -0
  146. package/dist/utils/url-params.js +114 -0
  147. package/package.json +89 -0
  148. package/react/package.json +4 -0
  149. package/server-actions/package.json +4 -0
  150. package/services/package.json +4 -0
@@ -0,0 +1,416 @@
1
+ import { type ConnectedModifier, type ConnectedModifierChoice } from '@wix/auto_sdk_stores_products-v-3';
2
+ export interface RootProps {
3
+ children: React.ReactNode;
4
+ }
5
+ /**
6
+ * Root component that provides the ProductModifiers service context to its children.
7
+ * This component sets up the necessary services for managing product modifier functionality.
8
+ *
9
+ * @order 1
10
+ * @component
11
+ * @example
12
+ * ```tsx
13
+ * import { ProductModifiers } from '@wix/stores/components';
14
+ *
15
+ * function ProductCustomization() {
16
+ * return (
17
+ * <ProductModifiers.Root>
18
+ * <div>
19
+ * <ProductModifiers.Modifiers>
20
+ * {({ modifiers, hasModifiers, selectedModifiers, areAllRequiredModifiersFilled }) => (
21
+ * <div>
22
+ * {hasModifiers && (
23
+ * <div>
24
+ * <h3>Customize your product</h3>
25
+ * {modifiers.map(modifier => (
26
+ * <ProductModifiers.Modifier key={modifier.id} modifier={modifier}>
27
+ * {({ name, mandatory, hasChoices, choices, isFreeText }) => (
28
+ * <div className="modifier-field">
29
+ * <label>
30
+ * {name} {mandatory && <span className="required">*</span>}
31
+ * </label>
32
+ * {hasChoices && (
33
+ * <div className="choices">
34
+ * {choices.map(choice => (
35
+ * <ProductModifiers.Choice key={choice.id} modifier={modifier} choice={choice}>
36
+ * {({ value, isSelected, select }) => (
37
+ * <button
38
+ * onClick={select}
39
+ * className={isSelected ? 'selected' : ''}
40
+ * >
41
+ * {value}
42
+ * </button>
43
+ * )}
44
+ * </ProductModifiers.Choice>
45
+ * ))}
46
+ * </div>
47
+ * )}
48
+ * {isFreeText && (
49
+ * <ProductModifiers.FreeText modifier={modifier}>
50
+ * {({ value, onChange, placeholder, maxChars }) => (
51
+ * <input
52
+ * type="text"
53
+ * value={value}
54
+ * onChange={(e) => onChange(e.target.value)}
55
+ * placeholder={placeholder}
56
+ * maxLength={maxChars}
57
+ * />
58
+ * )}
59
+ * </ProductModifiers.FreeText>
60
+ * )}
61
+ * </div>
62
+ * )}
63
+ * </ProductModifiers.Modifier>
64
+ * ))}
65
+ * {!areAllRequiredModifiersFilled && (
66
+ * <div className="warning">Please fill all required options</div>
67
+ * )}
68
+ * </div>
69
+ * )}
70
+ * </div>
71
+ * )}
72
+ * </ProductModifiers.Modifiers>
73
+ * </div>
74
+ * </ProductModifiers.Root>
75
+ * );
76
+ * }
77
+ * ```
78
+ */
79
+ export declare function Root(props: RootProps): React.ReactNode;
80
+ /**
81
+ * Props for Modifiers headless component
82
+ */
83
+ export interface ModifiersProps {
84
+ /** Render prop function that receives modifiers data */
85
+ children: (props: ModifiersRenderProps) => React.ReactNode;
86
+ }
87
+ /**
88
+ * Render props for Modifiers component
89
+ */
90
+ export interface ModifiersRenderProps {
91
+ /** Array of product modifiers */
92
+ modifiers: ConnectedModifier[];
93
+ /** Whether product has modifiers */
94
+ hasModifiers: boolean;
95
+ /** Currently selected modifier values */
96
+ selectedModifiers: Record<string, any>;
97
+ /** Whether all required modifiers are filled */
98
+ areAllRequiredModifiersFilled: boolean;
99
+ }
100
+ /**
101
+ * Headless component for all product modifiers
102
+ *
103
+ * @component
104
+ * @example
105
+ * ```tsx
106
+ * import { ProductModifiers } from '@wix/stores/components';
107
+ *
108
+ * function ModifiersSelector() {
109
+ * return (
110
+ * <ProductModifiers.Modifiers>
111
+ * {({ modifiers, hasModifiers, selectedModifiers, areAllRequiredModifiersFilled }) => (
112
+ * <div>
113
+ * {hasModifiers && (
114
+ * <div>
115
+ * <h3>Customize your product</h3>
116
+ * {modifiers.map(modifier => (
117
+ * <div key={modifier.id}>
118
+ * <label>{modifier.name}</label>
119
+ * {modifier.required && <span>*</span>}
120
+ * {modifier.choices?.map(choice => (
121
+ * <label key={choice.id}>
122
+ * <input
123
+ * type={modifier.multiple ? 'checkbox' : 'radio'}
124
+ * name={modifier.id}
125
+ * value={choice.id}
126
+ * checked={selectedModifiers[modifier.id] === choice.id}
127
+ * />
128
+ * {choice.description} (+{choice.priceChange?.price})
129
+ * </label>
130
+ * ))}
131
+ * </div>
132
+ * ))}
133
+ * {!areAllRequiredModifiersFilled && (
134
+ * <div className="warning">Please fill all required options</div>
135
+ * )}
136
+ * </div>
137
+ * )}
138
+ * </div>
139
+ * )}
140
+ * </ProductModifiers.Modifiers>
141
+ * );
142
+ * }
143
+ * ```
144
+ */
145
+ export declare function Modifiers(props: ModifiersProps): import("react").ReactNode;
146
+ /**
147
+ * Props for Modifier headless component
148
+ */
149
+ export interface ModifierProps {
150
+ /** Product modifier data */
151
+ modifier: ConnectedModifier;
152
+ /** Render prop function that receives modifier data */
153
+ children: (props: ModifierRenderProps) => React.ReactNode;
154
+ }
155
+ /**
156
+ * Render props for Modifier component
157
+ */
158
+ export interface ModifierRenderProps {
159
+ /** Modifier name */
160
+ name: string;
161
+ /** Modifier type */
162
+ type: any;
163
+ /** Whether this modifier is mandatory */
164
+ mandatory: boolean;
165
+ /** Array of choices for this modifier (for choice-based modifiers) */
166
+ choices: ConnectedModifierChoice[];
167
+ /** Currently selected value for this modifier */
168
+ selectedValue: any;
169
+ /** Whether this modifier has choices */
170
+ hasChoices: boolean;
171
+ /** Whether this modifier is a free text type */
172
+ isFreeText: boolean;
173
+ /** Maximum characters for free text */
174
+ maxChars?: number;
175
+ /** Placeholder text for free text */
176
+ placeholder?: string;
177
+ }
178
+ /**
179
+ * Headless component for a specific product modifier
180
+ *
181
+ * @component
182
+ * @example
183
+ * ```tsx
184
+ * import { ProductModifiers } from '@wix/stores/components';
185
+ *
186
+ * function ModifierField({ modifier }) {
187
+ * return (
188
+ * <ProductModifiers.Modifier modifier={modifier}>
189
+ * {({ name, mandatory, hasChoices, choices, selectedValue, isFreeText, placeholder, maxChars }) => (
190
+ * <div className="modifier-field">
191
+ * <label>
192
+ * {name} {mandatory && <span className="required">*</span>}
193
+ * </label>
194
+ * {hasChoices && (
195
+ * <div className="choices">
196
+ * {choices.map(choice => (
197
+ * <label key={choice.id}>
198
+ * <input
199
+ * type="radio"
200
+ * name={name}
201
+ * value={choice.name}
202
+ * checked={selectedValue?.choiceValue === choice.name}
203
+ * />
204
+ * {choice.description} (+{choice.priceChange?.price || '0'})
205
+ * </label>
206
+ * ))}
207
+ * </div>
208
+ * )}
209
+ * {isFreeText && (
210
+ * <input
211
+ * type="text"
212
+ * placeholder={placeholder}
213
+ * maxLength={maxChars}
214
+ * value={selectedValue?.freeTextValue || ''}
215
+ * />
216
+ * )}
217
+ * </div>
218
+ * )}
219
+ * </ProductModifiers.Modifier>
220
+ * );
221
+ * }
222
+ * ```
223
+ */
224
+ export declare function Modifier(props: ModifierProps): import("react").ReactNode;
225
+ /**
226
+ * Props for ModifierChoice headless component
227
+ */
228
+ export interface ChoiceProps {
229
+ /** Product modifier data */
230
+ modifier: ConnectedModifier;
231
+ /** Choice data */
232
+ choice: ConnectedModifierChoice;
233
+ /** Render prop function that receives choice data */
234
+ children: (props: ChoiceRenderProps) => React.ReactNode;
235
+ }
236
+ /**
237
+ * Render props for ModifierChoice component
238
+ */
239
+ export interface ChoiceRenderProps {
240
+ /** Choice value to display */
241
+ value: string;
242
+ /** Choice description (for color options) */
243
+ description: string | undefined;
244
+ /** Whether this choice is currently selected */
245
+ isSelected: boolean;
246
+ /** Function to select this choice */
247
+ select: () => void;
248
+ /** Modifier name */
249
+ modifierName: string;
250
+ /** Choice value */
251
+ choiceValue: string;
252
+ /** Color code for swatch choices */
253
+ colorCode?: string;
254
+ }
255
+ /**
256
+ * Headless component for individual modifier choice selection
257
+ *
258
+ * @component
259
+ * @example
260
+ * ```tsx
261
+ * import { ProductModifiers } from '@wix/stores/components';
262
+ *
263
+ * function ModifierChoiceButton({ modifier, choice }) {
264
+ * return (
265
+ * <ProductModifiers.Choice modifier={modifier} choice={choice}>
266
+ * {({ value, description, isSelected, select, colorCode }) => (
267
+ * <button
268
+ * onClick={select}
269
+ * className={`choice-button ${isSelected ? 'selected' : ''}`}
270
+ * style={colorCode ? { backgroundColor: colorCode } : {}}
271
+ * >
272
+ * {colorCode ? (
273
+ * <div className="color-swatch" title={value} />
274
+ * ) : (
275
+ * <span>{value}</span>
276
+ * )}
277
+ * {description && <span className="description">{description}</span>}
278
+ * </button>
279
+ * )}
280
+ * </ProductModifiers.Choice>
281
+ * );
282
+ * }
283
+ * ```
284
+ */
285
+ export declare function Choice(props: ChoiceProps): import("react").ReactNode;
286
+ /**
287
+ * Props for ModifierFreeText headless component
288
+ */
289
+ export interface FreeTextProps {
290
+ /** Product modifier data */
291
+ modifier: ConnectedModifier;
292
+ /** Render prop function that receives free text data */
293
+ children: (props: FreeTextRenderProps) => React.ReactNode;
294
+ }
295
+ /**
296
+ * Render props for ModifierFreeText component
297
+ */
298
+ export interface FreeTextRenderProps {
299
+ /** Current text value */
300
+ value: string;
301
+ /** Function to update text value */
302
+ setText: (value: string) => void;
303
+ /** Whether this modifier is mandatory */
304
+ mandatory: boolean;
305
+ /** Maximum characters allowed */
306
+ maxChars?: number;
307
+ /** Placeholder text */
308
+ placeholder?: string;
309
+ /** Character count */
310
+ charCount: number;
311
+ /** Whether character limit is exceeded */
312
+ isOverLimit: boolean;
313
+ /** Modifier name */
314
+ modifierName: string;
315
+ }
316
+ /**
317
+ * Headless component for free text modifier input
318
+ *
319
+ * @component
320
+ * @example
321
+ * ```tsx
322
+ * import { ProductModifiers } from '@wix/stores/components';
323
+ *
324
+ * function FreeTextModifier({ modifier }) {
325
+ * return (
326
+ * <ProductModifiers.FreeText modifier={modifier}>
327
+ * {({ value, setText, mandatory, maxChars, placeholder, charCount, isOverLimit, modifierName }) => (
328
+ * <div className="free-text-modifier">
329
+ * <label>
330
+ * {modifierName} {mandatory && <span className="required">*</span>}
331
+ * </label>
332
+ * <textarea
333
+ * value={value}
334
+ * setText={(e) => setText(e.target.value)}
335
+ * placeholder={placeholder}
336
+ * maxLength={maxChars}
337
+ * className={isOverLimit ? 'over-limit' : ''}
338
+ * />
339
+ * {maxChars && (
340
+ * <div className={`char-count ${isOverLimit ? 'over-limit' : ''}`}>
341
+ * {charCount}/{maxChars}
342
+ * </div>
343
+ * )}
344
+ * </div>
345
+ * )}
346
+ * </ProductModifiers.FreeText>
347
+ * );
348
+ * }
349
+ * ```
350
+ */
351
+ export declare function FreeText(props: FreeTextProps): import("react").ReactNode;
352
+ /**
353
+ * Props for ModifierToggleFreeText headless component
354
+ */
355
+ export interface ToggleFreeTextProps {
356
+ /** Product modifier data */
357
+ modifier: ConnectedModifier;
358
+ /** Render prop function that receives toggle data */
359
+ children: (props: ToggleFreeTextRenderProps) => React.ReactNode;
360
+ }
361
+ /**
362
+ * Render props for ModifierToggleFreeText component
363
+ */
364
+ export interface ToggleFreeTextRenderProps {
365
+ /** Whether the text input is shown */
366
+ isTextInputShown: boolean;
367
+ /** Function to toggle text input visibility */
368
+ toggle: () => void;
369
+ /** Whether this modifier is mandatory */
370
+ mandatory: boolean;
371
+ /** Modifier name */
372
+ modifierName: string;
373
+ }
374
+ /**
375
+ * Headless component for toggling free text modifier input
376
+ * Used for optional free text modifiers where a checkbox shows/hides the input
377
+ *
378
+ * @component
379
+ * @example
380
+ * ```tsx
381
+ * import { ProductModifiers } from '@wix/stores/components';
382
+ *
383
+ * function ToggleFreeTextModifier({ modifier }) {
384
+ * return (
385
+ * <ProductModifiers.ToggleFreeText modifier={modifier}>
386
+ * {({ isTextInputShown, toggle, mandatory, modifierName }) => (
387
+ * <div className="toggle-free-text">
388
+ * {!mandatory && (
389
+ * <label>
390
+ * <input
391
+ * type="checkbox"
392
+ * checked={isTextInputShown}
393
+ * onChange={toggle}
394
+ * />
395
+ * Add {modifierName}
396
+ * </label>
397
+ * )}
398
+ * {isTextInputShown && (
399
+ * <ProductModifiers.FreeText modifier={modifier}>
400
+ * {(props) => (
401
+ * <textarea
402
+ * value={props.value}
403
+ * onChange={(e) => props.onChange(e.target.value)}
404
+ * placeholder={props.placeholder}
405
+ * />
406
+ * )}
407
+ * </ProductModifiers.FreeText>
408
+ * )}
409
+ * </div>
410
+ * )}
411
+ * </ProductModifiers.ToggleFreeText>
412
+ * );
413
+ * }
414
+ * ```
415
+ */
416
+ export declare function ToggleFreeText(props: ToggleFreeTextProps): import("react").ReactNode;