@synopackageland/ui 0.13.0 → 0.13.2

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,168 @@
1
+ # Theme hooks: public `data-*` attributes and layout tokens
2
+
3
+ Since 0.13.1 the attributes and tokens on this page are **public API**. An app
4
+ or a workspace theme may select on them in its own CSS and set the tokens on
5
+ any ancestor. Class names, element nesting and every attribute not listed
6
+ here stay implementation details and can change in any release.
7
+
8
+ ## Stability rules
9
+
10
+ - A listed attribute keeps its name, the element it sits on and the values
11
+ listed for it until a **major** release (or a 0.x minor release, which the
12
+ changelog marks as breaking, as for any other API).
13
+ - New values may be added to an attribute in a patch or minor release. A
14
+ selector that tests for a value (`[data-variant='primary']`) keeps working; a
15
+ rule that assumes the listed values are the only ones may not.
16
+ - A token keeps its name and meaning. Its **unset** value is the look the
17
+ component had before the token existed; changing that default is a visible
18
+ change and is announced in the changelog.
19
+ - Removing or renaming a listed attribute or token is breaking: it is first
20
+ deprecated in the changelog for at least one minor release.
21
+ - Select on what is listed, then on standard roles and ARIA states
22
+ (`[aria-current='page']`, `[aria-expanded]`, `[role='dialog']`). Do not
23
+ depend on child order, on the tag of an unlisted element or on Tailwind
24
+ classes.
25
+
26
+ ## Attributes
27
+
28
+ ### Application root and layout
29
+
30
+ | Attribute | On | Values |
31
+ | --- | --- | --- |
32
+ | `data-ui-app` | `AppRoot`'s root and its floating hosts (portals) | present |
33
+ | `data-ui-theme`, `data-ui-density`, `data-ui-accent` | the app root (mirrored on floating hosts) | theme name, `compact`/`comfortable`, present |
34
+ | `data-ui-presentation` | `AppRoot` root | `mobile`, `window`, `web` |
35
+ | `data-ui-floating` | a floating host (dialog, menu, popover) | present |
36
+ | `data-ui-layout-mode` | `AppLayout` root | `mobile`, `window`, `web` |
37
+ | `data-ui-navigation` | `AppLayout` root, and `AppSidebar`'s `<nav>`, while the navigation is a top bar | `top` (absent for the sidebar and on a phone) |
38
+ | `data-ui-layout-height` | `AppLayout` root | `auto`, `fill` |
39
+ | `data-ui-sidebar-collapsed` | `AppLayout` root and `AppSidebar`'s `<nav>` | `true` while the web rail shows icons only |
40
+ | `data-ui-mobile-open` | `AppLayout` root | `true` while the phone drawer is open |
41
+ | `data-ui-layout-sidebar` | the navigation region (left column, top bar, or phone drawer) | present |
42
+ | `data-ui-layout-main` | the page region beside or under the navigation | present |
43
+ | `data-ui-sidebar-brand` | the brand block (web sidebar, top bar, phone bar, drawer header) | present |
44
+ | `data-ui-brand-icon`, `data-ui-brand-name` | the brand's logo `<img>` and name | present |
45
+ | `data-ui-sidebar-body` | wrapper of the `sidebar` slot | present |
46
+ | `data-ui-sidebar-footer` | wrapper of the `sidebar-footer` slot | present |
47
+ | `data-ui-sidebar-collapse` | the web rail's collapse button | present |
48
+ | `data-ui-mobile-navigation` | the phone bar above the page | present |
49
+ | `data-ui-mobile-menu` | the phone bar's menu (hamburger) button | present |
50
+ | `data-ui-mobile-sidebar-header` | the drawer's header row | present |
51
+ | `data-ui-mobile-backdrop` | the drawer's backdrop | present |
52
+ | `data-ui-app-toolbar` | `AppToolbar` | present |
53
+ | `data-ui-page-header` | `PageHeader` | present |
54
+ | `data-ui-page-header-meta`, `data-ui-page-header-actions` | `PageHeader`'s meta and actions areas | present |
55
+ | `data-page-surface` | `PageContent` | `auto`, `card`, `flat`, `none` |
56
+
57
+ ### Navigation rows (`AppSidebar`, side or top)
58
+
59
+ | Attribute | On | Values |
60
+ | --- | --- | --- |
61
+ | `data-nav-item` | a row that selects a page | present |
62
+ | `data-nav-branch` | a row with children (expands in the sidebar, opens a menu in the top bar) | present |
63
+ | `data-nav-group-label` | a group title (sidebar only) | present |
64
+ | `data-nav-group` | a group in the top bar, `role="group"` named by its label | present |
65
+ | `data-nav-label`, `data-nav-badge` | a row's label and badge | present |
66
+ | `data-nav-contains-current` | a top-bar branch whose child is the current page | present |
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 |
73
+ | `data-ui-sidebar-user` | `AppSidebarUser` | present |
74
+ | `data-ui-user-avatar`, `data-ui-user-name`, `data-ui-user-detail` | its parts | present |
75
+
76
+ ### Controls and surfaces
77
+
78
+ | Attribute | On | Values |
79
+ | --- | --- | --- |
80
+ | `data-variant` | `Button` | `primary`, `secondary`, `ghost`, `danger` |
81
+ | `data-variant` | `IconButton` | `primary`, `secondary`, `ghost` |
82
+ | `data-variant` | `SplitButton`'s outer group | `primary`, `secondary` |
83
+ | `data-kind` | `Button` | `tool`, `action` |
84
+ | `data-loading`, `data-disabled` | `Button` | present while loading / explicitly disabled |
85
+ | `data-split-main`, `data-split-arrow` | `SplitButton`'s two halves | present |
86
+ | `data-ui-surface` | `Surface` and every `Card` frame | present |
87
+ | `data-variant` | `Surface` / `Card` frame | `default`, `inset` |
88
+ | `data-ui-dialog`, `data-ui-sheet` | `Dialog` / `Sheet` panels | present |
89
+ | `data-ui-list-item-title`, `-description`, `-meta`, `-actions` | `ListItem` parts | present |
90
+ | `data-ui-statistic-label`, `-value`, `-note` | `Statistic` parts | present |
91
+
92
+ Select a `Button` variant with its tag so a `Surface`'s `data-variant` is not
93
+ caught as well: `button[data-variant='primary']`.
94
+
95
+ ## Layout and theme tokens
96
+
97
+ Each token below is read with a fallback: unset, the component looks as it did
98
+ before the token existed. Set them on the app root or any ancestor.
99
+
100
+ | Token | Affects | Unset |
101
+ | --- | --- | --- |
102
+ | `--ui-nav-row-height` | navigation row height/minimum height; inherited from any ancestor, including outside `AppLayout` | window 42px, web 40px, phone 46px |
103
+ | `--ui-icon-size` | icons in navigation rows (`AppSidebar`, side and top) | 22px in the sidebar, 18px in the top bar |
104
+ | `--ui-heading-weight` | `PageHeader` title, `Card` title, `TypoHeader`, web toolbar titles | 600 (`PageHeader`, `TypoHeader`, toolbar), 700 (`Card`, web `PageHeader`) |
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 |
106
+ | `--ui-top-nav-height` | the top navigation bar | `var(--ui-toolbar-height)` |
107
+ | `--ui-top-nav-bg` | the top navigation bar's background | `var(--ui-surface)`; web: `var(--ui-app-web-surface)` |
108
+ | `--ui-top-nav-border` | its bottom rule | `var(--ui-border)`; web: `var(--ui-app-web-border)` |
109
+ | `--ui-mobile-bar-bg` | the phone bar's background | `var(--ui-surface)` |
110
+ | `--ui-mobile-bar-fg` | the phone bar's text, menu button and brand | `var(--ui-text-secondary)` (text), `var(--ui-text)` (button, brand) |
111
+ | `--ui-mobile-bar-border` | the phone bar's bottom rule | `var(--ui-border-subtle)` |
112
+
113
+ The colour, radius, spacing and web tokens are listed in the
114
+ [README](../README.md#theme-override), [colour system](color-system.md) and
115
+ [adaptive layout](adaptive-layout.md#safe-overrides).
116
+
117
+ ## Example: a dark top bar
118
+
119
+ ```css
120
+ [data-ui-app] {
121
+ --ui-top-nav-bg: #111827;
122
+ --ui-top-nav-border: #111827;
123
+ --ui-mobile-bar-bg: #111827;
124
+ --ui-mobile-bar-fg: #f9fafb;
125
+ --ui-icon-size: 20px;
126
+ --ui-heading-weight: 700;
127
+ --ui-card-padding: 24px;
128
+ }
129
+ /* Text inside the bar reads on the dark background. */
130
+ [data-ui-app] [data-ui-layout-sidebar] {
131
+ --ui-text: #f9fafb;
132
+ --ui-text-muted: #9ca3af;
133
+ --ui-surface-hover: rgb(255 255 255 / 0.08);
134
+ }
135
+ [data-ui-app] button[data-variant='primary'] {
136
+ border-radius: 999px;
137
+ }
138
+ ```
139
+
140
+ ```vue
141
+ <AppLayout navigation="top" wide-layout="web">
142
+ <template #sidebar><AppSidebar v-model="page" :groups="groups" /></template>
143
+ <template #sidebar-footer><AppSidebarUser name="Ada Lin" /></template>
144
+ <PageContent>…</PageContent>
145
+ </AppLayout>
146
+ ```
147
+
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.0",
3
+ "version": "0.13.2",
4
4
  "description": "Shared Vue 3 UI component library with a DSM 7 inspired application theme",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -18,7 +18,8 @@
18
18
  "docs/color-system.md",
19
19
  "docs/component-defaults-0.5.7.md",
20
20
  "docs/json-ui.md",
21
- "docs/layout-rules.md"
21
+ "docs/layout-rules.md",
22
+ "docs/theme-hooks.md"
22
23
  ],
23
24
  "bin": {
24
25
  "syno-pkg-land-ui": "./dist/cli.js"