@synopackageland/ui 0.13.1 → 0.14.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.
@@ -0,0 +1,96 @@
1
+ # SplitPane, SizeBar and StorageMeter
2
+
3
+ Three building blocks for storage pages: two panes the user resizes, a size
4
+ bar for a list row, and a "free now → free after" projection. All three are
5
+ styled with classes only and work inside the DSM-embedded theme.
6
+
7
+ ## SplitPane
8
+
9
+ Two panes side by side (`horizontal`) or one above the other (`vertical`),
10
+ with a separator the user drags, moves with the keyboard, or double-clicks to
11
+ reset.
12
+
13
+ ```vue
14
+ <SplitPane storage-key="myapp.explore.split" :default-size="0.56" :min-start="280" :min-end="480">
15
+ <template #start><Treemap /></template>
16
+ <template #end><DataGrid ... /></template>
17
+ </SplitPane>
18
+ ```
19
+
20
+ | Prop | Default | Meaning |
21
+ | --- | --- | --- |
22
+ | `modelValue` | unset | The start pane's share of the room, 0–1. Bind `v-model` to control it; leave it unset and the pane keeps its own state. |
23
+ | `defaultSize` | `0.5` | The share it starts with and returns to on a double click. |
24
+ | `orientation` | `'horizontal'` | `horizontal`: start on the left. `vertical`: start on top. |
25
+ | `minStart` / `minEnd` | `160` | Each pane's minimum in px. The separator stops there; a window too small for both gives the start pane its minimum first. |
26
+ | `gap` | `12` | The separator's thickness in px (the room between the panes). |
27
+ | `storageKey` | unset | Remembers the share in this browser's `localStorage` under `<storageKey>:<orientation>`, so each orientation keeps its own share. Reading and writing are wrapped in `try/catch`; unreadable or invalid storage falls back to `defaultSize`. |
28
+ | `label` | "Resize panes" | The separator's accessible name. |
29
+
30
+ - **Keyboard.** The separator is a Tab stop (`role="separator"`). Left/Right
31
+ (horizontal) or Up/Down (vertical) move it by 2%, with Shift by 10%;
32
+ Home/End go to the minimums. Each change is saved.
33
+ - **ARIA.** `aria-orientation` is perpendicular to the layout, as the ARIA
34
+ pattern asks; `aria-valuenow`/`aria-valuemin`/`aria-valuemax` are whole
35
+ percentages of the start pane; `aria-controls` names the start pane.
36
+ - **Reset.** A double click removes the saved share and returns to
37
+ `defaultSize`. `reset()` is exposed for a menu command.
38
+ - Emits `update:modelValue` on every move. Hooks: `data-ui-split-pane`
39
+ (`data-orientation`, `data-dragging` while dragged),
40
+ `data-ui-split-pane-start`, `data-ui-split-pane-separator`,
41
+ `data-ui-split-pane-end`.
42
+
43
+ Choose the orientation from the measured content width, not a viewport media
44
+ query: a DSM window can be narrower than the browser.
45
+
46
+ ## SizeBar
47
+
48
+ A 4px bar for a table cell or list row: `value` against `max` (pass the
49
+ largest row, so that row fills the track), and `part` of it drawn from the
50
+ same start in the full tone, for example the reclaimable part of a size. The
51
+ numbers stay as text beside it.
52
+
53
+ ```vue
54
+ <template #cell-size="{ row }">
55
+ <CellText :text="formatFileSize(row.size)" />
56
+ <SizeBar :value="row.size" :max="largest" :part="row.reclaimable" />
57
+ </template>
58
+ ```
59
+
60
+ | Prop | Default | Meaning |
61
+ | --- | --- | --- |
62
+ | `value` | required | The row's size. `null`, `undefined` or `0` draws an empty track. |
63
+ | `max` | required | The size that fills the track. |
64
+ | `part` | `null` | The part of `value` to emphasise. |
65
+ | `tone` | `'primary'` | `primary`, `success`, `warning` or `danger`. |
66
+ | `label` | unset | Accessible name. Without it the bar is decorative (`aria-hidden`); give one only when the bar stands for numbers that are not shown. |
67
+
68
+ A non-zero value is at least 2px wide. The track colour is
69
+ `--ui-size-bar-track` (default `--ui-gray-a2`). Hooks: `data-ui-size-bar`
70
+ (`data-tone`), `data-ui-size-bar-value`, `data-ui-size-bar-part`.
71
+
72
+ ## StorageMeter
73
+
74
+ "Free now X → Free after Y" over a bar of the volume: used, the part a cleanup
75
+ frees, and free space.
76
+
77
+ ```vue
78
+ <StorageMeter :total="volume.total" :free="volume.free" :freeing="selection.bytes" :at-least="!selection.exact" :pending="selection.checking" />
79
+ ```
80
+
81
+ | Prop | Default | Meaning |
82
+ | --- | --- | --- |
83
+ | `total` / `free` | required | The volume's bytes. |
84
+ | `freeing` | required | Bytes the action frees; clamped to the used bytes. |
85
+ | `atLeast` | `false` | `freeing` is a lower bound: "Free after" reads "At least Y" and the freed part fades out at its end. |
86
+ | `pending` | `false` | A better number is being worked out: the freed part pulses (not with reduced motion) and the meter is `aria-busy`. |
87
+ | `labels` | built-in | `{ freeNow, freeAfter }`, for an app's own wording. |
88
+ | `format` | `formatFileSize` | Byte formatter (DSM's 1024 base). |
89
+
90
+ The meter is one `role="img"` whose name is "Free now X, free after Y". Its
91
+ text and bar follow the surrounding text colour (`currentColor`), so it reads
92
+ on a light page and on a dark action bar alike; "Free after" and the freed
93
+ part use `--ui-primary`. Hooks: `data-ui-storage-meter`,
94
+ `data-ui-storage-meter-now`, `data-ui-storage-meter-after`,
95
+ `data-ui-storage-meter-used`, `data-ui-storage-meter-freeing`
96
+ (`data-at-least`).
@@ -65,6 +65,11 @@ here stay implementation details and can change in any release.
65
65
  | `data-nav-label`, `data-nav-badge` | a row's label and badge | present |
66
66
  | `data-nav-contains-current` | a top-bar branch whose child is the current page | present |
67
67
  | `aria-current` | the current page's row | `page` |
68
+ | `data-ui-top-nav-item` | measurable top-level row wrapper | present |
69
+ | `data-ui-overflowed` | row moved into More (hidden and inert in the bar) | `true` |
70
+ | `data-ui-top-nav-more` | More menu trigger | present |
71
+ | `data-ui-selected` | More trigger when its subtree contains the current page | `true` |
72
+ | `data-ui-top-nav-overflow-menu` | portalled More dropdown panel | present |
68
73
  | `data-ui-sidebar-user` | `AppSidebarUser` | present |
69
74
  | `data-ui-user-avatar`, `data-ui-user-name`, `data-ui-user-detail` | its parts | present |
70
75
 
@@ -94,6 +99,7 @@ before the token existed. Set them on the app root or any ancestor.
94
99
 
95
100
  | Token | Affects | Unset |
96
101
  | --- | --- | --- |
102
+ | `--ui-nav-row-height` | navigation row height/minimum height; inherited from any ancestor, including outside `AppLayout` | window 42px, web 40px, phone 46px |
97
103
  | `--ui-icon-size` | icons in navigation rows (`AppSidebar`, side and top) | 22px in the sidebar, 18px in the top bar |
98
104
  | `--ui-heading-weight` | `PageHeader` title, `Card` title, `TypoHeader`, web toolbar titles | 600 (`PageHeader`, `TypoHeader`, toolbar), 700 (`Card`, web `PageHeader`) |
99
105
  | `--ui-card-padding` | a regular `Card`'s header, body and footer inset; the body's block padding is 0.8× | 20px (body 16px × 20px). Compact cards are unchanged |
@@ -140,3 +146,23 @@ The colour, radius, spacing and web tokens are listed in the
140
146
  ```
141
147
 
142
148
  The Histoire story *DSM 7 / Top navigation and theme hooks* shows both.
149
+
150
+ ## Navigation sizing and overflow
151
+
152
+ Set `--ui-nav-row-height: 30px` on the app's theme ancestor to override all
153
+ presentations. Layout modes set only the internal `--ui-nav-row-height-default`
154
+ fallback; they never redefine the public token. Existing density presets and
155
+ explicit values on a row or layout still take precedence through normal CSS
156
+ inheritance. Sidebar rows can grow to fit wrapped labels.
157
+
158
+ With `navigation="top"`, `AppSidebar` measures the available navigation width,
159
+ row widths (including icons and badges), group spacing and More trigger. The
160
+ trailing items move into More in their original order; nested items and disabled
161
+ states are preserved. More is selected when the current page is anywhere in
162
+ its subtree. Tab reaches the trigger, Enter/Space or ArrowDown opens it,
163
+ arrows navigate, and Escape closes it and returns focus. Resizing or changing
164
+ labels/badges remeasures the row. Hidden bar rows are inert and aria-hidden.
165
+ The phone drawer and default sidebar keep their existing behavior.
166
+
167
+ The portalled panel has `data-ui-top-nav-overflow-menu`; scope panel styles by
168
+ that attribute rather than relying on it being a descendant of the bar.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/ui",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Shared Vue 3 UI component library with a DSM 7 inspired application theme",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -19,6 +19,7 @@
19
19
  "docs/component-defaults-0.5.7.md",
20
20
  "docs/json-ui.md",
21
21
  "docs/layout-rules.md",
22
+ "docs/size-and-split.md",
22
23
  "docs/theme-hooks.md"
23
24
  ],
24
25
  "bin": {