@galangel/react-scroll-magic 1.0.2 β†’ 1.0.3

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 (26) hide show
  1. package/README.md +249 -112
  2. package/dist/Scroll/story/ai-chat/AIChatDemo.d.ts +3 -0
  3. package/dist/Scroll/story/ai-chat/components/AgentStepHeader.d.ts +13 -0
  4. package/dist/Scroll/story/ai-chat/components/ChatHeader.d.ts +7 -0
  5. package/dist/Scroll/story/ai-chat/components/ChatInput.d.ts +8 -0
  6. package/dist/Scroll/story/ai-chat/components/ChatStyles.d.ts +3 -0
  7. package/dist/Scroll/story/ai-chat/components/EmptyState.d.ts +3 -0
  8. package/dist/Scroll/story/ai-chat/components/OutputLineItem.d.ts +9 -0
  9. package/dist/Scroll/story/ai-chat/components/QuestionBubble.d.ts +8 -0
  10. package/dist/Scroll/story/ai-chat/components/ReasoningHeader.d.ts +13 -0
  11. package/dist/Scroll/story/ai-chat/components/SolutionHeader.d.ts +11 -0
  12. package/dist/Scroll/story/ai-chat/components/index.d.ts +9 -0
  13. package/dist/Scroll/story/ai-chat/hooks/index.d.ts +2 -0
  14. package/dist/Scroll/story/ai-chat/hooks/use-auto-scroll.d.ts +13 -0
  15. package/dist/Scroll/story/ai-chat/hooks/use-chat-messages.d.ts +9 -0
  16. package/dist/Scroll/story/ai-chat/index.d.ts +5 -0
  17. package/dist/Scroll/story/ai-chat/index.stories.d.ts +7 -0
  18. package/dist/Scroll/story/ai-chat/types/index.d.ts +22 -0
  19. package/dist/Scroll/story/ai-chat/utils/convert-to-items.d.ts +4 -0
  20. package/dist/Scroll/story/ai-chat/utils/generate-output-line.d.ts +3 -0
  21. package/dist/Scroll/story/ai-chat/utils/generate-question.d.ts +1 -0
  22. package/dist/Scroll/story/ai-chat/utils/index.d.ts +4 -0
  23. package/dist/Scroll/story/ai-chat/utils/step-config.d.ts +3 -0
  24. package/dist/cjs/index.js +1 -1
  25. package/dist/es/index.js +51 -51
  26. package/package.json +1 -1
package/README.md CHANGED
@@ -1,28 +1,46 @@
1
- # Scroll Component
1
+ <p align="center">
2
+ <img src="https://img.shields.io/badge/πŸͺ„-React_Scroll_Magic-667eea?style=for-the-badge&labelColor=764ba2" alt="React Scroll Magic" />
3
+ </p>
2
4
 
