@synopackageland/ui 0.17.12 → 0.17.14

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/docs/callout.md CHANGED
@@ -11,6 +11,20 @@ has its own component, and none of them is a full-width banner.
11
11
  | A risk or a limit of a feature | `<Callout variant="inline">` | One short sentence; longer text in `#details` behind "Learn more", or a link. |
12
12
  | A failure the user has to know about now, outside the page | `Notification` / `MessageBox` | See their docs. |
13
13
 
14
+ ## Closing
15
+
16
+ A Callout is dismissible by default: a 24px ✕ in the top-right corner,
17
+ drawn in the tone, labelled "Close" (`closeLabel`) and reached with Tab.
18
+ Closing hides that callout and emits `close`. It comes back by itself when
19
+ what it says changes: its tone, title, `code` or rendered text (a new error
20
+ message shows again), or `dismissKey` when the App names the condition
21
+ itself. A dismissal lasts while the component is mounted; it is not stored.
22
+
23
+ Set `:dismissible="false"` only for a state that must stay in view until it
24
+ is resolved, such as a setup step the App cannot work without. Never hide the
25
+ only way to an action behind a dismissible callout without another way to it
26
+ on the page.
27
+
14
28
  ## The look
15
29
 
16
30
  A Callout and a Toast share one look: a raised surface in the page's neutral
@@ -76,7 +90,7 @@ Two earlier looks were rejected:
76
90
  - **Message**: one line on why it matters or what happens next: "Share links
77
91
  keep using the old address". Do not explain the steps; the action does them.
78
92
  - **Action**: one button (`Button size="sm"`, drawn as a capsule), or a `Link` when it leaves the
79
- app. Two only when the second is "Later" and the Callout cannot be closed.
93
+ app. Two only when the second is "Later" and the Callout is not dismissible.
80
94
  The button label names what it does: "Apply nas.example.com", not "OK".
81
95
  - **Risk notes**: one sentence. Put the explanation in `#details`:
82
96
 
@@ -114,10 +128,10 @@ Two earlier looks were rejected:
114
128
  | `#actions` | One action, at the end of the message |
115
129
  | `#details` + `v-model:expanded` | Longer text behind a "Learn more" toggle (`moreLabel`, `lessLabel`) |
116
130
  | `code` | A machine error code, shown quieter after the message |
117
- | `closable`, `closeLabel`, `@close` | A close button for a message the user may dismiss |
131
+ | `dismissible` (default `true`), `dismissKey`, `closeLabel`, `@close` | The close button; the callout returns when its text or `dismissKey` changes. `false` only for a state that must stay in view |
118
132
  | `fill` | Span the container instead of stopping at 720px |
119
133
 
