@underverse-ui/underverse 1.0.33 → 1.0.35
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/AGENTS.md +15 -9
- package/CHANGELOG.md +79 -0
- package/README.md +50 -19
- package/agent-recipes.json +7 -2
- package/api-reference.json +30 -2
- package/dist/index.cjs +2736 -2536
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -13
- package/dist/index.d.ts +49 -13
- package/dist/index.js +2191 -1993
- package/dist/index.js.map +1 -1
- package/llms.txt +7 -6
- package/package.json +3 -1
package/AGENTS.md
CHANGED
|
@@ -40,30 +40,36 @@ export function Example() {
|
|
|
40
40
|
}
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
## Overlay Scrollbars (
|
|
43
|
+
## Overlay Scrollbars (opt-in)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Underverse uses component-level overlay scrollbars. No global selector scan and no app-wide MutationObserver.
|
|
46
46
|
|
|
47
47
|
```tsx
|
|
48
48
|
import "overlayscrollbars/overlayscrollbars.css";
|
|
49
|
-
import { OverlayScrollbarProvider } from "@underverse-ui/underverse";
|
|
49
|
+
import { OverlayScrollbarProvider, ScrollArea, DataTable } from "@underverse-ui/underverse";
|
|
50
50
|
|
|
51
51
|
export function App() {
|
|
52
52
|
return (
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
{
|
|
56
|
-
|
|
53
|
+
<OverlayScrollbarProvider theme="os-theme-underverse" autoHide="leave">
|
|
54
|
+
<ScrollArea className="h-56" useOverlayScrollbar />
|
|
55
|
+
<DataTable columns={columns} data={rows} useOverlayScrollbar />
|
|
56
|
+
</OverlayScrollbarProvider>
|
|
57
57
|
);
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
Behavior:
|
|
62
62
|
|
|
63
|
-
- Provider
|
|
64
|
-
-
|
|
63
|
+
- Provider is config-only (context defaults), not an auto-mount global scanner.
|
|
64
|
+
- Enable per component via `useOverlayScrollbar`.
|
|
65
|
+
- Hard skip: `html`, `body`, `[data-radix-portal]`, `[role="dialog"]`, `[aria-modal="true"]`, `[data-sonner-toaster]`.
|
|
65
66
|
- Use `data-os-ignore` on a node to opt out.
|
|
66
67
|
|
|
68
|
+
Useful APIs:
|
|
69
|
+
|
|
70
|
+
- `OverlayScrollArea` (dedicated heavy-scroll wrapper)
|
|
71
|
+
- `useOverlayScrollbarTarget(ref, options)` for custom component internals
|
|
72
|
+
|
|
67
73
|
## i18n Notes
|
|
68
74
|
|
|
69
75
|
- Components work without `next-intl` using fallback translations.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@underverse-ui/underverse` are documented in this file.
|
|
4
|
+
|
|
5
|
+
## [1.0.34] - 2026-02-24
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Switched OverlayScrollbars architecture to strict component-level opt-in.
|
|
10
|
+
- `OverlayScrollbarProvider` is now config-only (no global DOM scan, no global MutationObserver).
|
|
11
|
+
- Added dedicated `OverlayScrollArea` wrapper for heavy scroll zones.
|
|
12
|
+
- Added `useOverlayScrollbar?: boolean` (default `false`) on:
|
|
13
|
+
- `ScrollArea`
|
|
14
|
+
- `Table`
|
|
15
|
+
- `DataTable`
|
|
16
|
+
- `Combobox`
|
|
17
|
+
- `MultiCombobox`
|
|
18
|
+
- `CategoryTreeSelect`
|
|
19
|
+
- Hard skip safety kept for:
|
|
20
|
+
- `html`, `body`
|
|
21
|
+
- `[data-radix-portal]`
|
|
22
|
+
- `[role=\"dialog\"]`
|
|
23
|
+
- `[aria-modal=\"true\"]`
|
|
24
|
+
- `[data-sonner-toaster]`
|
|
25
|
+
- Removed global selector behavior from docs/recipes and marked `selector` prop deprecated (ignored).
|
|
26
|
+
|
|
27
|
+
## [1.0.32] - 2026-02-24
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Standardized OverlayScrollbars initialization to explicit marker targeting only:
|
|
32
|
+
- Provider now initializes only on `[data-os-scrollbar]`.
|
|
33
|
+
- Removed generic overflow class scanning (`.overflow-*`).
|
|
34
|
+
- Hardened provider behavior for production:
|
|
35
|
+
- No initialization on `document.body` / `document.documentElement`.
|
|
36
|
+
- Excludes portal / modal / toast trees:
|
|
37
|
+
- `[data-radix-portal]`
|
|
38
|
+
- `[role="dialog"]`
|
|
39
|
+
- `[aria-modal="true"]`
|
|
40
|
+
- `[data-sonner-toaster]`
|
|
41
|
+
- Supports node-level opt-out with `data-os-ignore`.
|
|
42
|
+
- Added provider configuration props:
|
|
43
|
+
- `enabled` (default `true`)
|
|
44
|
+
- `theme` (default `os-theme-underverse`)
|
|
45
|
+
- `visibility`
|
|
46
|
+
- `autoHide`
|
|
47
|
+
- `autoHideDelay`
|
|
48
|
+
- `dragScroll`
|
|
49
|
+
- `clickScroll`
|
|
50
|
+
- `selector` (default `.overflow-auto, .overflow-y-auto, .overflow-x-auto, .overflow-scroll, .overflow-y-scroll, .overflow-x-scroll, textarea, [data-os-scrollbar]`)
|
|
51
|
+
- `exclude` (default `html, body, [data-os-ignore], [data-radix-portal], [role='dialog'], [aria-modal='true'], [data-sonner-toaster]`)
|
|
52
|
+
- Exported provider prop type:
|
|
53
|
+
- `OverlayScrollbarProviderProps`
|
|
54
|
+
|
|
55
|
+
### Updated Components
|
|
56
|
+
|
|
57
|
+
- Provider now covers common scrollable surfaces by default via global selector, so Underverse components do not require per-component manual marker wiring.
|
|
58
|
+
|
|
59
|
+
### Internal
|
|
60
|
+
|
|
61
|
+
- `Popover` now sets `role="dialog"` only when `modal=true`, avoiding accidental exclusion for non-modal popovers.
|
|
62
|
+
- Moved to default global selector behavior, so apps no longer need to add `data-os-scrollbar` manually to each Underverse component.
|
|
63
|
+
|
|
64
|
+
### Testing
|
|
65
|
+
|
|
66
|
+
- Added controller-level tests for:
|
|
67
|
+
- selector initialization
|
|
68
|
+
- exclude behavior
|
|
69
|
+
- dynamic add/remove cleanup
|
|
70
|
+
- portal safety with wide selectors
|
|
71
|
+
- destroy cleanup (memory leak prevention)
|
|
72
|
+
|
|
73
|
+
### Migration
|
|
74
|
+
|
|
75
|
+
- Mount a single `OverlayScrollbarProvider` from the package at app root.
|
|
76
|
+
- Remove app-local DOM-scanning scrollbar providers.
|
|
77
|
+
- Keep `overlayscrollbars/overlayscrollbars.css` imported globally.
|
|
78
|
+
- Default is already global selector mode. Override `selector` only if you need custom scope.
|
|
79
|
+
- For app-specific opt-out nodes, use `data-os-ignore`.
|
package/README.md
CHANGED
|
@@ -137,39 +137,70 @@ import { Form, FormField, FormItem, FormLabel, FormMessage } from "@underverse-u
|
|
|
137
137
|
|
|
138
138
|
### Overlay Scrollbars (Optional, Recommended)
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
Underverse now uses **opt-in, component-level** OverlayScrollbars.
|
|
141
|
+
There is no global DOM scanning, no default global mount, and no app-wide MutationObserver.
|
|
141
142
|
|
|
142
143
|
```tsx
|
|
143
144
|
import "overlayscrollbars/overlayscrollbars.css";
|
|
144
|
-
import { OverlayScrollbarProvider } from "@underverse-ui/underverse";
|
|
145
|
+
import { OverlayScrollbarProvider, ScrollArea, DataTable } from "@underverse-ui/underverse";
|
|
145
146
|
|
|
146
147
|
function App() {
|
|
147
148
|
return (
|
|
148
|
-
|
|
149
|
-
<
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
<OverlayScrollbarProvider theme="os-theme-underverse" autoHide="leave">
|
|
150
|
+
<ScrollArea className="h-56" useOverlayScrollbar>
|
|
151
|
+
{/* long content */}
|
|
152
|
+
</ScrollArea>
|
|
153
|
+
|
|
154
|
+
<DataTable
|
|
155
|
+
columns={columns}
|
|
156
|
+
data={rows}
|
|
157
|
+
useOverlayScrollbar
|
|
154
158
|
/>
|
|
155
|
-
|
|
156
|
-
</>
|
|
159
|
+
</OverlayScrollbarProvider>
|
|
157
160
|
);
|
|
158
161
|
}
|
|
159
162
|
```
|
|
160
163
|
|
|
161
164
|
Provider behavior:
|
|
162
165
|
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
- Per-node opt-out
|
|
166
|
+
- Provider is **configuration only** (theme/options context).
|
|
167
|
+
- Scrollbars initialize only on components explicitly enabled via `useOverlayScrollbar`.
|
|
168
|
+
- Hard skip targets: `html`, `body`, `[data-radix-portal]`, `[role="dialog"]`, `[aria-modal="true"]`, `[data-sonner-toaster]`.
|
|
169
|
+
- Per-node opt-out remains available via `data-os-ignore`.
|
|
167
170
|
|
|
168
|
-
|
|
171
|
+
Provider props:
|
|
169
172
|
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
+
- `enabled?: boolean`
|
|
174
|
+
- `theme?: string`
|
|
175
|
+
- `visibility?: "visible" | "hidden" | "auto"`
|
|
176
|
+
- `autoHide?: "never" | "scroll" | "leave" | "move"`
|
|
177
|
+
- `autoHideDelay?: number`
|
|
178
|
+
- `dragScroll?: boolean`
|
|
179
|
+
- `clickScroll?: boolean`
|
|
180
|
+
- `exclude?: string` default: `html, body, [data-os-ignore], [data-radix-portal], [role='dialog'], [aria-modal='true'], [data-sonner-toaster]`
|
|
181
|
+
- `selector?: string` (deprecated, ignored; kept for backward compatibility)
|
|
182
|
+
|
|
183
|
+
Component-level enable flags:
|
|
184
|
+
|
|
185
|
+
- `ScrollArea`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
186
|
+
- `Table`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
187
|
+
- `DataTable`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
188
|
+
- `Combobox`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
189
|
+
- `MultiCombobox`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
190
|
+
- `CategoryTreeSelect`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
191
|
+
- `Textarea`: `useOverlayScrollbar?: boolean` (default `false`)
|
|
192
|
+
- `OverlayScrollArea`: dedicated wrapper for heavy scroll zones (`enabled` default `true`)
|
|
193
|
+
|
|
194
|
+
When to use:
|
|
195
|
+
|
|
196
|
+
- Long virtualized/table/list panels
|
|
197
|
+
- Fixed-height navigation panels and log viewers
|
|
198
|
+
|
|
199
|
+
When not to use:
|
|
200
|
+
|
|
201
|
+
- Normal form fields
|
|
202
|
+
- Short modal/dialog content
|
|
203
|
+
- Full page root scrolling
|
|
173
204
|
|
|
174
205
|
### Standalone React (Vite, CRA, etc.)
|
|
175
206
|
|
|
@@ -231,7 +262,7 @@ function App() {
|
|
|
231
262
|
|
|
232
263
|
### Navigation & Structure
|
|
233
264
|
|
|
234
|
-
- `Breadcrumb`, `Tabs` (includes `SimpleTabs`, `PillTabs`, `VerticalTabs`), `DropdownMenu`, `Pagination`, `Section`, `ScrollArea`
|
|
265
|
+
- `Breadcrumb`, `Tabs` (includes `SimpleTabs`, `PillTabs`, `VerticalTabs`), `DropdownMenu`, `Pagination`, `Section`, `ScrollArea`, `OverlayScrollArea`
|
|
235
266
|
|
|
236
267
|
### Data Display
|
|
237
268
|
|
package/agent-recipes.json
CHANGED
|
@@ -25,8 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"id": "overlay-scrollbar-provider",
|
|
28
|
-
"title": "Enable overlay scrollbars",
|
|
29
|
-
"code": "import \"overlayscrollbars/overlayscrollbars.css\";\nimport { OverlayScrollbarProvider } from \"@underverse-ui/underverse\";\n\nexport function App(){\n return
|
|
28
|
+
"title": "Enable overlay scrollbars (opt-in)",
|
|
29
|
+
"code": "import \"overlayscrollbars/overlayscrollbars.css\";\nimport { OverlayScrollbarProvider, ScrollArea } from \"@underverse-ui/underverse\";\n\nexport function App(){\n return (\n <OverlayScrollbarProvider theme=\"os-theme-underverse\" autoHide=\"leave\">\n <ScrollArea className=\"h-56\" useOverlayScrollbar>{/* content */}</ScrollArea>\n </OverlayScrollbarProvider>\n );\n}\n"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "overlay-scrollbar-custom-component",
|
|
33
|
+
"title": "Custom component with overlay scrollbar hook",
|
|
34
|
+
"code": "import { useRef } from \"react\";\nimport { useOverlayScrollbarTarget } from \"@underverse-ui/underverse\";\n\nexport function LogPanel(){\n const ref = useRef<HTMLDivElement>(null);\n useOverlayScrollbarTarget(ref, { enabled: true });\n\n return <div ref={ref} className=\"h-64 overflow-y-auto\">...</div>;\n}\n"
|
|
30
35
|
},
|
|
31
36
|
{
|
|
32
37
|
"id": "api-discovery-order",
|
package/api-reference.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "@underverse-ui/underverse",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.35",
|
|
4
4
|
"sourceEntry": "src/index.ts",
|
|
5
|
-
"totalExports":
|
|
5
|
+
"totalExports": 211,
|
|
6
6
|
"exports": [
|
|
7
7
|
{
|
|
8
8
|
"name": "*",
|
|
@@ -854,6 +854,20 @@
|
|
|
854
854
|
"local": false,
|
|
855
855
|
"aliasOf": "default"
|
|
856
856
|
},
|
|
857
|
+
{
|
|
858
|
+
"name": "OverlayScrollArea",
|
|
859
|
+
"kind": "value",
|
|
860
|
+
"source": "../../../components/ui/OverlayScrollArea",
|
|
861
|
+
"reexport": true,
|
|
862
|
+
"local": false
|
|
863
|
+
},
|
|
864
|
+
{
|
|
865
|
+
"name": "OverlayScrollAreaProps",
|
|
866
|
+
"kind": "type",
|
|
867
|
+
"source": "../../../components/ui/OverlayScrollArea",
|
|
868
|
+
"reexport": true,
|
|
869
|
+
"local": false
|
|
870
|
+
},
|
|
857
871
|
{
|
|
858
872
|
"name": "OverlayScrollbarProvider",
|
|
859
873
|
"kind": "value",
|
|
@@ -1408,6 +1422,20 @@
|
|
|
1408
1422
|
"reexport": true,
|
|
1409
1423
|
"local": false
|
|
1410
1424
|
},
|
|
1425
|
+
{
|
|
1426
|
+
"name": "useOverlayScrollbarTarget",
|
|
1427
|
+
"kind": "value",
|
|
1428
|
+
"source": "../../../components/ui/OverlayScrollbarProvider",
|
|
1429
|
+
"reexport": true,
|
|
1430
|
+
"local": false
|
|
1431
|
+
},
|
|
1432
|
+
{
|
|
1433
|
+
"name": "UseOverlayScrollbarTargetOptions",
|
|
1434
|
+
"kind": "type",
|
|
1435
|
+
"source": "../../../components/ui/OverlayScrollbarProvider",
|
|
1436
|
+
"reexport": true,
|
|
1437
|
+
"local": false
|
|
1438
|
+
},
|
|
1411
1439
|
{
|
|
1412
1440
|
"name": "useShadCNAnimations",
|
|
1413
1441
|
"kind": "value",
|