overflow-toolbar 0.1.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/LICENSE +21 -0
- package/README.md +258 -0
- package/dist/components/MuiOverflow/MuiOverflow.d.ts +4 -0
- package/dist/components/MuiOverflow/MuiOverflow.d.ts.map +1 -0
- package/dist/components/MuiOverflow/MuiOverflow.js +7 -0
- package/dist/components/MuiOverflow/MuiOverflow.js.map +1 -0
- package/dist/components/MuiOverflow/MuiOverflowItem.d.ts +12 -0
- package/dist/components/MuiOverflow/MuiOverflowItem.d.ts.map +1 -0
- package/dist/components/MuiOverflow/MuiOverflowItem.js +12 -0
- package/dist/components/MuiOverflow/MuiOverflowItem.js.map +1 -0
- package/dist/components/MuiOverflow/MuiOverflowMenu.d.ts +11 -0
- package/dist/components/MuiOverflow/MuiOverflowMenu.d.ts.map +1 -0
- package/dist/components/MuiOverflow/MuiOverflowMenu.js +11 -0
- package/dist/components/MuiOverflow/MuiOverflowMenu.js.map +1 -0
- package/dist/components/MuiOverflow/index.d.ts +4 -0
- package/dist/components/MuiOverflow/index.d.ts.map +1 -0
- package/dist/components/NoFrameworkOverflow/NoFrameworkOverflow.d.ts +22 -0
- package/dist/components/NoFrameworkOverflow/NoFrameworkOverflow.d.ts.map +1 -0
- package/dist/components/NoFrameworkOverflow/NoFrameworkOverflow.js +79 -0
- package/dist/components/NoFrameworkOverflow/NoFrameworkOverflow.js.map +1 -0
- package/dist/components/NoFrameworkOverflow/index.d.ts +3 -0
- package/dist/components/NoFrameworkOverflow/index.d.ts.map +1 -0
- package/dist/components/NoFrameworkOverflow/noframework.css +110 -0
- package/dist/components/Overflow/Overflow.css +1 -0
- package/dist/components/Overflow/Overflow.d.ts +12 -0
- package/dist/components/Overflow/Overflow.d.ts.map +1 -0
- package/dist/components/Overflow/Overflow.js +34 -0
- package/dist/components/Overflow/Overflow.js.map +1 -0
- package/dist/components/Overflow/OverflowContext.d.ts +7 -0
- package/dist/components/Overflow/OverflowContext.d.ts.map +1 -0
- package/dist/components/Overflow/OverflowContext.js +13 -0
- package/dist/components/Overflow/OverflowContext.js.map +1 -0
- package/dist/components/Overflow/OverflowController.d.ts +50 -0
- package/dist/components/Overflow/OverflowController.d.ts.map +1 -0
- package/dist/components/Overflow/OverflowController.js +146 -0
- package/dist/components/Overflow/OverflowController.js.map +1 -0
- package/dist/components/Overflow/OverflowItem.d.ts +12 -0
- package/dist/components/Overflow/OverflowItem.d.ts.map +1 -0
- package/dist/components/Overflow/OverflowItem.js +17 -0
- package/dist/components/Overflow/OverflowItem.js.map +1 -0
- package/dist/components/Overflow/OverflowMenu.d.ts +18 -0
- package/dist/components/Overflow/OverflowMenu.d.ts.map +1 -0
- package/dist/components/Overflow/OverflowMenu.js +36 -0
- package/dist/components/Overflow/OverflowMenu.js.map +1 -0
- package/dist/components/Overflow/index.d.ts +10 -0
- package/dist/components/Overflow/index.d.ts.map +1 -0
- package/dist/components/Overflow/overflowSteps.d.ts +26 -0
- package/dist/components/Overflow/overflowSteps.d.ts.map +1 -0
- package/dist/components/Overflow/overflowSteps.js +32 -0
- package/dist/components/Overflow/overflowSteps.js.map +1 -0
- package/dist/components/Overflow/useResizer.d.ts +3 -0
- package/dist/components/Overflow/useResizer.d.ts.map +1 -0
- package/dist/components/Overflow/useResizer.js +18 -0
- package/dist/components/Overflow/useResizer.js.map +1 -0
- package/dist/components/RxOverflow/RxOverflow.d.ts +5 -0
- package/dist/components/RxOverflow/RxOverflow.d.ts.map +1 -0
- package/dist/components/RxOverflow/RxOverflow.js +11 -0
- package/dist/components/RxOverflow/RxOverflow.js.map +1 -0
- package/dist/components/RxOverflow/RxOverflowItem.d.ts +12 -0
- package/dist/components/RxOverflow/RxOverflowItem.d.ts.map +1 -0
- package/dist/components/RxOverflow/RxOverflowItem.js +10 -0
- package/dist/components/RxOverflow/RxOverflowItem.js.map +1 -0
- package/dist/components/RxOverflow/RxOverflowMenu.d.ts +11 -0
- package/dist/components/RxOverflow/RxOverflowMenu.d.ts.map +1 -0
- package/dist/components/RxOverflow/RxOverflowMenu.js +33 -0
- package/dist/components/RxOverflow/RxOverflowMenu.js.map +1 -0
- package/dist/components/RxOverflow/cn.d.ts +3 -0
- package/dist/components/RxOverflow/cn.d.ts.map +1 -0
- package/dist/components/RxOverflow/cn.js +9 -0
- package/dist/components/RxOverflow/cn.js.map +1 -0
- package/dist/components/RxOverflow/index.d.ts +5 -0
- package/dist/components/RxOverflow/index.d.ts.map +1 -0
- package/dist/components/RxOverflow/rx.css +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/mui.js +9 -0
- package/dist/mui.js.map +1 -0
- package/dist/overflow.js +14 -0
- package/dist/overflow.js.map +1 -0
- package/dist/rx.js +11 -0
- package/dist/rx.js.map +1 -0
- package/dist/vanilla.js +5 -0
- package/dist/vanilla.js.map +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +176 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Wes Jones
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Overflow
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/overflow-toolbar)
|
|
4
|
+
[](https://bundlephobia.com/package/overflow-toolbar)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://github.com/wesjones/overflow/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
A responsive toolbar overflow component that automatically collapses items into a dropdown menu as the container shrinks. Items transition through three states: **visible** → **min** (icon-only) → **hidden** (moved to menu).
|
|
9
|
+
|
|
10
|
+
<a href="https://wesjones.github.io/overflow/" target="_blank"><strong>Live Demo</strong></a>
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- **Automatic overflow detection** — items collapse into a menu as the container narrows using ResizeObserver
|
|
15
|
+
- **Three item states** — visible, min (icon-only), and hidden (in menu)
|
|
16
|
+
- **Compact mode** — items collapse one at a time instead of all at once
|
|
17
|
+
- **Reverse mode** — collapse from the left instead of the right
|
|
18
|
+
- **Menu-only items** — items that always live in the dropdown (e.g. Help, About)
|
|
19
|
+
- **Min state** — items shrink to icon-only before being fully hidden
|
|
20
|
+
- **Three implementations** — React/Radix UI, Material UI, and vanilla JavaScript
|
|
21
|
+
- **Tree-shakeable** — import only the variant you need via subpath exports
|
|
22
|
+
- **TypeScript** — full type declarations included
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install overflow-toolbar
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Radix UI (React)
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { RxOverflow, RxOverflowItem, RxOverflowMenu } from 'overflow-toolbar/rx';
|
|
36
|
+
import 'overflow-toolbar/rx/styles';
|
|
37
|
+
import 'overflow-toolbar/styles';
|
|
38
|
+
|
|
39
|
+
<RxOverflow style={{ gap: 8 }}>
|
|
40
|
+
<RxOverflowMenu opener={<button>More</button>}>
|
|
41
|
+
<RxOverflowItem menuid="format"><button>Format</button></RxOverflowItem>
|
|
42
|
+
<RxOverflowItem menuid="filter"><button>Filters</button></RxOverflowItem>
|
|
43
|
+
</RxOverflowMenu>
|
|
44
|
+
|
|
45
|
+
<RxOverflowItem menuid="format"><button>Format</button></RxOverflowItem>
|
|
46
|
+
<RxOverflowItem menuid="filter"><button>Filters</button></RxOverflowItem>
|
|
47
|
+
</RxOverflow>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Material UI (React)
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
import { MuiOverflow, MuiOverflowItem, MuiOverflowMenu } from 'overflow-toolbar/mui';
|
|
54
|
+
import 'overflow-toolbar/styles';
|
|
55
|
+
import { Button, MenuItem } from '@mui/material';
|
|
56
|
+
|
|
57
|
+
<MuiOverflow sx={{ gap: 1 }}>
|
|
58
|
+
<MuiOverflowMenu opener={<Button>More</Button>}>
|
|
59
|
+
<MuiOverflowItem menuid="format"><MenuItem>Format</MenuItem></MuiOverflowItem>
|
|
60
|
+
<MuiOverflowItem menuid="filter"><MenuItem>Filters</MenuItem></MuiOverflowItem>
|
|
61
|
+
</MuiOverflowMenu>
|
|
62
|
+
|
|
63
|
+
<MuiOverflowItem menuid="format"><Button>Format</Button></MuiOverflowItem>
|
|
64
|
+
<MuiOverflowItem menuid="filter"><Button>Filters</Button></MuiOverflowItem>
|
|
65
|
+
</MuiOverflow>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Vanilla JavaScript
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
import { OverflowToolbar } from 'overflow-toolbar/vanilla';
|
|
72
|
+
import 'overflow-toolbar/vanilla/styles';
|
|
73
|
+
import 'overflow-toolbar/styles';
|
|
74
|
+
|
|
75
|
+
const ul = document.querySelector('#my-toolbar');
|
|
76
|
+
const toolbar = new OverflowToolbar(ul);
|
|
77
|
+
|
|
78
|
+
// Later: toolbar.update() after DOM changes
|
|
79
|
+
// Cleanup: toolbar.destroy()
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
```html
|
|
83
|
+
<ul id="my-toolbar">
|
|
84
|
+
<li data-overflow-role="menu">
|
|
85
|
+
<button data-menu-trigger>More</button>
|
|
86
|
+
<div data-menu-panel>
|
|
87
|
+
<button data-menuid="format">Format</button>
|
|
88
|
+
<button data-menuid="filter">Filters</button>
|
|
89
|
+
</div>
|
|
90
|
+
</li>
|
|
91
|
+
<li data-overflow-role="item" data-menuid="format">
|
|
92
|
+
<button>Format</button>
|
|
93
|
+
</li>
|
|
94
|
+
<li data-overflow-role="item" data-menuid="filter">
|
|
95
|
+
<button>Filters</button>
|
|
96
|
+
</li>
|
|
97
|
+
</ul>
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Subpath Imports
|
|
101
|
+
|
|
102
|
+
Import only what you need for optimal tree-shaking:
|
|
103
|
+
|
|
104
|
+
| Import path | Contents |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `overflow-toolbar` | Everything (all variants) |
|
|
107
|
+
| `overflow-toolbar/core` | Core React components (`Overflow`, `OverflowItem`, `OverflowMenu`, `OverflowController`) |
|
|
108
|
+
| `overflow-toolbar/rx` | Radix UI variant (`RxOverflow`, `RxOverflowItem`, `RxOverflowMenu`) |
|
|
109
|
+
| `overflow-toolbar/mui` | Material UI variant (`MuiOverflow`, `MuiOverflowItem`, `MuiOverflowMenu`) |
|
|
110
|
+
| `overflow-toolbar/vanilla` | Vanilla JS (`OverflowToolbar`) |
|
|
111
|
+
| `overflow-toolbar/styles` | Core CSS (required by all variants) |
|
|
112
|
+
| `overflow-toolbar/rx/styles` | Radix UI styles |
|
|
113
|
+
| `overflow-toolbar/vanilla/styles` | Vanilla JS styles |
|
|
114
|
+
|
|
115
|
+
## API
|
|
116
|
+
|
|
117
|
+
### `Overflow` / `RxOverflow` / `MuiOverflow`
|
|
118
|
+
|
|
119
|
+
The container component. Wraps toolbar items and the overflow menu.
|
|
120
|
+
|
|
121
|
+
| Prop | Type | Default | Description |
|
|
122
|
+
|---|---|---|---|
|
|
123
|
+
| `children` | `ReactNode` | — | Overflow items and menu |
|
|
124
|
+
| `compact` | `boolean` | `false` | Collapse items one at a time |
|
|
125
|
+
| `reverse` | `boolean` | `false` | Collapse from the left |
|
|
126
|
+
| `className` | `string` | — | CSS class name |
|
|
127
|
+
| `style` | `CSSProperties` | — | Inline styles |
|
|
128
|
+
| `sx` | `SxProps` | — | MUI system props (MUI only) |
|
|
129
|
+
|
|
130
|
+
### `OverflowItem` / `RxOverflowItem` / `MuiOverflowItem`
|
|
131
|
+
|
|
132
|
+
Wraps each toolbar item. Place matching items in both the toolbar and the menu, linked by `menuid`.
|
|
133
|
+
|
|
134
|
+
| Prop | Type | Default | Description |
|
|
135
|
+
|---|---|---|---|
|
|
136
|
+
| `children` | `ReactNode` | — | Item content |
|
|
137
|
+
| `menuid` | `string` | — | Links toolbar item to its menu counterpart |
|
|
138
|
+
| `minStateWidth` | `string` \| `number` | — | Width in min state (`string` for Rx, `number` for MUI spacing units) |
|
|
139
|
+
|
|
140
|
+
### `OverflowMenu` / `RxOverflowMenu` / `MuiOverflowMenu`
|
|
141
|
+
|
|
142
|
+
The dropdown menu container. Must include an `opener` element (the trigger button).
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Description |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `children` | `ReactNode` | Menu items |
|
|
147
|
+
| `opener` | `ReactNode` | The button that opens the menu |
|
|
148
|
+
|
|
149
|
+
### `OverflowController`
|
|
150
|
+
|
|
151
|
+
Framework-agnostic controller class for building custom implementations.
|
|
152
|
+
|
|
153
|
+
| Method | Description |
|
|
154
|
+
|---|---|
|
|
155
|
+
| `connect()` | Start observing and apply initial state |
|
|
156
|
+
| `disconnect()` | Stop observing and clear all applied styles/attributes |
|
|
157
|
+
| `update()` | Re-scan children and restart (call after DOM changes) |
|
|
158
|
+
|
|
159
|
+
## Modes
|
|
160
|
+
|
|
161
|
+
### Compact Mode
|
|
162
|
+
|
|
163
|
+
Items collapse one at a time with tight spacing. Adjacent buttons get squared-off corners for a grouped look:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
<RxOverflow compact>
|
|
167
|
+
{/* items... */}
|
|
168
|
+
</RxOverflow>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Reverse Mode
|
|
172
|
+
|
|
173
|
+
Items collapse from the left side first instead of the right:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
<RxOverflow reverse>
|
|
177
|
+
{/* items... */}
|
|
178
|
+
</RxOverflow>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Min State
|
|
182
|
+
|
|
183
|
+
Items shrink to a fixed width (icon-only) before being fully hidden:
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<RxOverflowItem menuid="format" minStateWidth="2.25rem">
|
|
187
|
+
<button><FormatIcon /> Format</button>
|
|
188
|
+
</RxOverflowItem>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
For MUI, `minStateWidth` accepts a number (theme spacing units):
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<MuiOverflowItem menuid="format" minStateWidth={5}>
|
|
195
|
+
<Button><FormatIcon /> Format</Button>
|
|
196
|
+
</MuiOverflowItem>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Menu-Only Items
|
|
200
|
+
|
|
201
|
+
Items without a `menuid` always stay where they are — in the toolbar or in the menu:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<RxOverflowMenu opener={<button>More</button>}>
|
|
205
|
+
<RxOverflowItem menuid="format"><button>Format</button></RxOverflowItem>
|
|
206
|
+
{/* Always in the menu */}
|
|
207
|
+
<RxOverflowItem><div role="separator" /></RxOverflowItem>
|
|
208
|
+
<RxOverflowItem><button>Help</button></RxOverflowItem>
|
|
209
|
+
</RxOverflowMenu>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Vanilla JS
|
|
213
|
+
|
|
214
|
+
The vanilla implementation uses `data-` attributes for configuration:
|
|
215
|
+
|
|
216
|
+
| Attribute | Element | Description |
|
|
217
|
+
|---|---|---|
|
|
218
|
+
| `data-overflow-role="item"` | `<li>` | Marks a toolbar item |
|
|
219
|
+
| `data-overflow-role="menu"` | `<li>` | Marks the menu container |
|
|
220
|
+
| `data-menuid` | `<li>`, menu item | Links toolbar and menu items |
|
|
221
|
+
| `data-min-state-width` | `<li>` | Min-state width (CSS value) |
|
|
222
|
+
| `data-menu-trigger` | `<button>` | The menu open/close button |
|
|
223
|
+
| `data-menu-panel` | `<div>` | The menu panel (uses Popover API) |
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const toolbar = new OverflowToolbar(document.querySelector('ul'), {
|
|
227
|
+
compact: true,
|
|
228
|
+
reverse: false,
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
toolbar.update(); // after DOM changes
|
|
232
|
+
toolbar.destroy(); // cleanup
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Browser Support
|
|
236
|
+
|
|
237
|
+
Requires [ResizeObserver](https://caniuse.com/resizeobserver) (all modern browsers). The vanilla JS variant also uses the [Popover API](https://caniuse.com/mdn-api_htmlelement_popover) for the dropdown menu.
|
|
238
|
+
|
|
239
|
+
## Contributing
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
git clone https://github.com/wesjones/overflow.git
|
|
243
|
+
cd overflow
|
|
244
|
+
pnpm install
|
|
245
|
+
pnpm storybook # dev with Storybook on port 6006
|
|
246
|
+
pnpm test:unit # run unit tests
|
|
247
|
+
pnpm build:lib # build the library
|
|
248
|
+
pnpm typecheck # check types
|
|
249
|
+
pnpm lint # lint
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Also Known As
|
|
253
|
+
|
|
254
|
+
This component implements what is commonly known as a responsive toolbar, overflow menu, adaptive toolbar, collapsible toolbar, priority+ pattern, priority-plus navigation, toolbar button group overflow, responsive action bar, command bar, or "more menu." It handles responsive buttons, auto-collapse, icon-only collapse, and dynamic toolbar resizing using ResizeObserver.
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflow.d.ts","sourceRoot":"","sources":["../../../src/components/MuiOverflow/MuiOverflow.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,aAAa,CAAC,aAAa,CAAwB,CAAC;AAE7E,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflow.js","sources":["../../../src/components/MuiOverflow/MuiOverflow.tsx"],"sourcesContent":["import { styled } from '@mui/material/styles';\nimport type { OverflowProps } from '../Overflow';\nimport { Overflow } from '../Overflow';\n\nconst MuiOverflow: React.ComponentType<OverflowProps> = styled(Overflow)({});\n\nexport default MuiOverflow;\n"],"names":["MuiOverflow","styled","Overflow"],"mappings":";;AAIA,MAAMA,IAAkDC,EAAOC,CAAQ,EAAE,CAAA,CAAE;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
interface MuiOverflowItemProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
menuid?: string;
|
|
5
|
+
minStateWidth?: number;
|
|
6
|
+
}
|
|
7
|
+
declare function MuiOverflowItem({ children, menuid, minStateWidth }: MuiOverflowItemProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare const _default: typeof MuiOverflowItem & {
|
|
9
|
+
overflowRole: "item";
|
|
10
|
+
};
|
|
11
|
+
export default _default;
|
|
12
|
+
//# sourceMappingURL=MuiOverflowItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflowItem.d.ts","sourceRoot":"","sources":["../../../src/components/MuiOverflow/MuiOverflowItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,iBAAS,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,oBAAoB,2CASjF;;;;AAED,wBAAiF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as m } from "react/jsx-runtime";
|
|
2
|
+
import { useTheme as s } from "@mui/material/styles";
|
|
3
|
+
import f from "../Overflow/OverflowItem.js";
|
|
4
|
+
function n({ children: o, menuid: t, minStateWidth: e }) {
|
|
5
|
+
const r = s(), i = e !== void 0 ? r.spacing(e) : void 0;
|
|
6
|
+
return /* @__PURE__ */ m(f, { menuid: t, minStateWidth: i, children: o });
|
|
7
|
+
}
|
|
8
|
+
const v = Object.assign(n, { overflowRole: "item" });
|
|
9
|
+
export {
|
|
10
|
+
v as default
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=MuiOverflowItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflowItem.js","sources":["../../../src/components/MuiOverflow/MuiOverflowItem.tsx"],"sourcesContent":["import { useTheme } from '@mui/material/styles';\nimport type { ReactNode } from 'react';\nimport { OverflowItem } from '../Overflow';\n\ninterface MuiOverflowItemProps {\n children: ReactNode;\n menuid?: string;\n minStateWidth?: number;\n}\n\nfunction MuiOverflowItem({ children, menuid, minStateWidth }: MuiOverflowItemProps) {\n const theme = useTheme();\n const cssWidth = minStateWidth !== undefined ? theme.spacing(minStateWidth) : undefined;\n\n return (\n <OverflowItem menuid={menuid} minStateWidth={cssWidth}>\n {children}\n </OverflowItem>\n );\n}\n\nexport default Object.assign(MuiOverflowItem, { overflowRole: 'item' as const });\n"],"names":["MuiOverflowItem","children","menuid","minStateWidth","theme","useTheme","cssWidth","jsx","OverflowItem","MuiOverflowItem_default"],"mappings":";;;AAUA,SAASA,EAAgB,EAAE,UAAAC,GAAU,QAAAC,GAAQ,eAAAC,KAAuC;AAClF,QAAMC,IAAQC,EAAA,GACRC,IAAWH,MAAkB,SAAYC,EAAM,QAAQD,CAAa,IAAI;AAE9E,SACE,gBAAAI,EAACC,GAAA,EAAa,QAAAN,GAAgB,eAAeI,GAC1C,UAAAL,GACH;AAEJ;AAEA,MAAAQ,IAAe,OAAO,OAAOT,GAAiB,EAAE,cAAc,QAAiB;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
interface MuiOverflowMenuProps {
|
|
3
|
+
opener: ReactNode;
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
declare function MuiOverflowMenu({ opener, children }: MuiOverflowMenuProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare const _default: typeof MuiOverflowMenu & {
|
|
8
|
+
overflowRole: "menu";
|
|
9
|
+
};
|
|
10
|
+
export default _default;
|
|
11
|
+
//# sourceMappingURL=MuiOverflowMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflowMenu.d.ts","sourceRoot":"","sources":["../../../src/components/MuiOverflow/MuiOverflowMenu.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,oBAAoB;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,iBAAS,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAYlE;;;;AAED,wBAAiF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import i from "@mui/material/Menu";
|
|
3
|
+
import l from "../Overflow/OverflowMenu.js";
|
|
4
|
+
function M({ opener: r, children: n }) {
|
|
5
|
+
return /* @__PURE__ */ e(l, { opener: r, renderMenu: ({ anchorEl: o, open: u, onClose: t, children: f }) => /* @__PURE__ */ e(i, { anchorEl: o, open: u, onClose: t, children: f }), children: n });
|
|
6
|
+
}
|
|
7
|
+
const a = Object.assign(M, { overflowRole: "menu" });
|
|
8
|
+
export {
|
|
9
|
+
a as default
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=MuiOverflowMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MuiOverflowMenu.js","sources":["../../../src/components/MuiOverflow/MuiOverflowMenu.tsx"],"sourcesContent":["import Menu from '@mui/material/Menu';\nimport type { ReactNode } from 'react';\nimport { OverflowMenu, type RenderMenuProps } from '../Overflow';\n\ninterface MuiOverflowMenuProps {\n opener: ReactNode;\n children: ReactNode;\n}\n\nfunction MuiOverflowMenu({ opener, children }: MuiOverflowMenuProps) {\n const renderMenu = ({ anchorEl, open, onClose, children: menuChildren }: RenderMenuProps) => (\n <Menu anchorEl={anchorEl} open={open} onClose={onClose}>\n {menuChildren}\n </Menu>\n );\n\n return (\n <OverflowMenu opener={opener} renderMenu={renderMenu}>\n {children}\n </OverflowMenu>\n );\n}\n\nexport default Object.assign(MuiOverflowMenu, { overflowRole: 'menu' as const });\n"],"names":["MuiOverflowMenu","opener","children","jsx","OverflowMenu","anchorEl","open","onClose","menuChildren","Menu","MuiOverflowMenu_default"],"mappings":";;;AASA,SAASA,EAAgB,EAAE,QAAAC,GAAQ,UAAAC,KAAkC;AAOnE,SACE,gBAAAC,EAACC,GAAA,EAAa,QAAAH,GAAgB,YAPb,CAAC,EAAE,UAAAI,GAAU,MAAAC,GAAM,SAAAC,GAAS,UAAUC,EAAA,MACvD,gBAAAL,EAACM,GAAA,EAAK,UAAAJ,GAAoB,MAAAC,GAAY,SAAAC,GACnC,UAAAC,GACH,GAKG,UAAAN,EAAA,CACH;AAEJ;AAEA,MAAAQ,IAAe,OAAO,OAAOV,GAAiB,EAAE,cAAc,QAAiB;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/MuiOverflow/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type OverflowHost, type ScanResult } from '../Overflow/OverflowController';
|
|
2
|
+
export interface OverflowToolbarOptions {
|
|
3
|
+
compact?: boolean;
|
|
4
|
+
reverse?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare class OverflowToolbar implements OverflowHost {
|
|
7
|
+
private ul;
|
|
8
|
+
private compact;
|
|
9
|
+
private reverse;
|
|
10
|
+
private controller;
|
|
11
|
+
constructor(ul: HTMLUListElement, opts?: OverflowToolbarOptions);
|
|
12
|
+
/** Re-scan after external DOM changes and restart the observer. */
|
|
13
|
+
update(): void;
|
|
14
|
+
/** Tear down ResizeObserver and clean up DOM state. */
|
|
15
|
+
destroy(): void;
|
|
16
|
+
getContainerEl(): HTMLElement;
|
|
17
|
+
isCompact(): boolean;
|
|
18
|
+
isReverse(): boolean;
|
|
19
|
+
scanChildren(): ScanResult;
|
|
20
|
+
private setupPopover;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=NoFrameworkOverflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoFrameworkOverflow.d.ts","sourceRoot":"","sources":["../../../src/components/NoFrameworkOverflow/NoFrameworkOverflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,UAAU,EAGhB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,eAAgB,YAAW,YAAY;IAClD,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAqB;gBAE3B,EAAE,EAAE,gBAAgB,EAAE,IAAI,GAAE,sBAA2B;IAanE,mEAAmE;IACnE,MAAM,IAAI,IAAI;IAId,uDAAuD;IACvD,OAAO,IAAI,IAAI;IAOf,cAAc,IAAI,WAAW;IAI7B,SAAS,IAAI,OAAO;IAIpB,SAAS,IAAI,OAAO;IAIpB,YAAY,IAAI,UAAU;IA8D1B,OAAO,CAAC,YAAY;CAcrB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { OverflowController as v } from "../Overflow/OverflowController.js";
|
|
2
|
+
class y {
|
|
3
|
+
ul;
|
|
4
|
+
compact;
|
|
5
|
+
reverse;
|
|
6
|
+
controller;
|
|
7
|
+
constructor(o, e = {}) {
|
|
8
|
+
this.ul = o, this.compact = e.compact ?? !1, this.reverse = e.reverse ?? !1, this.ul.classList.add("overflow"), this.compact && this.ul.classList.add("overflow-compact"), this.reverse && this.ul.classList.add("overflow-reverse"), this.controller = new v(this), this.controller.connect();
|
|
9
|
+
}
|
|
10
|
+
/** Re-scan after external DOM changes and restart the observer. */
|
|
11
|
+
update() {
|
|
12
|
+
this.controller.update();
|
|
13
|
+
}
|
|
14
|
+
/** Tear down ResizeObserver and clean up DOM state. */
|
|
15
|
+
destroy() {
|
|
16
|
+
this.controller.disconnect(), this.ul.classList.remove("overflow", "overflow-compact", "overflow-reverse");
|
|
17
|
+
}
|
|
18
|
+
/* ── OverflowHost ─────────────────────────────────────── */
|
|
19
|
+
getContainerEl() {
|
|
20
|
+
return this.ul;
|
|
21
|
+
}
|
|
22
|
+
isCompact() {
|
|
23
|
+
return this.compact;
|
|
24
|
+
}
|
|
25
|
+
isReverse() {
|
|
26
|
+
return this.reverse;
|
|
27
|
+
}
|
|
28
|
+
scanChildren() {
|
|
29
|
+
const o = [];
|
|
30
|
+
let e = null, r = -1, s = -1, l = 0;
|
|
31
|
+
for (const t of Array.from(this.ul.children)) {
|
|
32
|
+
const n = t.dataset.overflowRole;
|
|
33
|
+
if (n) {
|
|
34
|
+
if (n === "item" && (s === -1 && (s = l), o.push({
|
|
35
|
+
el: t,
|
|
36
|
+
buttonEl: t.querySelector("button"),
|
|
37
|
+
menuid: t.dataset.menuid || void 0,
|
|
38
|
+
minStateWidth: t.dataset.minStateWidth || void 0
|
|
39
|
+
})), n === "menu") {
|
|
40
|
+
r = l;
|
|
41
|
+
const c = t.querySelector("[data-menu-trigger]"), i = t.querySelector("[data-menu-panel]");
|
|
42
|
+
if (c && i) {
|
|
43
|
+
t.classList.add("overflow-opener"), i.setAttribute("popover", ""), this.setupPopover(c, i);
|
|
44
|
+
const a = Array.from(i.children), d = /* @__PURE__ */ new Set();
|
|
45
|
+
let u = !1;
|
|
46
|
+
for (const h of a) {
|
|
47
|
+
const m = h.dataset.menuid;
|
|
48
|
+
m ? d.add(m) : u = !0;
|
|
49
|
+
}
|
|
50
|
+
e = {
|
|
51
|
+
el: t,
|
|
52
|
+
triggerEl: c,
|
|
53
|
+
menuItemEls: a,
|
|
54
|
+
inMenuIds: d,
|
|
55
|
+
hasMenuOnlyItems: u
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
l++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const f = r !== -1 && (s === -1 || r < s);
|
|
63
|
+
return { items: o, menu: e, menuFirst: f };
|
|
64
|
+
}
|
|
65
|
+
setupPopover(o, e) {
|
|
66
|
+
o.addEventListener("click", () => {
|
|
67
|
+
if (e.matches(":popover-open"))
|
|
68
|
+
e.hidePopover();
|
|
69
|
+
else {
|
|
70
|
+
const r = o.getBoundingClientRect();
|
|
71
|
+
e.style.position = "fixed", e.style.top = `${r.bottom + 4}px`, e.style.left = `${r.left}px`, e.style.margin = "0", e.showPopover();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
y as OverflowToolbar
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=NoFrameworkOverflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoFrameworkOverflow.js","sources":["../../../src/components/NoFrameworkOverflow/NoFrameworkOverflow.ts"],"sourcesContent":["import {\n OverflowController,\n type OverflowHost,\n type ScanResult,\n type ScannedItem,\n type ScannedMenu,\n} from '../Overflow/OverflowController';\n\nexport interface OverflowToolbarOptions {\n compact?: boolean;\n reverse?: boolean;\n}\n\nexport class OverflowToolbar implements OverflowHost {\n private ul: HTMLUListElement;\n private compact: boolean;\n private reverse: boolean;\n private controller: OverflowController;\n\n constructor(ul: HTMLUListElement, opts: OverflowToolbarOptions = {}) {\n this.ul = ul;\n this.compact = opts.compact ?? false;\n this.reverse = opts.reverse ?? false;\n\n this.ul.classList.add('overflow');\n if (this.compact) this.ul.classList.add('overflow-compact');\n if (this.reverse) this.ul.classList.add('overflow-reverse');\n\n this.controller = new OverflowController(this);\n this.controller.connect();\n }\n\n /** Re-scan after external DOM changes and restart the observer. */\n update(): void {\n this.controller.update();\n }\n\n /** Tear down ResizeObserver and clean up DOM state. */\n destroy(): void {\n this.controller.disconnect();\n this.ul.classList.remove('overflow', 'overflow-compact', 'overflow-reverse');\n }\n\n /* ── OverflowHost ─────────────────────────────────────── */\n\n getContainerEl(): HTMLElement {\n return this.ul;\n }\n\n isCompact(): boolean {\n return this.compact;\n }\n\n isReverse(): boolean {\n return this.reverse;\n }\n\n scanChildren(): ScanResult {\n const items: ScannedItem[] = [];\n let menu: ScannedMenu | null = null;\n let menuIndex = -1;\n let firstItemIndex = -1;\n let index = 0;\n\n for (const child of Array.from(this.ul.children) as HTMLElement[]) {\n const role = child.dataset.overflowRole as 'item' | 'menu' | undefined;\n if (!role) continue;\n\n if (role === 'item') {\n if (firstItemIndex === -1) firstItemIndex = index;\n items.push({\n el: child,\n buttonEl: child.querySelector('button'),\n menuid: child.dataset.menuid || undefined,\n minStateWidth: child.dataset.minStateWidth || undefined,\n });\n }\n\n if (role === 'menu') {\n menuIndex = index;\n const trigger = child.querySelector<HTMLElement>('[data-menu-trigger]');\n const panel = child.querySelector<HTMLElement>('[data-menu-panel]');\n\n if (trigger && panel) {\n child.classList.add('overflow-opener');\n panel.setAttribute('popover', '');\n this.setupPopover(trigger, panel);\n\n const menuItemEls = Array.from(panel.children) as HTMLElement[];\n const inMenuIds = new Set<string>();\n let hasMenuOnlyItems = false;\n for (const mi of menuItemEls) {\n const mid = mi.dataset.menuid;\n if (mid) {\n inMenuIds.add(mid);\n } else {\n hasMenuOnlyItems = true;\n }\n }\n\n menu = {\n el: child,\n triggerEl: trigger,\n menuItemEls,\n inMenuIds,\n hasMenuOnlyItems,\n };\n }\n }\n\n index++;\n }\n\n const menuFirst =\n menuIndex !== -1 && (firstItemIndex === -1 || menuIndex < firstItemIndex);\n\n return { items, menu, menuFirst };\n }\n\n private setupPopover(trigger: HTMLElement, panel: HTMLElement): void {\n trigger.addEventListener('click', () => {\n if (panel.matches(':popover-open')) {\n panel.hidePopover();\n } else {\n const rect = trigger.getBoundingClientRect();\n panel.style.position = 'fixed';\n panel.style.top = `${rect.bottom + 4}px`;\n panel.style.left = `${rect.left}px`;\n panel.style.margin = '0';\n panel.showPopover();\n }\n });\n }\n}\n"],"names":["OverflowToolbar","ul","opts","OverflowController","items","menu","menuIndex","firstItemIndex","index","child","role","trigger","panel","menuItemEls","inMenuIds","hasMenuOnlyItems","mi","mid","menuFirst","rect"],"mappings":";AAaO,MAAMA,EAAwC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAYC,GAAsBC,IAA+B,IAAI;AACnE,SAAK,KAAKD,GACV,KAAK,UAAUC,EAAK,WAAW,IAC/B,KAAK,UAAUA,EAAK,WAAW,IAE/B,KAAK,GAAG,UAAU,IAAI,UAAU,GAC5B,KAAK,WAAS,KAAK,GAAG,UAAU,IAAI,kBAAkB,GACtD,KAAK,WAAS,KAAK,GAAG,UAAU,IAAI,kBAAkB,GAE1D,KAAK,aAAa,IAAIC,EAAmB,IAAI,GAC7C,KAAK,WAAW,QAAA;AAAA,EAClB;AAAA;AAAA,EAGA,SAAe;AACb,SAAK,WAAW,OAAA;AAAA,EAClB;AAAA;AAAA,EAGA,UAAgB;AACd,SAAK,WAAW,WAAA,GAChB,KAAK,GAAG,UAAU,OAAO,YAAY,oBAAoB,kBAAkB;AAAA,EAC7E;AAAA;AAAA,EAIA,iBAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,eAA2B;AACzB,UAAMC,IAAuB,CAAA;AAC7B,QAAIC,IAA2B,MAC3BC,IAAY,IACZC,IAAiB,IACjBC,IAAQ;AAEZ,eAAWC,KAAS,MAAM,KAAK,KAAK,GAAG,QAAQ,GAAoB;AACjE,YAAMC,IAAOD,EAAM,QAAQ;AAC3B,UAAKC,GAYL;AAAA,YAVIA,MAAS,WACPH,MAAmB,OAAIA,IAAiBC,IAC5CJ,EAAM,KAAK;AAAA,UACT,IAAIK;AAAA,UACJ,UAAUA,EAAM,cAAc,QAAQ;AAAA,UACtC,QAAQA,EAAM,QAAQ,UAAU;AAAA,UAChC,eAAeA,EAAM,QAAQ,iBAAiB;AAAA,QAAA,CAC/C,IAGCC,MAAS,QAAQ;AACnB,UAAAJ,IAAYE;AACZ,gBAAMG,IAAUF,EAAM,cAA2B,qBAAqB,GAChEG,IAAQH,EAAM,cAA2B,mBAAmB;AAElE,cAAIE,KAAWC,GAAO;AACpB,YAAAH,EAAM,UAAU,IAAI,iBAAiB,GACrCG,EAAM,aAAa,WAAW,EAAE,GAChC,KAAK,aAAaD,GAASC,CAAK;AAEhC,kBAAMC,IAAc,MAAM,KAAKD,EAAM,QAAQ,GACvCE,wBAAgB,IAAA;AACtB,gBAAIC,IAAmB;AACvB,uBAAWC,KAAMH,GAAa;AAC5B,oBAAMI,IAAMD,EAAG,QAAQ;AACvB,cAAIC,IACFH,EAAU,IAAIG,CAAG,IAEjBF,IAAmB;AAAA,YAEvB;AAEA,YAAAV,IAAO;AAAA,cACL,IAAII;AAAA,cACJ,WAAWE;AAAA,cACX,aAAAE;AAAA,cACA,WAAAC;AAAA,cACA,kBAAAC;AAAA,YAAA;AAAA,UAEJ;AAAA,QACF;AAEA,QAAAP;AAAA;AAAA,IACF;AAEA,UAAMU,IACJZ,MAAc,OAAOC,MAAmB,MAAMD,IAAYC;AAE5D,WAAO,EAAE,OAAAH,GAAO,MAAAC,GAAM,WAAAa,EAAA;AAAA,EACxB;AAAA,EAEQ,aAAaP,GAAsBC,GAA0B;AACnE,IAAAD,EAAQ,iBAAiB,SAAS,MAAM;AACtC,UAAIC,EAAM,QAAQ,eAAe;AAC/B,QAAAA,EAAM,YAAA;AAAA,WACD;AACL,cAAMO,IAAOR,EAAQ,sBAAA;AACrB,QAAAC,EAAM,MAAM,WAAW,SACvBA,EAAM,MAAM,MAAM,GAAGO,EAAK,SAAS,CAAC,MACpCP,EAAM,MAAM,OAAO,GAAGO,EAAK,IAAI,MAC/BP,EAAM,MAAM,SAAS,KACrBA,EAAM,YAAA;AAAA,MACR;AAAA,IACF,CAAC;AAAA,EACH;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/NoFrameworkOverflow/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* ── NoFramework Overflow Styles ──────────────────────────── */
|
|
2
|
+
/* Self-contained: includes both layout and theme. */
|
|
3
|
+
/* Deep orange theme, distinct from Rx (purple) and MUI. */
|
|
4
|
+
|
|
5
|
+
/* ── Toolbar button ──────────────────────────────────────── */
|
|
6
|
+
.nf-btn {
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
gap: 0.5rem;
|
|
10
|
+
padding: 0.375rem 1rem;
|
|
11
|
+
border: none;
|
|
12
|
+
border-radius: 0.375rem;
|
|
13
|
+
background: oklch(0.65 0.24 50);
|
|
14
|
+
color: white;
|
|
15
|
+
font-size: 0.9375rem;
|
|
16
|
+
line-height: 1.75;
|
|
17
|
+
font-weight: 500;
|
|
18
|
+
white-space: nowrap;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
user-select: none;
|
|
21
|
+
transition: background 0.15s;
|
|
22
|
+
height: 2.5rem;
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
background: oklch(0.60 0.24 50);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&:active {
|
|
29
|
+
background: oklch(0.55 0.24 50);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&:focus-visible {
|
|
33
|
+
outline: 2px solid oklch(0.70 0.24 50 / 0.5);
|
|
34
|
+
outline-offset: 2px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* ── Popover panel ───────────────────────────────────────── */
|
|
39
|
+
.nf-menu-panel {
|
|
40
|
+
z-index: 50;
|
|
41
|
+
min-width: 8rem;
|
|
42
|
+
padding: 0.25rem;
|
|
43
|
+
border-radius: 0.375rem;
|
|
44
|
+
border: 1px solid oklch(0.90 0.01 50);
|
|
45
|
+
background: white;
|
|
46
|
+
box-shadow:
|
|
47
|
+
0 4px 6px -1px oklch(0 0 0 / 0.1),
|
|
48
|
+
0 2px 4px -2px oklch(0 0 0 / 0.1);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Popover API animation */
|
|
52
|
+
@keyframes nf-popover-in {
|
|
53
|
+
from { opacity: 0; transform: scale(0.95) translateY(-4px); }
|
|
54
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes nf-popover-out {
|
|
58
|
+
from { opacity: 1; transform: scale(1) translateY(0); }
|
|
59
|
+
to { opacity: 0; transform: scale(0.95) translateY(-4px); }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.nf-menu-panel:popover-open {
|
|
63
|
+
animation: nf-popover-in 0.15s ease-out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* ── Popover menu item ───────────────────────────────────── */
|
|
67
|
+
.nf-menu-item {
|
|
68
|
+
display: flex;
|
|
69
|
+
width: 100%;
|
|
70
|
+
align-items: center;
|
|
71
|
+
gap: 0.5rem;
|
|
72
|
+
padding: 0.375rem 0.5rem;
|
|
73
|
+
border: none;
|
|
74
|
+
border-radius: 0.25rem;
|
|
75
|
+
background: transparent;
|
|
76
|
+
color: oklch(0.30 0.02 50);
|
|
77
|
+
font-size: 0.9375rem;
|
|
78
|
+
line-height: 1.75;
|
|
79
|
+
text-align: left;
|
|
80
|
+
cursor: default;
|
|
81
|
+
user-select: none;
|
|
82
|
+
transition: background 0.1s, color 0.1s;
|
|
83
|
+
|
|
84
|
+
&:hover {
|
|
85
|
+
background: oklch(0.95 0.01 50);
|
|
86
|
+
color: oklch(0.20 0.02 50);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&:active {
|
|
90
|
+
background: oklch(0.92 0.02 50);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&:focus-visible {
|
|
94
|
+
outline: none;
|
|
95
|
+
background: oklch(0.95 0.01 50);
|
|
96
|
+
color: oklch(0.20 0.02 50);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* ── Menu separator ──────────────────────────────────────── */
|
|
101
|
+
.nf-separator {
|
|
102
|
+
height: 1px;
|
|
103
|
+
margin: 0.25rem 0;
|
|
104
|
+
background: oklch(0.90 0.01 50);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.nf-btn svg {
|
|
108
|
+
min-width: 24px;
|
|
109
|
+
min-height: 24px;
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
div:has(>.overflow){justify-content:space-between;gap:1px}div:has(>.overflow) .overflow>:not([data-state=hidden]):first-child,div:has(>.overflow) .overflow>[data-state=hidden]:first-child+:not([data-state=hidden]){margin-left:auto;margin-right:0}div:has(>.overflow) .overflow.overflow-reverse>:not([data-state=hidden]):first-child,div:has(>.overflow) .overflow.overflow-reverse>[data-state=hidden]:first-child+:not([data-state=hidden]){margin-left:0;margin-right:auto}.overflow{--u: 8px;--u1: calc(var(--u) * 1);--u2: calc(var(--u) * 2);--u3: calc(var(--u) * 3);--u4: calc(var(--u) * 4);--u5: calc(var(--u) * 5);--hiddenCount: 0;display:flex;gap:0;justify-content:flex-start;white-space:nowrap;max-width:100%;overflow:hidden;list-style:none;margin:0 0 0 auto;padding:0;flex:min(var(--hiddenCount, 0)) 1 auto}.overflow>*{flex:0 0 fit-content;list-style:none;padding:0;margin:0}.overflow>li.overflow-opener{margin-left:auto;max-width:var(--u5)}.overflow-compact{gap:1px!important}.overflow-compact:not(.overflow-reverse)>:not([data-state=hidden])~:not([data-state=hidden])>button{border-top-left-radius:0;border-bottom-left-radius:0}.overflow-compact:not(.overflow-reverse)>:not([data-state=hidden]):has(~:not([data-state=hidden]))>button{border-top-right-radius:0;border-bottom-right-radius:0}.overflow-reverse{margin-left:0;margin-right:auto;flex-direction:row-reverse}.overflow-reverse>li.overflow-opener{margin-left:0;margin-right:auto}.overflow-compact.overflow-reverse>:not([data-state=hidden])~:not([data-state=hidden])>button{border-top-right-radius:0;border-bottom-right-radius:0}.overflow-compact.overflow-reverse>:not([data-state=hidden]):has(~:not([data-state=hidden]))>button{border-top-left-radius:0;border-bottom-left-radius:0}:is(.overflow-item-min,.overflow-opener)>button{font-size:0;min-width:100%;width:100%;max-width:100%;align-items:center;justify-content:center;gap:0}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import './Overflow.css';
|
|
3
|
+
export interface OverflowProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
className?: string;
|
|
6
|
+
style?: React.CSSProperties;
|
|
7
|
+
compact?: boolean;
|
|
8
|
+
reverse?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare const Overflow: import("react").ForwardRefExoticComponent<OverflowProps & import("react").RefAttributes<HTMLUListElement>>;
|
|
11
|
+
export default Overflow;
|
|
12
|
+
//# sourceMappingURL=Overflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Overflow.d.ts","sourceRoot":"","sources":["../../../src/components/Overflow/Overflow.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkD,KAAK,SAAS,EAA0C,MAAM,OAAO,CAAC;AAC/H,OAAO,gBAAgB,CAAC;AAKxB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,QAAA,MAAM,QAAQ,4GAuEZ,CAAC;AAEH,eAAe,QAAQ,CAAC"}
|