120
- Theme hooks (`data-tone`, `data-variant`, `data-fill`, the `data-ui-callout-*`
134
+ Theme hooks (`data-tone`, `data-variant`, `data-fill`, `data-dismissible`, the `data-ui-callout-*`
121
135
  parts) and tokens (`--ui-callout-max-width`, `--ui-callout-radius`,
122
136
  `--ui-callout-glow`, `--ui-callout-shadow`, which Toast shares) are listed in
123
137
  [theme hooks](theme-hooks.md).
@@ -18,7 +18,7 @@ These rules keep pages built from `@synopackageland/ui` consistent. The componen
18
18
  - [Button policy](button-policy.md) says which button goes where: its shape, variant and order.
19
19
  - Buttons that belong together sit in one row with an 8px gap: `FormActions` in a form, the `#footer` slot in a section or card.
20
20
  - Only the bar that closes a dialog or form draws capsule `action` buttons, without a `kind`: `FormActions`, `Footbar`, `AppActionBar`, a `Notification`'s actions, and the footers of `Dialog`, `Wizard`, `Sheet` and `Panel` (`#fbar`), with the main action last. `kind="tool"` opts one button out. A `SettingsSection` or `Card` footer, header actions and content stay `tool` buttons; put a section's Save / Cancel in `FormActions`.
21
- - On a settings form longer than the window, `FormActions sticky` keeps Apply in view at the bottom over a divider. Do not write your own sticky footer.
21
+ - A settings tab's Reset / Apply go in `SettingsPage`'s `#footer`: it stays at the bottom over a divider while only the sections scroll. Do not write your own sticky footer.
22
22
  - Each page has one refresh, in the page header. Panels expose `refresh()` for it instead of their own button.
23
23
  - A disabled primary button keeps readable text. Put the reason next to it, such as "Enter the password to confirm."
24
24
  - Danger actions sit apart from the rest: the explanation comes first, then the button, or a confirm dialog.
@@ -29,24 +29,46 @@ These rules keep pages built from `@synopackageland/ui` consistent. The componen
29
29
  - Labels sit above their controls (`Form direction="vertical"`), except in short DSM-style dialogs.
30
30
  - Size a field by its content: number fields are 128px; text fields use `fieldWidth`. Put two short fields side by side rather than stretching one across the page.
31
31
  - A checkbox's text sits on the same line as its box. Do not apply `display: grid` to `label` in App CSS; `Checkbox` renders its own label.
32
+ - For 2–4 mutually exclusive settings, use `RadioGroup` (vertical by default, `orientation="horizontal"` when labels fit). A checkbox enables an independent option; a switch turns a feature on or off immediately. Keep the circular radio with a dot, square checkbox with a tick, and pill switch with a moving thumb.
33
+ - Reserve `SegmentControl` for toolbar view switching: its selected item is a primary-filled capsule. `variant="sheet"` and `SectionTabs` are navigation tabs. Do not use either as a form value selector.
32
34
  - Choices side by side are 34px apart (`--ui-choice-inline-gap`, DSM's Task Scheduler) and share one top whether checked or not. For a set of checkboxes use `CheckboxGroup` (`orientation="horizontal"` for a row, `v-model` an array of values), as `RadioGroup` for one choice; Checkboxes written one after another get the same gap. Do not add margins between them.
33
35
  - A password field has a show/hide toggle; `Input type="password"` adds it.
34
36
  - Show a NAS path with `PathDisplay`, not a read-only input. It truncates from the start, shows the full path in a tooltip when it is cut, and offers copy. In a table cell use `display="name"`: the folder's name on one line, the full path always in its tooltip, copy still copies the full path.
35
37
 
38
+ ### Settings choice example
39
+
40
+ ```vue
41
+ <FormItem label="Domain and LDAP people">
42
+ <RadioGroup
43
+ v-model="directoryReadMode"
44
+ :options="[
45
+ { value: 'lookup', label: 'When someone looks them up' },
46
+ { value: 'never', label: 'Not read' },
47
+ ]"
48
+ />
49
+ </FormItem>
50
+ ```
51
+
52
+ The setting is a form value, saved with the page's Apply action. It does not navigate between views.
53
+
36
54
  ## Settings pages
37
55
 
56
+ - Use `<SectionTabs fill keep-mounted>` for settings with local unsaved drafts. `keep-mounted` mounts every supplied item panel immediately and hides inactive panels with `v-show`; their effects stay active. Without it, switching tabs unmounts the previous panel. `fill` alone only controls layout. Keep persistent business data and background work in the app when needed.
57
+ - `SettingsPage` spaces direct sibling `SettingsSection`s by `--ui-space-6` (24px); place them directly in its default slot without a `Space` wrapper. `Fieldset` keeps its own DSM spacing.
38
58
  - A settings page has one label column. `FormItem` (horizontal), `SettingsRow` and `KeyValueRow` share `--ui-label-column` (`--ui-label-width`, at most 40% of a narrow row) and `--ui-label-gap`, so SDK panels and App rows line up; `FormActions inset` starts at the same edge. Labels and `KeyValueRow` values break between words, not inside one. Do not pass a different `labelWidth` per section.
39
59
  - Labels sit left in the column, as on DSM's own settings pages: the eye runs down one edge, and a long label wraps instead of pushing the value.
40
60
  - Colours are fixed by role: section title `--ui-text` semibold 14px, label and value `--ui-text`, help text `--ui-text-secondary` 12px.
41
61
  - A `SettingsRow` with a `description` aligns its label with the control's first line, not the middle of control and description.
42
62
  - A row that is only a button: give it a `SettingsRow` label when it acts on one thing, or put it in the section `#footer`. Inside a horizontal form, use `FormActions inset` so the button starts on the value edge.
43
- - A DSM-native settings page reads its structure from indentation and spacing (Control Panel > Network > General). Each section is a `Fieldset`: a blue title with a chevron (up while open) over a dashed divider across the whole width, collapsible. Sections one after another keep a 20px gap. A one-line explanation of the section is the Fieldset's `description`, directly under the title and across the whole width, not in the label column. Fields are one `Form` with one `labelWidth` (or the theme's column) and `FormItem`s; one `Form` may hold several Fieldsets.
63
+ - A DSM-native settings page reads its structure from indentation and spacing (Control Panel > Security; measurements in [dsm-native-metrics.md](dsm-native-metrics.md#settings-page-control-panel--security-network)). Each section is a `Fieldset`: a 15px blue title over a dashed divider across the whole width, collapsible and expanded by default, with a chevron pointing up when expanded and down when collapsed (as Control Panel > Network). Use `:collapsible="false"` for a fixed section without a chevron (as Control Panel > Security). The title text and the fields start 8px in; the next section's title follows 8px after the body. A one-line explanation of the section is the Fieldset's `description`, directly under the title and across the whole width, not in the label column. Fields are one `Form` with one `labelWidth` (or the theme's column) and `FormItem`s; one `Form` may hold several Fieldsets.
64
+ - A checkbox option is a `FormItem :label="false"` with a `Checkbox`: the box sits on the section's left edge and its help text (`description`) is a line of its own under the label text. Do not put a label beside a checkbox or a switch that already says what it does.
44
65
  - A read-only value is a `FormItem` with `text-only`: plain text in the control column, level with its label. A button that acts on it (Edit) goes in the item's `#after` slot and follows the field column.
45
66
  - Options that only matter while a checkbox or switch is on go in a `FormGroup` right after it, with `:disabled="!on"`. The parent is a `FormItem :label="false"`, so it starts at the section's left edge. The group indents one 28px step, disables and dims every control inside, and the labels inside give up the indent so the controls stay on the form's column, as DSM draws them. Nest a `FormGroup` for a second level. Do not indent with your own padding or disable each child by hand.
46
67
  - A section button such as Advanced Settings goes inside the `FormGroup` it belongs to, after its fields, as a plain `Button`: it starts on the group's indent and follows the group's disabled state. Do not centre it or put it in the label column.
47
68
  - A unit goes in the `Input`'s `unit` (or `#unit` slot): `<Input v-model="timeout" type="number" unit="s" />` puts "s" right after the field. Do not put units in the FormItem's `#after` slot, which starts after the whole field column.
48
69
  - Explanation is a short `description` under its field. A note is a `FormNote`: one remark reads "Note: …" on one line, two or more `items` become a list under the heading. Put it under the field it is about with `inset` (it starts on the field column), or at the end of the section without. Facts to read or copy (addresses, paths) go in an `InfoBox`. A warning or an error is a `Callout`. Do not write long full-width paragraphs or a separate "Note:" heading between fields.
49
- - A settings page has one Apply. On a page or window, put Reset then Apply in the footer (`Footbar`, `AppActionBar`), as Control Panel does; inside a form that ends the page, use `FormActions inset`. Do not put a Save between the fields of a section.
70
+ - A settings page has one Apply. Put Reset then Apply in `SettingsPage`'s `#footer`, at the bottom-right, as Control Panel does. Keep the footer while the page has settings to apply, so nothing moves when a draft changes. Do not put a Save between the fields of a section.
71
+ - A button that belongs to a field (Allowed websites, Trusted Proxies, Advanced Settings) is a grey `Button variant="secondary"` in the flow: in the `FormGroup` it depends on, after the field it acts on (`#after`), or under the section's description.
50
72
 
51
73
  ## Tables
52
74
 
@@ -63,7 +85,7 @@ These rules keep pages built from `@synopackageland/ui` consistent. The componen
63
85
  ## Fields
64
86
 
65
87
  - A field with buttons acting on it (a URL and its Install button) goes in `InputGroup`: one line, 8px gap, the field takes the room left.
66
- - Stack page sections with `Space direction="column"` and a pixel `spacing`; add `wrap` to a row of tags or buttons that may run out of room.
88
+ - Outside `SettingsPage`, stack page sections with `Space direction="column"` and a pixel `spacing`; add `wrap` to a row of tags or buttons that may run out of room.
67
89
 
68
90
  ## Numbers and times
69
91
 
@@ -85,6 +107,7 @@ These rules keep pages built from `@synopackageland/ui` consistent. The componen
85
107
  ## Page
86
108
 
87
109
  - `PageHeader` sticks to the top while the content scrolls.
88
- - A list page whose grid pages its rows (downloads, tasks, logs) uses `AppLayout height="fill"` and `PageContent height="fill"`: the header, tabs and toolbar stay, the DataGrid (the last child) fills the height left and scrolls its rows, and its pager stays in view. Do not let the whole page scroll past a 50-row page to reach the pager.
110
+ - A settings page with tabs is `SectionTabs fill` with one `SettingsPage` per panel, in a container with a height (a window, `AppLayout height="fill"`): the tab strip stays at the top, the footer at the bottom, and only the sections scroll. Without a height (a phone page), the page scrolls, the strip sticks to the top and the footer to the bottom, above the safe area. Under 520px of row width labels stack over their controls.
111
+ - `DataGrid` and `DataTable` fill the height their flex-column container leaves by default (`fill`), as DSM's lists do: the header row stays, the rows scroll inside the table, and a DataGrid's footer ("3 items", the pager) sits at the container's bottom whatever the row count. A list page uses `AppLayout height="fill"` and `PageContent height="fill"` so the table, its last child, gets that height. Where the page itself scrolls (a phone), the footer sticks to the bottom of the viewport above the safe area. Give a short table inside a form, a settings section or a dialog `:fill="false"`: it is as tall as its rows. Do not let the whole page scroll past a 50-row page to reach the pager.
89
112
  - `PageHeader` keeps the title and its `meta` slot (an info button, a chip) on one line. Actions that would crowd the title move under it, at the right edge; a title longer than its line ends in "…" and shows in full on hover.
90
113
  - `EmptyState` fills the remaining height and centres its content. Do not add footnotes below it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synopackageland/ui",
3
- "version": "0.17.12",
3
+ "version": "0.17.14",
4
4
  "description": "Shared Vue 3 UI component library with a DSM 7 inspired application theme",
5
5
  "license": "MIT",
6
6
  "type": "module",