@deadragdoll/reactnu 0.1.56 → 0.1.73
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/dist/components/MainMenu/MainMenu.types.d.ts +8 -1
- package/dist/components/MainMenu/internals/MainMenuSubmenuShell.d.ts +7 -0
- package/dist/components/Spacer/Spacer.d.ts +7 -0
- package/dist/components/Spacer/index.d.ts +1 -0
- package/dist/components/ToolBar/ToolBar.d.ts +6 -2
- package/dist/index.cjs +894 -809
- package/dist/index.d.ts +1 -0
- package/dist/index.js +645 -562
- package/dist/styles.css +80 -9
- package/dist/windowing/AppBarItem.d.ts +1 -1
- package/docs/API_REFERENCE.md +2 -0
- package/docs/COMPONENT_INDEX.md +1 -0
- package/docs/MainMenu.md +11 -1
- package/docs/PopupMenu.md +2 -0
- package/docs/Spacer.md +41 -0
- package/docs/StatusBarItem.md +1 -0
- package/docs/TOKEN_CHECKLIST.md +9 -0
- package/docs/ToolBar.md +15 -2
- package/package.json +1 -1
package/dist/styles.css
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
--nu-color-button-face-alt: #c7c7c7;
|
|
21
21
|
--nu-color-button-danger: #c84d4d;
|
|
22
22
|
--nu-color-button-success: #188f3b;
|
|
23
|
+
--nu-text-danger: #c84d4d;
|
|
24
|
+
--nu-text-success: #188f3b;
|
|
23
25
|
--nu-color-button-text: #000000;
|
|
24
26
|
--nu-color-field-bg: #000000;
|
|
25
27
|
--nu-color-field-text: #ffffff;
|
|
@@ -47,6 +49,17 @@
|
|
|
47
49
|
--nu-button-press-depth-y: 0.1em;
|
|
48
50
|
--nu-frame-thickness: 2px;
|
|
49
51
|
--nu-rule-thickness: 1px;
|
|
52
|
+
--nu-toolbar-background: var(--nu-color-panel);
|
|
53
|
+
--nu-toolbar-inset: 0.2ch;
|
|
54
|
+
--nu-toolbar-border-color: var(--nu-border-dark);
|
|
55
|
+
--nu-toolbar-border-style: solid;
|
|
56
|
+
--nu-toolbar-border-width: var(--nu-rule-thickness);
|
|
57
|
+
--nu-toolbar-separator-color: var(--nu-border-dark);
|
|
58
|
+
--nu-toolbar-separator-style: solid;
|
|
59
|
+
--nu-toolbar-separator-width: var(--nu-rule-thickness);
|
|
60
|
+
--nu-menu-divider-color: var(--nu-border-dark);
|
|
61
|
+
--nu-menu-divider-style: solid;
|
|
62
|
+
--nu-menu-divider-width: var(--nu-rule-thickness);
|
|
50
63
|
--nu-window-shadow-bg: rgba(0, 0, 0, 0.38);
|
|
51
64
|
--nu-window-shadow-offset-x: 1ch;
|
|
52
65
|
--nu-window-shadow-offset-y: 1em;
|
|
@@ -1086,20 +1099,23 @@
|
|
|
1086
1099
|
.nu-main-menu__item-button:disabled {
|
|
1087
1100
|
cursor: default;
|
|
1088
1101
|
}
|
|
1089
|
-
.nu-main-menu__item--root .nu-main-menu__item-button {
|
|
1102
|
+
.nu-main-menu__item--root > .nu-main-menu__item-button {
|
|
1090
1103
|
display: inline-flex;
|
|
1091
1104
|
align-items: center;
|
|
1092
1105
|
min-height: 1.4rem;
|
|
1093
1106
|
padding: 0 0.65rem;
|
|
1094
1107
|
}
|
|
1095
1108
|
.nu-main-menu__item--submenu .nu-main-menu__item-button {
|
|
1096
|
-
grid-template-columns:
|
|
1109
|
+
grid-template-columns: minmax(max-content, 1fr) max-content 0.8rem;
|
|
1097
1110
|
gap: 0.45rem;
|
|
1098
1111
|
width: 100%;
|
|
1099
1112
|
min-width: 13rem;
|
|
1100
1113
|
min-height: 1.35rem;
|
|
1101
1114
|
padding: 0 0.55rem;
|
|
1102
1115
|
}
|
|
1116
|
+
.nu-main-menu__item--submenu .nu-main-menu__item-button[data-has-leading] {
|
|
1117
|
+
grid-template-columns: auto minmax(max-content, 1fr) max-content 0.8rem;
|
|
1118
|
+
}
|
|
1103
1119
|
.nu-main-menu__item--open > .nu-main-menu__item-button {
|
|
1104
1120
|
background: var(--nu-color-field-bg);
|
|
1105
1121
|
color: var(--nu-text-primary);
|
|
@@ -1147,14 +1163,23 @@
|
|
|
1147
1163
|
top: calc(100% - 1px);
|
|
1148
1164
|
left: 0;
|
|
1149
1165
|
}
|
|
1166
|
+
.nu-main-menu__submenu-shell--root[data-open-left] {
|
|
1167
|
+
right: 0;
|
|
1168
|
+
left: auto;
|
|
1169
|
+
}
|
|
1150
1170
|
.nu-main-menu__submenu-shell--submenu {
|
|
1151
1171
|
top: -0.2rem;
|
|
1152
1172
|
left: calc(100% - 1px);
|
|
1153
1173
|
}
|
|
1174
|
+
.nu-main-menu__submenu-shell--submenu[data-open-left] {
|
|
1175
|
+
right: calc(100% - 1px);
|
|
1176
|
+
left: auto;
|
|
1177
|
+
}
|
|
1154
1178
|
.nu-main-menu__divider {
|
|
1155
|
-
height:
|
|
1179
|
+
height: 0;
|
|
1156
1180
|
margin: 0.18rem 0.55rem;
|
|
1157
|
-
|
|
1181
|
+
border-block-start: var(--nu-menu-divider-width) var(--nu-menu-divider-style)
|
|
1182
|
+
var(--nu-menu-divider-color);
|
|
1158
1183
|
}
|
|
1159
1184
|
.nu-main-menu__check {
|
|
1160
1185
|
display: inline-flex;
|
|
@@ -1164,6 +1189,13 @@
|
|
|
1164
1189
|
block-size: var(--nu-glyph-cell-size);
|
|
1165
1190
|
color: var(--nu-text-hotkey);
|
|
1166
1191
|
}
|
|
1192
|
+
.nu-main-menu__leading {
|
|
1193
|
+
display: inline-flex;
|
|
1194
|
+
align-items: center;
|
|
1195
|
+
justify-content: center;
|
|
1196
|
+
gap: 0.25rem;
|
|
1197
|
+
grid-column: 1;
|
|
1198
|
+
}
|
|
1167
1199
|
.nu-main-menu__check-box {
|
|
1168
1200
|
display: inline-flex;
|
|
1169
1201
|
align-items: center;
|
|
@@ -1184,24 +1216,41 @@
|
|
|
1184
1216
|
block-size: var(--nu-glyph-cell-size);
|
|
1185
1217
|
color: currentColor;
|
|
1186
1218
|
}
|
|
1219
|
+
.nu-main-menu__icon > svg {
|
|
1220
|
+
inline-size: var(--nu-glyph-cell-size);
|
|
1221
|
+
block-size: var(--nu-glyph-cell-size);
|
|
1222
|
+
}
|
|
1187
1223
|
.nu-main-menu__label {
|
|
1188
1224
|
min-width: 0;
|
|
1225
|
+
grid-column: 1;
|
|
1226
|
+
}
|
|
1227
|
+
.nu-main-menu__item-button[data-has-leading] .nu-main-menu__label {
|
|
1228
|
+
grid-column: 2;
|
|
1189
1229
|
}
|
|
1190
1230
|
.nu-main-menu__hotkey {
|
|
1191
1231
|
color: var(--nu-text-hotkey);
|
|
1192
1232
|
}
|
|
1193
1233
|
.nu-main-menu__shortcut {
|
|
1234
|
+
grid-column: 2;
|
|
1235
|
+
justify-self: end;
|
|
1194
1236
|
margin-left: 1rem;
|
|
1195
1237
|
color: var(--nu-main-menu-text);
|
|
1196
1238
|
}
|
|
1239
|
+
.nu-main-menu__item-button[data-has-leading] .nu-main-menu__shortcut {
|
|
1240
|
+
grid-column: 3;
|
|
1241
|
+
}
|
|
1197
1242
|
.nu-main-menu__item--open .nu-main-menu__shortcut,
|
|
1198
1243
|
.nu-main-menu__item:not(.nu-main-menu__item--disabled):hover
|
|
1199
1244
|
.nu-main-menu__shortcut {
|
|
1200
1245
|
color: currentColor;
|
|
1201
1246
|
}
|
|
1202
1247
|
.nu-main-menu__submenu-arrow {
|
|
1248
|
+
grid-column: 3;
|
|
1203
1249
|
justify-self: end;
|
|
1204
1250
|
}
|
|
1251
|
+
.nu-main-menu__item-button[data-has-leading] .nu-main-menu__submenu-arrow {
|
|
1252
|
+
grid-column: 4;
|
|
1253
|
+
}
|
|
1205
1254
|
.nu-masked-field {
|
|
1206
1255
|
display: grid;
|
|
1207
1256
|
gap: var(--nu-space-xs);
|
|
@@ -1807,10 +1856,10 @@
|
|
|
1807
1856
|
color: var(--nu-text-accent);
|
|
1808
1857
|
}
|
|
1809
1858
|
.nu-report-cell--danger {
|
|
1810
|
-
color: var(--nu-text-
|
|
1859
|
+
color: var(--nu-text-danger);
|
|
1811
1860
|
}
|
|
1812
1861
|
.nu-report-cell--success {
|
|
1813
|
-
color: var(--nu-text-
|
|
1862
|
+
color: var(--nu-text-success);
|
|
1814
1863
|
}
|
|
1815
1864
|
.nu-search-box {
|
|
1816
1865
|
display: grid;
|
|
@@ -1899,6 +1948,13 @@
|
|
|
1899
1948
|
color: var(--nu-text-muted);
|
|
1900
1949
|
font-size: 0.75rem;
|
|
1901
1950
|
}
|
|
1951
|
+
.nu-spacer {
|
|
1952
|
+
display: block;
|
|
1953
|
+
flex: 1 1 auto;
|
|
1954
|
+
min-width: 0;
|
|
1955
|
+
min-height: 0;
|
|
1956
|
+
pointer-events: none;
|
|
1957
|
+
}
|
|
1902
1958
|
.nu-spin-box {
|
|
1903
1959
|
display: grid;
|
|
1904
1960
|
gap: var(--nu-space-xs);
|
|
@@ -2387,7 +2443,11 @@
|
|
|
2387
2443
|
gap: 0.5ch;
|
|
2388
2444
|
min-width: 0;
|
|
2389
2445
|
min-height: 0;
|
|
2390
|
-
|
|
2446
|
+
overflow: clip;
|
|
2447
|
+
padding: var(--nu-toolbar-inset);
|
|
2448
|
+
border: var(--nu-toolbar-border-width) var(--nu-toolbar-border-style)
|
|
2449
|
+
var(--nu-toolbar-border-color);
|
|
2450
|
+
background: var(--nu-toolbar-background);
|
|
2391
2451
|
font-family: var(--nu-font-body);
|
|
2392
2452
|
}
|
|
2393
2453
|
.nu-toolbar[data-fill] {
|
|
@@ -2433,6 +2493,16 @@
|
|
|
2433
2493
|
opacity: 0.6;
|
|
2434
2494
|
cursor: not-allowed;
|
|
2435
2495
|
}
|
|
2496
|
+
.nu-toolbar__static {
|
|
2497
|
+
display: inline-flex;
|
|
2498
|
+
align-items: center;
|
|
2499
|
+
justify-content: center;
|
|
2500
|
+
flex: none;
|
|
2501
|
+
}
|
|
2502
|
+
.nu-toolbar__static > svg {
|
|
2503
|
+
inline-size: var(--nu-glyph-cell-size);
|
|
2504
|
+
block-size: var(--nu-glyph-cell-size);
|
|
2505
|
+
}
|
|
2436
2506
|
.nu-toolbar__button-icon,
|
|
2437
2507
|
.nu-toolbar__button-caret {
|
|
2438
2508
|
display: inline-flex;
|
|
@@ -2448,10 +2518,11 @@
|
|
|
2448
2518
|
padding-left: 0.55ch;
|
|
2449
2519
|
}
|
|
2450
2520
|
.nu-toolbar__separator {
|
|
2451
|
-
width:
|
|
2521
|
+
width: 0;
|
|
2452
2522
|
align-self: stretch;
|
|
2453
2523
|
margin: 0 0.35ch;
|
|
2454
|
-
|
|
2524
|
+
border-inline-start: var(--nu-toolbar-separator-width)
|
|
2525
|
+
var(--nu-toolbar-separator-style) var(--nu-toolbar-separator-color);
|
|
2455
2526
|
}
|
|
2456
2527
|
.nu-toolbar[data-wrap] .nu-toolbar__separator {
|
|
2457
2528
|
min-height: 1em;
|
|
@@ -15,7 +15,7 @@ type AppBarItemStaticProps = AppBarItemBaseProps & Omit<HTMLAttributes<HTMLDivEl
|
|
|
15
15
|
export type AppBarItemProps = AppBarItemButtonProps | AppBarItemStaticProps;
|
|
16
16
|
export declare function AppBarItem(props: AppBarItemProps): import("react").DetailedReactHTMLElement<{
|
|
17
17
|
className: string;
|
|
18
|
-
type: "button" | "
|
|
18
|
+
type: "button" | "reset" | "submit";
|
|
19
19
|
defaultChecked?: boolean | undefined | undefined;
|
|
20
20
|
defaultValue?: string | number | readonly string[] | undefined;
|
|
21
21
|
suppressContentEditableWarning?: boolean | undefined | undefined;
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -115,6 +115,8 @@ See: [Slot Customization](./SLOT_CUSTOMIZATION.md)
|
|
|
115
115
|
docs: [Splitter](./Splitter.md)
|
|
116
116
|
- `Stack`
|
|
117
117
|
docs: [Stack](./Stack.md)
|
|
118
|
+
- `Spacer`
|
|
119
|
+
docs: [Spacer](./Spacer.md)
|
|
118
120
|
- `ToolBar`, `ToolButton`, `ToolSeparator`
|
|
119
121
|
docs: [ToolBar](./ToolBar.md)
|
|
120
122
|
|
package/docs/COMPONENT_INDEX.md
CHANGED
package/docs/MainMenu.md
CHANGED
|
@@ -29,9 +29,19 @@
|
|
|
29
29
|
- `MainMenuDivider`
|
|
30
30
|
- `id`
|
|
31
31
|
- `type: "divider"`
|
|
32
|
+
- `MainMenuSpacer`
|
|
33
|
+
- `id`
|
|
34
|
+
- `type: "spacer"`
|
|
35
|
+
- Valid at the root level only; pushes following menu items to the right.
|
|
32
36
|
|
|
33
37
|
## Notes
|
|
34
38
|
|
|
35
39
|
- Top-level dropdowns open below their root items.
|
|
36
|
-
- Nested submenus open to the right
|
|
40
|
+
- Nested submenus open to the right by default and automatically open to the
|
|
41
|
+
left only when their right edge would leave the viewport.
|
|
37
42
|
- Active and hovered items use the same black selection pattern used elsewhere in the library.
|
|
43
|
+
- Popup-menu dividers use `--nu-menu-divider-color`,
|
|
44
|
+
`--nu-menu-divider-style`, and `--nu-menu-divider-width`.
|
|
45
|
+
- Use `{ id: "main-menu-spacer", type: "spacer" }` between root menu items to
|
|
46
|
+
align the following menu group to the opposite edge. Their dropdowns choose
|
|
47
|
+
the viewport-facing side when opened.
|
package/docs/PopupMenu.md
CHANGED
|
@@ -40,6 +40,8 @@ const popupMenu = usePopupMenu();
|
|
|
40
40
|
## Notes
|
|
41
41
|
|
|
42
42
|
- Popup menus render through a portal and are not clipped by local overflow containers.
|
|
43
|
+
- Nested popup-menu levels open to the right by default and flip left only when
|
|
44
|
+
they would overflow the viewport.
|
|
43
45
|
- `openFromContextMenu(event)` carries the event target into the portal, so
|
|
44
46
|
context menus inherit tokens from the nearest `NuThemeProvider`. Pass the
|
|
45
47
|
optional `themeSource` to `openAtPoint(...)` when opening one manually.
|
package/docs/Spacer.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Spacer
|
|
2
|
+
|
|
3
|
+
`Spacer` fills unused space in a flex layout, moving all following controls to
|
|
4
|
+
the opposite edge. It is decorative and is hidden from assistive technology.
|
|
5
|
+
|
|
6
|
+
## Usage
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
<ToolBar>
|
|
10
|
+
<ToolButton>&Open</ToolButton>
|
|
11
|
+
<Spacer />
|
|
12
|
+
<ToolButton>&Help</ToolButton>
|
|
13
|
+
</ToolBar>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
It works in `ToolBar`, `Stack direction="row"`, and a window `statusBar`:
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
<Window
|
|
20
|
+
statusBar={
|
|
21
|
+
<>
|
|
22
|
+
<StatusBarItem>F2 Save</StatusBarItem>
|
|
23
|
+
<Spacer />
|
|
24
|
+
<StatusBarItem>Ready</StatusBarItem>
|
|
25
|
+
</>
|
|
26
|
+
}
|
|
27
|
+
title="Editor"
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For a root `MainMenu`, use the menu model equivalent:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
const items: MainMenuNode[] = [
|
|
35
|
+
{ id: "file", text: "&File" },
|
|
36
|
+
{ id: "window", text: "&Window" },
|
|
37
|
+
{ id: "menu-spacer", type: "spacer" },
|
|
38
|
+
{ id: "profile", text: "&Profile" },
|
|
39
|
+
{ id: "about", text: "&About" }
|
|
40
|
+
];
|
|
41
|
+
```
|
package/docs/StatusBarItem.md
CHANGED
package/docs/TOKEN_CHECKLIST.md
CHANGED
|
@@ -61,6 +61,15 @@ If a component needs a new reusable visual value, add it there first instead of
|
|
|
61
61
|
- `--nu-control-height`
|
|
62
62
|
- `--nu-frame-thickness`
|
|
63
63
|
- `--nu-rule-thickness`
|
|
64
|
+
- Toolbar and menu dividers:
|
|
65
|
+
- `--nu-toolbar-background`
|
|
66
|
+
- `--nu-toolbar-inset`
|
|
67
|
+
- `--nu-toolbar-border-color`, `--nu-toolbar-border-style`,
|
|
68
|
+
`--nu-toolbar-border-width`
|
|
69
|
+
- `--nu-toolbar-separator-color`, `--nu-toolbar-separator-style`,
|
|
70
|
+
`--nu-toolbar-separator-width`
|
|
71
|
+
- `--nu-menu-divider-color`, `--nu-menu-divider-style`,
|
|
72
|
+
`--nu-menu-divider-width`
|
|
64
73
|
- Button mechanics:
|
|
65
74
|
- `--nu-button-shadow-x`
|
|
66
75
|
- `--nu-button-shadow-y`
|
package/docs/ToolBar.md
CHANGED
|
@@ -7,12 +7,13 @@ For the same button behavior outside a toolbar container, use [CommandButton](./
|
|
|
7
7
|
## Usage
|
|
8
8
|
|
|
9
9
|
```tsx
|
|
10
|
-
<ToolBar>
|
|
10
|
+
<ToolBar startContent={<NuGlyph aria-hidden name="folder" />}>
|
|
11
11
|
<ToolButton icon="folder">&Scan</ToolButton>
|
|
12
12
|
<ToolButton icon="star" pressed>
|
|
13
13
|
&Watch
|
|
14
14
|
</ToolButton>
|
|
15
15
|
<ToolSeparator />
|
|
16
|
+
<Spacer />
|
|
16
17
|
<ToolDropButton
|
|
17
18
|
icon="folder"
|
|
18
19
|
menuItems={[
|
|
@@ -32,20 +33,32 @@ For the same button behavior outside a toolbar container, use [CommandButton](./
|
|
|
32
33
|
- `ToolButton`
|
|
33
34
|
- `ToolDropButton`
|
|
34
35
|
- `ToolSeparator`
|
|
36
|
+
- `Spacer`
|
|
35
37
|
|
|
36
38
|
## Key Props
|
|
37
39
|
|
|
38
40
|
- `fill?: boolean`
|
|
39
41
|
- `wrap?: boolean`
|
|
42
|
+
- `startContent?: ReactNode`
|
|
43
|
+
- `endContent?: ReactNode`
|
|
40
44
|
- `slotStyles`
|
|
41
45
|
- `slotClassNames`
|
|
42
46
|
|
|
43
47
|
## Notes
|
|
44
48
|
|
|
45
|
-
- `ToolBar`
|
|
49
|
+
- `ToolBar` defaults to `fill={true}` and uses `--nu-toolbar-background` for
|
|
50
|
+
its surface.
|
|
51
|
+
- `startContent` and `endContent` render static React content before and after
|
|
52
|
+
the controls. Use them for decorative icons or compact status text, not for
|
|
53
|
+
actions that need toolbar keyboard semantics.
|
|
46
54
|
- `wrap={true}` lets tools continue on the next row when the container is too narrow.
|
|
47
55
|
- `ToolButton` supports `toggled` for toggle-style tools. `pressed` is kept as a legacy alias through the shared command-button layer.
|
|
48
56
|
- `ToolButton` also supports `icon` and optional `dropdown`.
|
|
49
57
|
- `ToolDropButton` is a convenience wrapper for `ToolButton dropdown`.
|
|
50
58
|
- If `menuItems` are provided, `ToolDropButton` opens `PopupMenu` automatically and reports selection through `onMenuItemSelect`.
|
|
51
59
|
- `ToolSeparator` is decorative and should only be used between tools.
|
|
60
|
+
- Toolbar chrome is themeable through `--nu-toolbar-border-color`,
|
|
61
|
+
`--nu-toolbar-border-style`, and `--nu-toolbar-border-width`; separators
|
|
62
|
+
use the corresponding `--nu-toolbar-separator-*` tokens.
|
|
63
|
+
- `--nu-toolbar-inset` controls Toolbar padding on all four sides.
|
|
64
|
+
- `Spacer` fills free space and moves following tools to the opposite edge.
|