3
- [Live Demo](https://galangel.github.io/react-scroll-magic/)
5
+ <h1 align="center">πŸͺ„ React Scroll Magic</h1>
4
6
 
5
- ## Overview
7
+ <p align="center">
8
+ <strong>Create magical scroll experiences with nested sticky headers, collapsible sections, and smooth animations.</strong>
9
+ </p>
6
10
 
7
- The Scroll Magic Component is a React component that provides smooth scrolling functionality for your web application. It allows you to create scroll between items and headers and keep the headers visible.
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@galangel/react-scroll-magic"><img src="https://img.shields.io/npm/v/@galangel/react-scroll-magic.svg?style=flat-square&color=667eea" alt="npm version" /></a>
13
+ <a href="https://www.npmjs.com/package/@galangel/react-scroll-magic"><img src="https://img.shields.io/npm/dm/@galangel/react-scroll-magic.svg?style=flat-square&color=764ba2" alt="npm downloads" /></a>
14
+ <a href="https://github.com/galangel/react-scroll-magic/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square" alt="license" /></a>
15
+ <img src="https://img.shields.io/badge/TypeScript-Ready-3178c6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />
16
+ <img src="https://img.shields.io/badge/React-18+-61dafb?style=flat-square&logo=react&logoColor=white" alt="React 18+" />
17
+ </p>
8
18
 
9
- ## Features
19
+ <p align="center">
20
+ <a href="https://galangel.github.io/react-scroll-magic/">πŸ“– Live Demo & Documentation</a>
21
+ </p>
10
22
 
11
- - **Sticky Headers**: Headers can stick to top, bottom, or both directions
12
- - **Click-to-Scroll**: Click any header to smoothly scroll to its content
13
- - **Collapsible Sections**: Headers can expand/collapse their nested content
14
- - **Infinite Scrolling**: Load more content when reaching the bottom
15
- - **Nested Structure**: Support for deeply nested hierarchical content
16
- - **Multiple Header Behaviors**: Choose between sticky, push, or normal header behavior
17
- - **TypeScript Support**: Fully typed with comprehensive interfaces
18
- - **Customizable Rendering**: Complete control over how items and loading states are rendered
23
+ ---
19
24
 
20
- ## Installation
25
+ ## ✨ Key Features
21
26
 
22
- To install the Scroll Component, use npm or yarn:
27
+ | Feature | Description |
28
+ | ------------------------- | --------------------------------------------------------------------------- |
29
+ | πŸ“Œ **Sticky Headers** | Headers stick to top as you scroll, with support for nested sticky behavior |
30
+ | 🎯 **Nested Structure** | Create deeply nested hierarchies with items inside items |
31
+ | πŸ“¦ **Collapse/Expand** | Each section with nested content can be collapsed or expanded |
32
+ | ♾️ **Infinite Scrolling** | Built-in support for loading more items when reaching the bottom |
33
+ | 🎨 **Fully Customizable** | Complete control over rendering via render props |
34
+ | πŸ”€ **TypeScript Ready** | Fully typed with comprehensive interfaces |
35
+
36
+ ---
37
+
38
+ ## πŸš€ Quick Start
39
+
40
+ ### Installation
23
41
 
24
42
  ```bash
25
- npm i @galangel/react-scroll-magic
43
+ npm install @galangel/react-scroll-magic
26
44
  ```
27
45
 
28
46
  or
@@ -31,53 +49,85 @@ or
31
49
  yarn add @galangel/react-scroll-magic
32
50
  ```
33
51
 
34
- ## Usage
35
-
36
- Here is a basic example of how to use the Scroll Component in your React application:
52
+ ### Basic Usage
37
53
 
38
54
  ```jsx
39
- import React from 'react';
40
55
  import { Scroll } from '@galangel/react-scroll-magic';
41
56
 
42
- const App = () => {
43
- const items = [
44
- {
45
- // Header item with nested content
46
- render: ({ collapse }) => (
47
- <div style={{ padding: '10px', backgroundColor: '#f0f0f0' }}>
48
- Header 1
49
- {collapse && (
50
- <button onClick={collapse.isOpen ? collapse.close : collapse.open}>{collapse.isOpen ? 'β–Ό' : 'β–Ά'}</button>
51
- )}
52
- </div>
53
- ),
54
- nestedItems: [
55
- {
56
- // Regular item
57
- render: () => <div style={{ padding: '10px' }}>Item 1.1</div>,
58
- },
59
- {
60
- render: () => <div style={{ padding: '10px' }}>Item 1.2</div>,
61
- },
62
- ],
63
- },
64
- {
65
- // Simple item without nesting
66
- render: () => <div style={{ padding: '10px' }}>Simple Item</div>,
67
- },
68
- ];
69
-
57
+ const items = [
58
+ {
59
+ id: 'section-1',
60
+ render: ({ collapse }) => (
61
+ <div style={{ padding: '10px', backgroundColor: '#f0f0f0' }}>
62
+ Header 1
63
+ {collapse && (
64
+ <button onClick={collapse.isOpen ? collapse.close : collapse.open}>{collapse.isOpen ? 'β–Ό' : 'β–Ά'}</button>
65
+ )}
66
+ </div>
67
+ ),
68
+ nestedItems: [
69
+ { render: () => <div style={{ padding: '10px' }}>Item 1.1</div> },
70
+ { render: () => <div style={{ padding: '10px' }}>Item 1.2</div> },
71
+ ],
72
+ },
73
+ {
74
+ id: 'section-2',
75
+ render: () => <div style={{ padding: '10px' }}>Simple Item</div>,
76
+ },
77
+ ];
78
+
79
+ function App() {
70
80
  return (
71
81
  <div style={{ height: '400px', width: '100%' }}>
72
- <Scroll items={items} stickTo="all" headerBehavior="stick" scrollBehavior="smooth" />
82
+ <Scroll items={items} headerBehavior="push" scrollBehavior="smooth" />
73
83
  </div>
74
84
  );
75
- };
85
+ }
86
+ ```
87
+
88
+ ---
89
+
90
+ ## πŸ“š API Reference
91
+
92
+ ### Scroll Component Props
76
93
 
77
- export default App;
94
+ | Prop | Type | Default | Description |
95
+ | ---------------- | --------------------------------- | ---------- | -------------------------------------------------------------------------------------- |
96
+ | `items` | `Items` | Required | Array of items to render. Each item has a `render` function and optional `nestedItems` |
97
+ | `stickTo` | `'top' \| 'bottom' \| 'all'` | `'all'` | Where headers should stick when scrolling |
98
+ | `scrollBehavior` | `'auto' \| 'instant' \| 'smooth'` | `'smooth'` | CSS scroll-behavior when clicking headers |
99
+ | `headerBehavior` | `'stick' \| 'push' \| 'none'` | `'none'` | How headers behave when scrolling |
100
+ | `loading` | `Loading` | Optional | Configuration for infinite scrolling |
101
+
102
+ ### Item Structure
103
+
104
+ ```typescript
105
+ interface Item {
106
+ id?: string; // Optional unique identifier
107
+ render: (props: {
108
+ // Render function for the item
109
+ collapse?: {
110
+ isOpen: boolean; // Current collapse state
111
+ open: () => void; // Function to expand
112
+ close: () => void; // Function to collapse
113
+ };
114
+ }) => JSX.Element;
115
+ nestedItems?: Item[]; // Optional nested items (makes this a header)
116
+ }
78
117
  ```
79
118
 
80
- ### Infinite Scrolling Example
119
+ ### Loading Type Definition
120
+
121
+ ```typescript
122
+ interface Loading {
123
+ onBottomReached?: () => Promise<void>; // Callback when user scrolls to bottom
124
+ render?: (isLoading: boolean) => JSX.Element; // Custom loading indicator renderer
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## ♾️ Infinite Scrolling Example
81
131
 
82
132
  ```jsx
83
133
  import React, { useState } from 'react';
@@ -90,7 +140,6 @@ const InfiniteScrollExample = () => {
90
140
  ]);
91
141
 
92
142
  const loadMoreItems = async () => {
93
- // Simulate API call
94
143
  await new Promise((resolve) => setTimeout(resolve, 1000));
95
144
 
96
145
  const newItems = Array.from({ length: 10 }, (_, i) => ({
@@ -115,106 +164,194 @@ const InfiniteScrollExample = () => {
115
164
  };
116
165
  ```
117
166
 
118
- ## Props
167
+ ---
119
168
 
120
- The Scroll Component accepts the following props:
169
+ ## 🎨 Styling & CSS Classes
121
170
 
122
- | Prop | Type | Default | Description |
123
- | ---------------- | --------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------- |
124
- | `items` | `Items` | Required | Array of items to render. Each item has a `render` function and optional `nestedItems` |
125
- | `stickTo` | `'top' \| 'bottom' \| 'all'` | `'all'` | Where headers should stick when scrolling |
126
- | `scrollBehavior` | `'auto' \| 'instant' \| 'smooth'` | `'smooth'` | CSS scroll-behavior when clicking headers to scroll to content |
127
- | `headerBehavior` | `'stick' \| 'push' \| 'none'` | `'none'` | How headers behave: `stick` = sticky positioning, `push` = headers push down content, `none` = normal flow |
128
- | `loading` | `Loading` | Optional | Configuration for infinite scrolling and loading states |
171
+ The component uses semantic CSS classes that you can target for custom styling. Here's a complete reference:
129
172
 
130
- ### Items Type Definition
173
+ ### CSS Class Reference
131
174
 
132
- ```typescript
133
- type Items = Item[];
175
+ | Class Name | Element | Description |
176
+ | ------------------------- | ------- | ----------------------------------------------- |
177
+ | `.scroll-list` | `<ul>` | Main scroll container element |
178
+ | `.scroll-item` | `<li>` | Regular list item (items without `nestedItems`) |
179
+ | `.scroll-header` | `<li>` | Header item (items with `nestedItems`) |
180
+ | `.scroll-header.stick` | `<li>` | Header with `headerBehavior="stick"` |
181
+ | `.scroll-header.push` | `<li>` | Header with `headerBehavior="push"` |
182
+ | `.scroll-header.none` | `<li>` | Header with `headerBehavior="none"` |
183
+ | `.scroll-loading` | `<li>` | Loading indicator container |
184
+ | `.scroll-loading.loading` | `<li>` | Loading indicator when actively loading |
134
185
 
135
- interface Item {
136
- id?: string; // Optional unique identifier
137
- render: (renderProps: RenderProps) => JSX.Element; // Function to render the item
138
- nestedItems?: Item[]; // Optional nested items (makes this a header)
186
+ ### Styling Examples
187
+
188
+ ```css
189
+ /* Main scroll container */
190
+ .scroll-list {
191
+ list-style: none;
192
+ margin: 0;
193
+ padding: 0;
194
+ height: 100%;
195
+ overflow-y: auto;
139
196
  }
140
197
 
141
- interface RenderProps {
142
- collapse?: {
143
- open: () => void; // Function to expand nested items
144
- close: () => void; // Function to collapse nested items
145
- isOpen: boolean; // Current collapse state
146
- };
198
+ /* All items (headers and regular items) */
199
+ .scroll-item,
200
+ .scroll-header {
201
+ width: 100%;
202
+ box-sizing: border-box;
147
203
  }
148
- ```
149
204
 
150
- ### Loading Type Definition
205
+ /* Regular items */
206
+ .scroll-item {
207
+ padding: 12px 16px;
208
+ background-color: #fff;
209
+ border-bottom: 1px solid #eee;
210
+ }
151
211
 
152
- ```typescript
153
- interface Loading {
154
- onBottomReached?: () => Promise<void>; // Callback when user scrolls to bottom
155
- render?: (isLoading: boolean) => JSX.Element; // Custom loading indicator renderer
212
+ /* Header items - base styles */
213
+ .scroll-header {
214
+ padding: 16px 20px;
215
+ background-color: #f5f5f5;
216
+ font-weight: 600;
217
+ cursor: pointer;
218
+ border-bottom: 1px solid #ddd;
156
219
  }
157
- ```
158
220
 
159
- ## Item Structure
221
+ /* Sticky header behavior */
222
+ .scroll-header.stick {
223
+ position: sticky;
224
+ /* top/bottom values are set dynamically by the component */
225
+ }
160
226
 
161
- - **Simple Items**: Items without `nestedItems` are rendered as regular list items
162
- - **Header Items**: Items with `nestedItems` become clickable headers that can:
163
- - Scroll to their content when clicked
164
- - Be collapsed/expanded using the `collapse` props in the render function
165
- - Stick to top/bottom based on `stickTo` and `headerBehavior` settings
166
- - **Nested Structure**: Items can be nested to any depth for complex hierarchical layouts
227
+ /* Push header behavior */
228
+ .scroll-header.push {
229
+ position: sticky;
230
+ /* top value is set dynamically by the component */
231
+ }
167
232
 
168
- ## Styling
233
+ /* Header hover effect */
234
+ .scroll-header:hover {
235
+ background-color: #e8e8e8;
236
+ }
169
237
 
170
- The component uses CSS classes that you can target for styling:
238
+ /* Loading indicator */
239
+ .scroll-loading {
240
+ display: none;
241
+ padding: 20px;
242
+ text-align: center;
243
+ }
244
+
245
+ .scroll-loading.loading {
246
+ display: block;
247
+ }
248
+
249
+ /* Loading spinner animation */
250
+ .scroll-loading.loading::after {
251
+ content: '';
252
+ display: inline-block;
253
+ width: 20px;
254
+ height: 20px;
255
+ border: 2px solid #ccc;
256
+ border-top-color: #667eea;
257
+ border-radius: 50%;
258
+ animation: spin 1s linear infinite;
259
+ }
260
+
261
+ @keyframes spin {
262
+ to {
263
+ transform: rotate(360deg);
264
+ }
265
+ }
266
+ ```
267
+
268
+ ### Dark Theme Example
171
269
 
172
270
  ```css
173
- /* Main scroll container */
271
+ /* Dark theme styling */
174
272
  .scroll-list {
175
- /* Your styles here */
273
+ background-color: #1a202c;
176
274
  }
177
275
 
178
- /* Header items */
179
- .scroll-header {
180
- /* Your styles here */
276
+ .scroll-item {
277
+ background-color: #2d3748;
278
+ color: #e2e8f0;
279
+ border-bottom: 1px solid #4a5568;
181
280
  }
182
281
 
183
- /* Sticky header behavior */
184
- .scroll-header.stick {
185
- position: sticky;
186
- /* Additional sticky styles */
282
+ .scroll-header {
283
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
284
+ color: #fff;
285
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
187
286
  }
188
287
 
189
- /* Push header behavior */
190
- .scroll-header.push {
191
- /* Push behavior styles */
288
+ .scroll-header:hover {
289
+ filter: brightness(1.1);
192
290
  }
193
291
 
194
- /* Regular items */
195
- .scroll-item {
196
- /* Your styles here */
292
+ .scroll-loading.loading::after {
293
+ border-color: #4a5568;
294
+ border-top-color: #667eea;
197
295
  }
198
296
  ```
199
297
 
200
- **Important**: Make sure your scroll container has a defined height for the scrolling to work properly:
298
+ ### Important Notes
299
+
300
+ > ⚠️ **Container Height Required**: The scroll container must have a defined height for scrolling to work properly.
201
301
 
202
302
  ```jsx
203
303
  <div style={{ height: '400px' }}>
204
304
  {' '}
205
- {/* Define height here */}
305
+ {/* or height: '100vh' */}
206
306
  <Scroll items={items} />
207
307
  </div>
208
308
  ```
209
309
 
210
- ## License
310
+ ---
311
+
312
+ ## πŸ’‘ Tips & Best Practices
313
+
314
+ | Tip | Description |
315
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
316
+ | 🎯 **Use Unique IDs** | Assign unique `id` properties to items for better performance and scroll-to functionality |
317
+ | πŸ›‘ **Stop Propagation** | When adding click handlers inside items (like collapse buttons), use `e.stopPropagation()` to prevent scroll-to behavior |
318
+ | πŸ“ **Set Container Height** | The Scroll component needs a container with a defined height (`height: 100vh` or fixed pixels) |
319
+ | 🎨 **headerBehavior: "push"** | The "push" mode creates a natural feel where headers push each other out of view |
320
+
321
+ ---
322
+
323
+ ## πŸ€– Real World Example: AI Chat
324
+
325
+ Check out the [AI Chat demo](https://galangel.github.io/react-scroll-magic/?path=/story/examples-ai-chat--ai-chat) showcasing a complex real-world use case with:
326
+
327
+ - πŸ’¬ **Question β†’ Response Flow**: Messages with nested reasoning steps
328
+ - 🧠 **Collapsible Reasoning**: Auto-collapse when complete
329
+ - πŸ“œ **Deep Nesting**: Four levels of nesting working seamlessly
330
+
331
+ ---
332
+
333
+ ## πŸ“„ License
211
334
 
212
335
  This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.
213
336
 
214
- ## Contributing
337
+ ---
338
+
339
+ ## 🀝 Contributing
215
340
 
216
341
  Contributions are welcome! Please read the [CONTRIBUTING](CONTRIBUTING.md) guidelines before submitting a pull request.
217
342
 
218
- ## Contact
343
+ ---
344
+
345
+ ## πŸ’¬ Contact
346
+
347
+ For any questions or feedback, please [open an issue](https://github.com/galangel/react-scroll-magic/issues) on GitHub.
348
+
349
+ ---
350
+
351
+ <p align="center">
352
+ Made with πŸͺ„ by <a href="https://github.com/galangel">@galangel</a>
353
+ </p>
219
354
 
220
- For any questions or feedback, please open an issue on GitHub.
355
+ <p align="center">
356
+ <a href="https://www.buymeacoffee.com/galangel"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50" /></a>
357
+ </p>
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+
3
+ export declare const AIChatDemo: React.FC;
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { AgentStep } from '../types';
3
+
4
+ interface AgentStepHeaderProps {
5
+ step: AgentStep;
6
+ collapse?: {
7
+ isOpen: boolean;
8
+ open: () => void;
9
+ close: () => void;
10
+ };
11
+ }
12
+ export declare const AgentStepHeader: React.FC<AgentStepHeaderProps>;
13
+ export {};
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface ChatHeaderProps {
4
+ isGenerating: boolean;
5
+ }
6
+ export declare const ChatHeader: React.FC<ChatHeaderProps>;
7
+ export {};
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface ChatInputProps {
4
+ isGenerating: boolean;
5
+ onGenerate: () => void;
6
+ }
7
+ export declare const ChatInput: React.FC<ChatInputProps>;
8
+ export {};
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+
3
+ export declare const ChatStyles: React.FC;
@@ -0,0 +1,3 @@
1
+ import { default as React } from 'react';
2
+
3
+ export declare const EmptyState: React.FC;
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface OutputLineItemProps {
4
+ text: string;
5
+ isNew?: boolean;
6
+ indent?: number;
7
+ }
8
+ export declare const OutputLineItem: React.FC<OutputLineItemProps>;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface QuestionBubbleProps {
4
+ question: string;
5
+ timestamp: string;
6
+ }
7
+ export declare const QuestionBubble: React.FC<QuestionBubbleProps>;
8
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface ReasoningHeaderProps {
4
+ messageId: string;
5
+ messageIsComplete?: boolean;
6
+ collapse?: {
7
+ isOpen: boolean;
8
+ open: () => void;
9
+ close: () => void;
10
+ };
11
+ }
12
+ export declare const ReasoningHeader: React.FC<ReasoningHeaderProps>;
13
+ export {};
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+
3
+ interface SolutionHeaderProps {
4
+ collapse?: {
5
+ isOpen: boolean;
6
+ open: () => void;
7
+ close: () => void;
8
+ };
9
+ }
10
+ export declare const SolutionHeader: React.FC<SolutionHeaderProps>;
11
+ export {};
@@ -0,0 +1,9 @@
1
+ export { QuestionBubble } from './QuestionBubble';
2
+ export { AgentStepHeader } from './AgentStepHeader';
3
+ export { ReasoningHeader } from './ReasoningHeader';
4
+ export { SolutionHeader } from './SolutionHeader';
5
+ export { OutputLineItem } from './OutputLineItem';
6
+ export { ChatHeader } from './ChatHeader';
7
+ export { ChatInput } from './ChatInput';
8
+ export { EmptyState } from './EmptyState';
9
+ export { ChatStyles } from './ChatStyles';
@@ -0,0 +1,2 @@
1
+ export { useAutoScroll } from './use-auto-scroll';
2
+ export { useChatMessages } from './use-chat-messages';
@@ -0,0 +1,13 @@
1
+ interface UseAutoScrollOptions {
2
+ threshold?: number;
3
+ scrollIdleDelay?: number;
4
+ hasContent?: boolean;
5
+ }
6
+ interface UseAutoScrollReturn {
7
+ scrollContainerRef: React.RefObject<HTMLDivElement>;
8
+ shouldAutoScroll: () => boolean;
9
+ scrollToBottom: () => void;
10
+ forceAutoScrollOn: () => void;
11
+ }
12
+ export declare const useAutoScroll: ({ threshold, scrollIdleDelay, hasContent, }?: UseAutoScrollOptions) => UseAutoScrollReturn;
13
+ export {};
@@ -0,0 +1,9 @@
1
+ import { ChatMessage } from '../types';
2
+
3
+ interface UseChatMessagesReturn {
4
+ messages: ChatMessage[];
5
+ isGenerating: boolean;
6
+ generateResponse: () => void;
7
+ }
8
+ export declare const useChatMessages: () => UseChatMessagesReturn;
9
+ export {};
@@ -0,0 +1,5 @@
1
+ export { AIChatDemo } from './AIChatDemo';
2
+ export * from './types';
3
+ export * from './components';
4
+ export * from './hooks';
5
+ export * from './utils';
@@ -0,0 +1,7 @@
1
+ import { Preview, StoryObj } from '@storybook/react';
2
+ import { Scroll } from '../../index';
3
+
4
+ declare const preview: Preview;
5
+ export default preview;
6
+ type Story = StoryObj<typeof Scroll>;
7
+ export declare const AIChat: Story;
@@ -0,0 +1,22 @@
1
+ export interface OutputLine {
2
+ id: string;
3
+ text: string;
4
+ }
5
+ export interface AgentStep {
6
+ id: string;
7
+ type: 'thinking' | 'searching' | 'analyzing' | 'solution';
8
+ title: string;
9
+ outputs: OutputLine[];
10
+ isComplete: boolean;
11
+ }
12
+ export interface ChatMessage {
13
+ id: string;
14
+ question: string;
15
+ steps: AgentStep[];
16
+ isComplete: boolean;
17
+ }
18
+ export interface StepConfig {
19
+ icon: string;
20
+ title: string;
21
+ bgColor: string;
22
+ }
@@ -0,0 +1,4 @@
1
+ import { Items } from '../../../types';
2
+ import { ChatMessage } from '../types';
3
+
4
+ export declare const convertToItems: (messages: ChatMessage[]) => Items;
@@ -0,0 +1,3 @@
1
+ import { AgentStep } from '../types';
2
+
3
+ export declare const generateOutputLine: (stepType: AgentStep["type"]) => string;
@@ -0,0 +1 @@
1
+ export declare const generateQuestion: () => string;
@@ -0,0 +1,4 @@
1
+ export { generateQuestion } from './generate-question';
2
+ export { generateOutputLine } from './generate-output-line';
3
+ export { getStepConfig } from './step-config';
4
+ export { convertToItems } from './convert-to-items';
@@ -0,0 +1,3 @@
1
+ import { AgentStep, StepConfig } from '../types';
2
+
3
+ export declare const getStepConfig: (type: AgentStep["type"]) => StepConfig;
package/dist/cjs/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),l=require("react"),L=(e=[])=>e.slice(0,e.length-1).map((u,m)=>e.slice(0,m+1)),k=l.createContext({getTopHeadersTotalHeight:()=>0,getBottomHeadersTotalHeight:()=>0,scrollToView:()=>{},setListRef:()=>{},stickTo:"all",scrollBehavior:"smooth",headerBehavior:"none",addHeader:()=>{},headerCollaspeOpen:()=>{},headerCollaspeClose:()=>{},collapsedPaths:[]}),z=()=>l.useContext(k),F=({children:e,stickTo:t="all",scrollBehavior:g="smooth",headerBehavior:u="none"})=>{const[m,f]=l.useState(null),[i,r]=l.useState([]),a=l.useRef({}),C=s=>{const n=a.current[s.join("-")],c=n.nextElementSibling;if(m&&c){const S=window.getComputedStyle(c),d=n.getBoundingClientRect().height,o=p(s),j=parseFloat(S.marginTop)+parseFloat(S.marginBottom)+parseFloat(S.paddingTop)+parseFloat(S.paddingBottom)+parseFloat(S.borderTopWidth)+parseFloat(S.borderBottomWidth),x=Math.ceil(t==="bottom"?c.offsetTop-d:c.offsetTop-o-d+j);m.scrollTo({top:x,behavior:g})}},b=(s,n)=>{a.current[n.join("-")]=s},p=(s=[])=>{const n=L(s),c=n.map(o=>o.join("-"));if(u==="stick"){const o=n.reduce((H,y)=>{const P=y[y.length-1],O=Array.from({length:P},(I,w)=>[...y.slice(0,y.length-1),w]).map(I=>I.join("-"));return H.push(...O),H},[]);c.push(...o);const j=s[s.length-1],x=Array.from({length:j},(H,y)=>[...s.slice(0,s.length-1),y]).map(H=>H.join("-"));c.push(...x)}return c.map(o=>a.current[o]).reduce((o,j)=>{var H;return o+((H=j==null?void 0:j.getBoundingClientRect)==null?void 0:H.call(j).height)||0},0)},T=(s=[])=>{const n=s[s.length-1];return Object.entries(a.current).reduce((d,[o,j])=>{const x=o.split("-").map(Number);return x.length===1&&x[0]>n&&d.push(j),d},[]).reduce((d,o)=>{var x;return d+((x=o==null?void 0:o.getBoundingClientRect)==null?void 0:x.call(o).height)||0},0)},R=s=>{const n=s.join("-");i.includes(n)&&r(c=>c.filter(S=>S!==n))},B=s=>{const n=s.join("-");i.includes(n)||r(c=>[...c,n])};return h.jsx(k.Provider,{value:{addHeader:b,getTopHeadersTotalHeight:p,getBottomHeadersTotalHeight:T,stickTo:t,scrollToView:C,setListRef:f,scrollBehavior:g,headerBehavior:u,headerCollaspeOpen:R,headerCollaspeClose:B,collapsedPaths:i},children:e})},M=({path:e,itemId:t,itemRender:g})=>{const{getTopHeadersTotalHeight:u,getBottomHeadersTotalHeight:m,scrollToView:f,stickTo:i,headerBehavior:r,addHeader:a,headerCollaspeClose:C,headerCollaspeOpen:b,collapsedPaths:p}=z(),T=l.useRef(null),R=()=>{f(e)};l.useEffect(()=>{if(T.current){const d=T.current;a(d,e)}},[T]);const B=l.useMemo(()=>{if(r==="stick"){let d="auto",o="auto";return d=i==="top"||i==="all"?u(e):"auto",o=i==="bottom"||i==="all"?m(e):"auto",{top:d,bottom:o,zIndex:100-e.length}}else if(r==="push")return{top:u(e),zIndex:100-e.length}},[r,e,i]),s=l.useCallback(()=>b(e),[b,e]),n=l.useCallback(()=>C(e),[C,e]),c=l.useMemo(()=>p.includes(e.join("-")),[p]),S=l.useMemo(()=>g({collapse:{open:s,close:n,isOpen:!c}}),[g,c,s,n]);return h.jsx("li",{id:t,onClick:R,className:`scroll-header ${r} `,style:{...B},"aria-label":"Scroll Header",role:"heading","aria-level":e.length,ref:T,children:S})},N=({itemRender:e,itemId:t})=>h.jsx("li",{id:t,role:"listitem","aria-label":"Scroll Item",className:"scroll-item ",children:e({})}),E={visibility:"hidden",position:"absolute",width:"0",height:"0"},v=({headerBehavior:e,items:t,path:g=[],collapsedPaths:u})=>{const m=e==="push"?"section":l.Fragment;return h.jsx("section",{children:t.map((f,i)=>{var a;const r=[...g,i];if((a=f.nestedItems)!=null&&a.length){const C=u.includes(r.join("-"))?E:{};return h.jsxs(m,{children:[h.jsx(M,{path:r,itemRender:f.render,itemId:f.id}),h.jsx("section",{style:C,children:v({items:f.nestedItems,headerBehavior:e,path:r,collapsedPaths:u})})]},r.join("-"))}else return h.jsx(N,{itemRender:f.render,itemId:f.id},r.join("-"))})})},V=({loading:e})=>e?h.jsx("li",{role:"listitem","aria-label":"Scroll Loading",className:`scroll-loading ${e?"loading":""}`}):null,W=({items:e,loading:t})=>{const{setListRef:g,headerBehavior:u,collapsedPaths:m,scrollBehavior:f}=z(),[i,r]=l.useState(!1),a=l.useRef(null);l.useEffect(()=>{a.current&&g(a.current)},[a]);const C=l.useCallback(b=>{if(e.length===0||!(t!=null&&t.onBottomReached))return;const p=b.target;Math.floor(p.scrollHeight-p.scrollTop)<p.clientHeight+10&&(p.dataset.loading||(p.dataset.loading="true",r(!0),t.onBottomReached().finally(()=>{p.dataset.loading="",r(!1)})))},[e.length===0,t==null?void 0:t.onBottomReached]);return h.jsxs("ul",{ref:a,className:"scroll-list",onScroll:t!=null&&t.onBottomReached?C:void 0,style:{scrollBehavior:f},children:[v({items:e,headerBehavior:u,collapsedPaths:m}),t!=null&&t.render?t.render(i):h.jsx(V,{loading:i})]})},_=({stickTo:e,scrollBehavior:t,headerBehavior:g,loading:u,items:m})=>h.jsx(F,{headerBehavior:g,stickTo:e,scrollBehavior:t,children:h.jsx(W,{loading:u,items:m})});exports.Scroll=_;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react/jsx-runtime"),l=require("react"),w=(e=[])=>e.slice(0,e.length-1).map((u,h)=>e.slice(0,h+1)),k=l.createContext({getTopHeadersTotalHeight:()=>0,getBottomHeadersTotalHeight:()=>0,scrollToView:()=>{},setListRef:()=>{},stickTo:"all",scrollBehavior:"smooth",headerBehavior:"none",addHeader:()=>{},headerCollaspeOpen:()=>{},headerCollaspeClose:()=>{},collapsedPaths:[]}),z=()=>l.useContext(k),F=({children:e,stickTo:t="all",scrollBehavior:g="smooth",headerBehavior:u="none"})=>{const[h,p]=l.useState(null),[i,r]=l.useState([]),a=l.useRef({}),b=s=>{const n=a.current[s.join("-")],c=n.nextElementSibling;if(h&&c){const C=window.getComputedStyle(c),d=n.getBoundingClientRect().height,o=f(s),S=parseFloat(C.marginTop)+parseFloat(C.marginBottom)+parseFloat(C.paddingTop)+parseFloat(C.paddingBottom)+parseFloat(C.borderTopWidth)+parseFloat(C.borderBottomWidth),j=Math.ceil(t==="bottom"?c.offsetTop-d:c.offsetTop-o-d+S);h.scrollTo({top:j,behavior:g})}},x=(s,n)=>{a.current[n.join("-")]=s},f=(s=[])=>{const n=w(s),c=n.map(o=>o.join("-"));if(u==="stick"){const o=n.reduce((H,y)=>{const P=y[y.length-1],O=Array.from({length:P},(I,L)=>[...y.slice(0,y.length-1),L]).map(I=>I.join("-"));return H.push(...O),H},[]);c.push(...o);const S=s[s.length-1],j=Array.from({length:S},(H,y)=>[...s.slice(0,s.length-1),y]).map(H=>H.join("-"));c.push(...j)}return c.map(o=>a.current[o]).reduce((o,S)=>{var H;return o+((H=S==null?void 0:S.getBoundingClientRect)==null?void 0:H.call(S).height)||0},0)},T=(s=[])=>{const n=s[s.length-1];return Object.entries(a.current).reduce((d,[o,S])=>{const j=o.split("-").map(Number);return j.length===1&&j[0]>n&&d.push(S),d},[]).reduce((d,o)=>{var j;return d+((j=o==null?void 0:o.getBoundingClientRect)==null?void 0:j.call(o).height)||0},0)},R=s=>{const n=s.join("-");i.includes(n)&&r(c=>c.filter(C=>C!==n))},B=s=>{const n=s.join("-");i.includes(n)||r(c=>[...c,n])};return m.jsx(k.Provider,{value:{addHeader:x,getTopHeadersTotalHeight:f,getBottomHeadersTotalHeight:T,stickTo:t,scrollToView:b,setListRef:p,scrollBehavior:g,headerBehavior:u,headerCollaspeOpen:R,headerCollaspeClose:B,collapsedPaths:i},children:e})},M=({path:e,itemId:t,itemRender:g})=>{const{getTopHeadersTotalHeight:u,getBottomHeadersTotalHeight:h,scrollToView:p,stickTo:i,headerBehavior:r,addHeader:a,headerCollaspeClose:b,headerCollaspeOpen:x,collapsedPaths:f}=z(),T=l.useRef(null),R=()=>{p(e)};l.useEffect(()=>{if(T.current){const d=T.current;a(d,e)}},[T]);const B=l.useMemo(()=>{if(r==="stick"){let d="auto",o="auto";return d=i==="top"||i==="all"?u(e):"auto",o=i==="bottom"||i==="all"?h(e):"auto",{top:d,bottom:o,zIndex:100-e.length}}else if(r==="push")return{top:u(e),zIndex:100-e.length}},[r,e,i]),s=l.useCallback(()=>x(e),[x,e]),n=l.useCallback(()=>b(e),[b,e]),c=l.useMemo(()=>f.includes(e.join("-")),[f]),C=l.useMemo(()=>g({collapse:{open:s,close:n,isOpen:!c}}),[g,c,s,n]);return m.jsx("li",{id:t,onClick:R,className:`scroll-header ${r} `,style:{...B},"aria-label":"Scroll Header",role:"heading","aria-level":e.length,ref:T,children:C})},N=({itemRender:e,itemId:t})=>m.jsx("li",{id:t,role:"listitem","aria-label":"Scroll Item",className:"scroll-item ",children:e({})}),E={display:"none"},v=({headerBehavior:e,items:t,path:g=[],collapsedPaths:u})=>{const h=e==="push"?"section":l.Fragment;return m.jsx("section",{children:t.map((p,i)=>{var a;const r=[...g,i];if((a=p.nestedItems)!=null&&a.length){const x=u.includes(r.join("-"))?E:void 0;return m.jsxs(h,{children:[m.jsx(M,{path:r,itemRender:p.render,itemId:p.id}),m.jsx("section",{style:x,children:v({items:p.nestedItems,headerBehavior:e,path:r,collapsedPaths:u})})]},r.join("-"))}else return m.jsx(N,{itemRender:p.render,itemId:p.id},r.join("-"))})})},V=({loading:e})=>e?m.jsx("li",{role:"listitem","aria-label":"Scroll Loading",className:`scroll-loading ${e?"loading":""}`}):null,W=({items:e,loading:t})=>{const{setListRef:g,headerBehavior:u,collapsedPaths:h,scrollBehavior:p}=z(),[i,r]=l.useState(!1),a=l.useRef(null);l.useEffect(()=>{a.current&&g(a.current)},[a]);const b=l.useCallback(x=>{if(e.length===0||!(t!=null&&t.onBottomReached))return;const f=x.target;Math.floor(f.scrollHeight-f.scrollTop)<f.clientHeight+10&&(f.dataset.loading||(f.dataset.loading="true",r(!0),t.onBottomReached().finally(()=>{f.dataset.loading="",r(!1)})))},[e.length===0,t==null?void 0:t.onBottomReached]);return m.jsxs("ul",{ref:a,className:"scroll-list",onScroll:t!=null&&t.onBottomReached?b:void 0,style:{scrollBehavior:p},children:[v({items:e,headerBehavior:u,collapsedPaths:h}),t!=null&&t.render?t.render(i):m.jsx(V,{loading:i})]})},_=({stickTo:e,scrollBehavior:t,headerBehavior:g,loading:u,items:h})=>m.jsx(F,{headerBehavior:g,stickTo:e,scrollBehavior:t,children:m.jsx(W,{loading:u,items:h})});exports.Scroll=_;
package/dist/es/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { jsx as C, jsxs as w } from "react/jsx-runtime";
2
- import B, { useState as P, useRef as k, useEffect as L, useMemo as j, useCallback as z } from "react";
3
- const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)), O = B.createContext({
1
+ import { jsx as C, jsxs as L } from "react/jsx-runtime";
2
+ import B, { useState as P, useRef as k, useEffect as O, useMemo as j, useCallback as z } from "react";
3
+ const W = (e = []) => e.slice(0, e.length - 1).map((d, m) => e.slice(0, m + 1)), w = B.createContext({
4
4
  getTopHeadersTotalHeight: () => 0,
5
5
  getBottomHeadersTotalHeight: () => 0,
6
6
  scrollToView: () => {
@@ -17,40 +17,40 @@ const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)),
17
17
  headerCollaspeClose: () => {
18
18
  },
19
19
  collapsedPaths: []
20
- }), F = () => B.useContext(O), _ = ({
20
+ }), F = () => B.useContext(w), _ = ({
21
21
  children: e,
22
22
  stickTo: t = "all",
23
23
  scrollBehavior: u = "smooth",
24
24
  headerBehavior: d = "none"
25
25
  }) => {
26
- const [h, m] = P(null), [c, l] = P([]), i = k({}), S = (o) => {
26
+ const [m, g] = P(null), [c, l] = P([]), i = k({}), b = (o) => {
27
27
  const n = i.current[o.join("-")], r = n.nextElementSibling;
28
- if (h && r) {
29
- const p = window.getComputedStyle(r), a = n.getBoundingClientRect().height, s = g(o), f = parseFloat(p.marginTop) + parseFloat(p.marginBottom) + parseFloat(p.paddingTop) + parseFloat(p.paddingBottom) + parseFloat(p.borderTopWidth) + parseFloat(p.borderBottomWidth), H = Math.ceil(t === "bottom" ? r.offsetTop - a : r.offsetTop - s - a + f);
30
- h.scrollTo({ top: H, behavior: u });
28
+ if (m && r) {
29
+ const p = window.getComputedStyle(r), a = n.getBoundingClientRect().height, s = h(o), f = parseFloat(p.marginTop) + parseFloat(p.marginBottom) + parseFloat(p.paddingTop) + parseFloat(p.paddingBottom) + parseFloat(p.borderTopWidth) + parseFloat(p.borderBottomWidth), H = Math.ceil(t === "bottom" ? r.offsetTop - a : r.offsetTop - s - a + f);
30
+ m.scrollTo({ top: H, behavior: u });
31
31
  }
32
- }, T = (o, n) => {
32
+ }, S = (o, n) => {
33
33
  i.current[n.join("-")] = o;
34
- }, g = (o = []) => {
34
+ }, h = (o = []) => {
35
35
  const n = W(o), r = n.map((s) => s.join("-"));
36
36
  if (d === "stick") {
37
- const s = n.reduce((b, y) => {
37
+ const s = n.reduce((T, y) => {
38
38
  const M = y[y.length - 1], E = Array.from({ length: M }, (v, V) => [
39
39
  ...y.slice(0, y.length - 1),
40
40
  V
41
41
  ]).map((v) => v.join("-"));
42
- return b.push(...E), b;
42
+ return T.push(...E), T;
43
43
  }, []);
44
44
  r.push(...s);
45
- const f = o[o.length - 1], H = Array.from({ length: f }, (b, y) => [
45
+ const f = o[o.length - 1], H = Array.from({ length: f }, (T, y) => [
46
46
  ...o.slice(0, o.length - 1),
47
47
  y
48
- ]).map((b) => b.join("-"));
48
+ ]).map((T) => T.join("-"));
49
49
  r.push(...H);
50
50
  }
51
51
  return r.map((s) => i.current[s]).reduce((s, f) => {
52
- var b;
53
- return s + ((b = f == null ? void 0 : f.getBoundingClientRect) == null ? void 0 : b.call(f).height) || 0;
52
+ var T;
53
+ return s + ((T = f == null ? void 0 : f.getBoundingClientRect) == null ? void 0 : T.call(f).height) || 0;
54
54
  }, 0);
55
55
  }, x = (o = []) => {
56
56
  const n = o[o.length - 1];
@@ -69,15 +69,15 @@ const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)),
69
69
  c.includes(n) || l((r) => [...r, n]);
70
70
  };
71
71
  return /* @__PURE__ */ C(
72
- O.Provider,
72
+ w.Provider,
73
73
  {
74
74
  value: {
75
- addHeader: T,
76
- getTopHeadersTotalHeight: g,
75
+ addHeader: S,
76
+ getTopHeadersTotalHeight: h,
77
77
  getBottomHeadersTotalHeight: x,
78
78
  stickTo: t,
79
- scrollToView: S,
80
- setListRef: m,
79
+ scrollToView: b,
80
+ setListRef: g,
81
81
  scrollBehavior: u,
82
82
  headerBehavior: d,
83
83
  headerCollaspeOpen: I,
@@ -90,18 +90,18 @@ const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)),
90
90
  }, A = ({ path: e, itemId: t, itemRender: u }) => {
91
91
  const {
92
92
  getTopHeadersTotalHeight: d,
93
- getBottomHeadersTotalHeight: h,
94
- scrollToView: m,
93
+ getBottomHeadersTotalHeight: m,
94
+ scrollToView: g,
95
95
  stickTo: c,
96
96
  headerBehavior: l,
97
97
  addHeader: i,
98
- headerCollaspeClose: S,
99
- headerCollaspeOpen: T,
100
- collapsedPaths: g
98
+ headerCollaspeClose: b,
99
+ headerCollaspeOpen: S,
100
+ collapsedPaths: h
101
101
  } = F(), x = k(null), I = () => {
102
- m(e);
102
+ g(e);
103
103
  };
104
- L(() => {
104
+ O(() => {
105
105
  if (x.current) {
106
106
  const a = x.current;
107
107
  i(a, e);
@@ -110,10 +110,10 @@ const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)),
110
110
  const R = j(() => {
111
111
  if (l === "stick") {
112
112
  let a = "auto", s = "auto";
113
- return a = c === "top" || c === "all" ? d(e) : "auto", s = c === "bottom" || c === "all" ? h(e) : "auto", { top: a, bottom: s, zIndex: 100 - e.length };
113
+ return a = c === "top" || c === "all" ? d(e) : "auto", s = c === "bottom" || c === "all" ? m(e) : "auto", { top: a, bottom: s, zIndex: 100 - e.length };
114
114
  } else if (l === "push")
115
115
  return { top: d(e), zIndex: 100 - e.length };
116
- }, [l, e, c]), o = z(() => T(e), [T, e]), n = z(() => S(e), [S, e]), r = j(() => g.includes(e.join("-")), [g]), p = j(
116
+ }, [l, e, c]), o = z(() => S(e), [S, e]), n = z(() => b(e), [b, e]), r = j(() => h.includes(e.join("-")), [h]), p = j(
117
117
  () => u({
118
118
  collapse: {
119
119
  open: o,
@@ -137,49 +137,49 @@ const W = (e = []) => e.slice(0, e.length - 1).map((d, h) => e.slice(0, h + 1)),
137
137
  children: p
138
138
  }
139
139
  );
140
- }, $ = ({ itemRender: e, itemId: t }) => /* @__PURE__ */ C("li", { id: t, role: "listitem", "aria-label": "Scroll Item", className: "scroll-item ", children: e({}) }), q = { visibility: "hidden", position: "absolute", width: "0", height: "0" }, N = ({ headerBehavior: e, items: t, path: u = [], collapsedPaths: d }) => {
141
- const h = e === "push" ? "section" : B.Fragment;
142
- return /* @__PURE__ */ C("section", { children: t.map((m, c) => {
140
+ }, $ = ({ itemRender: e, itemId: t }) => /* @__PURE__ */ C("li", { id: t, role: "listitem", "aria-label": "Scroll Item", className: "scroll-item ", children: e({}) }), q = { display: "none" }, N = ({ headerBehavior: e, items: t, path: u = [], collapsedPaths: d }) => {
141
+ const m = e === "push" ? "section" : B.Fragment;
142
+ return /* @__PURE__ */ C("section", { children: t.map((g, c) => {
143
143
  var i;
144
144
  const l = [...u, c];
145
- if ((i = m.nestedItems) != null && i.length) {
146
- const S = d.includes(l.join("-")) ? q : {};
147
- return /* @__PURE__ */ w(h, { children: [
148
- /* @__PURE__ */ C(A, { path: l, itemRender: m.render, itemId: m.id }),
149
- /* @__PURE__ */ C("section", { style: S, children: N({ items: m.nestedItems, headerBehavior: e, path: l, collapsedPaths: d }) })
145
+ if ((i = g.nestedItems) != null && i.length) {
146
+ const S = d.includes(l.join("-")) ? q : void 0;
147
+ return /* @__PURE__ */ L(m, { children: [
148
+ /* @__PURE__ */ C(A, { path: l, itemRender: g.render, itemId: g.id }),
149
+ /* @__PURE__ */ C("section", { style: S, children: N({ items: g.nestedItems, headerBehavior: e, path: l, collapsedPaths: d }) })
150
150
  ] }, l.join("-"));
151
151
  } else
152
- return /* @__PURE__ */ C($, { itemRender: m.render, itemId: m.id }, l.join("-"));
152
+ return /* @__PURE__ */ C($, { itemRender: g.render, itemId: g.id }, l.join("-"));
153
153
  }) });
154
154
  }, D = ({ loading: e }) => e ? /* @__PURE__ */ C("li", { role: "listitem", "aria-label": "Scroll Loading", className: `scroll-loading ${e ? "loading" : ""}` }) : null, G = ({ items: e, loading: t }) => {
155
- const { setListRef: u, headerBehavior: d, collapsedPaths: h, scrollBehavior: m } = F(), [c, l] = B.useState(!1), i = k(null);
156
- L(() => {
155
+ const { setListRef: u, headerBehavior: d, collapsedPaths: m, scrollBehavior: g } = F(), [c, l] = B.useState(!1), i = k(null);
156
+ O(() => {
157
157
  i.current && u(i.current);
158
158
  }, [i]);
159
- const S = z(
160
- (T) => {
159
+ const b = z(
160
+ (S) => {
161
161
  if (e.length === 0 || !(t != null && t.onBottomReached)) return;
162
- const g = T.target;
163
- Math.floor(g.scrollHeight - g.scrollTop) < g.clientHeight + 10 && (g.dataset.loading || (g.dataset.loading = "true", l(!0), t.onBottomReached().finally(() => {
164
- g.dataset.loading = "", l(!1);
162
+ const h = S.target;
163
+ Math.floor(h.scrollHeight - h.scrollTop) < h.clientHeight + 10 && (h.dataset.loading || (h.dataset.loading = "true", l(!0), t.onBottomReached().finally(() => {
164
+ h.dataset.loading = "", l(!1);
165
165
  })));
166
166
  },
167
167
  [e.length === 0, t == null ? void 0 : t.onBottomReached]
168
168
  );
169
- return /* @__PURE__ */ w(
169
+ return /* @__PURE__ */ L(
170
170
  "ul",
171
171
  {
172
172
  ref: i,
173
173
  className: "scroll-list",
174
- onScroll: t != null && t.onBottomReached ? S : void 0,
175
- style: { scrollBehavior: m },
174
+ onScroll: t != null && t.onBottomReached ? b : void 0,
175
+ style: { scrollBehavior: g },
176
176
  children: [
177
- N({ items: e, headerBehavior: d, collapsedPaths: h }),
177
+ N({ items: e, headerBehavior: d, collapsedPaths: m }),
178
178
  t != null && t.render ? t.render(c) : /* @__PURE__ */ C(D, { loading: c })
179
179
  ]
180
180
  }
181
181
  );
182
- }, Q = ({ stickTo: e, scrollBehavior: t, headerBehavior: u, loading: d, items: h }) => /* @__PURE__ */ C(_, { headerBehavior: u, stickTo: e, scrollBehavior: t, children: /* @__PURE__ */ C(G, { loading: d, items: h }) });
182
+ }, Q = ({ stickTo: e, scrollBehavior: t, headerBehavior: u, loading: d, items: m }) => /* @__PURE__ */ C(_, { headerBehavior: u, stickTo: e, scrollBehavior: t, children: /* @__PURE__ */ C(G, { loading: d, items: m }) });
183
183
  export {
184
184
  Q as Scroll
185
185
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galangel/react-scroll-magic",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Powerful scroll component that feels like magic!",
5
5
  "author": "Gal Angel <gal0angel@gmail.com> (@gal.angel)",
6
6
  "keywords": [