@mtdt/observeops-ds-spec 0.1.8 → 0.1.9
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/AGENTS.md +3 -1
- package/components/registry/button.json +10 -0
- package/components/registry/data-viz-tooltips.json +144 -2
- package/components/registry/date-time-pickers.json +36 -1
- package/components/registry/drawer.json +10 -0
- package/components/registry/dropdown-picker.json +35 -0
- package/components/registry/filters.json +29 -2
- package/components/registry/form-item.json +25 -0
- package/components/registry/input.json +5 -0
- package/components/registry/layout-page-templates.json +9 -0
- package/components/registry/layout-panels.json +41 -1
- package/components/registry/layout-screen-regions.json +8 -0
- package/components/registry/link.json +15 -0
- package/components/registry/loose-tags.json +5 -0
- package/components/registry/menu.json +12 -0
- package/components/registry/modal.json +20 -0
- package/components/registry/navigation.json +77 -0
- package/components/registry/popover.json +25 -0
- package/components/registry/radio.json +15 -0
- package/components/registry/scheduler.json +20 -0
- package/components/registry/select.json +5 -0
- package/components/registry/selected-pills.json +45 -1
- package/components/registry/severity.json +48 -1
- package/components/registry/table.json +30 -0
- package/components/registry/tabs.json +25 -0
- package/components/registry/tag.json +45 -0
- package/components/registry/toolbars.json +32 -0
- package/components/registry/tooltip.json +15 -0
- package/package.json +1 -1
- package/spec.manifest.json +59 -59
|
@@ -421,5 +421,82 @@
|
|
|
421
421
|
],
|
|
422
422
|
"doc": "Molecules/Navigation/Accessibility",
|
|
423
423
|
"$note": "Catalogue-wide gap SF-001 = no visible :focus-visible ring; tracked in findings/."
|
|
424
|
+
},
|
|
425
|
+
"usageRules": {
|
|
426
|
+
"primary-nav": {
|
|
427
|
+
"useWhen": "You need the app's global wayfinding between top-level product MODULES. This is the left vertical FlotoNavBar sidebar (MLayoutSider): collapsed to 65px by default (brand mark + module icons), hover-expands/pins to 170px (ObserveOps logo + labels). Renders the role/license-gated visibleMenuItems set with the active module highlighted --primary and an inset left rule when expanded.",
|
|
428
|
+
"dontUse": "Don't use it to navigate SECTIONS inside a single module (use side-menu-*), for sibling views of one page (use Tabs, Molecules/Tabs), or for a step-through flow (use steps). Don't hand-roll a module rail — reuse FlotoNavBar.",
|
|
429
|
+
"example": "The ObserveOps left module sidebar switching between Dashboards, Monitors, Alerts, SLO (BETA), Reports, Topology, NCCM, NetRoute, the Explorers, Audits, and Settings."
|
|
430
|
+
},
|
|
431
|
+
"side-menu-section": {
|
|
432
|
+
"useWhen": "A module's left panel is a fixed set of named SECTIONS that each expand to sub-items. This is the MCollapse accordion form (settings/components/left-menu.vue, ~20 uses) with an active --primary left rule.",
|
|
433
|
+
"dontUse": "Don't use it when the content is a nested hierarchy (side-menu-tree), a category list with counts/favourites (side-menu-categories), or a searchable flat saved-views list (side-menu-list). Don't use it for top-level modules (primary-nav).",
|
|
434
|
+
"example": "The Settings module left menu — an MCollapse accordion of setting sections (e.g. General, Users & Roles, Monitoring) expanding to their sub-items."
|
|
435
|
+
},
|
|
436
|
+
"side-menu-tree": {
|
|
437
|
+
"useWhen": "The left panel must present an infinite/virtualised HIERARCHY — chevron + type icon/severity + name + count badge, nested, often above Type/Group/Saved Query tabs. Built on the shared components/hierarchy/infinite-tree.vue (RecycleScroller).",
|
|
438
|
+
"dontUse": "Don't use a tree for a flat list of sections (side-menu-section), for dashboard categories (side-menu-categories), or for saved-view lists with inline rename (side-menu-list). A faceted checkbox sidebar that filters a grid is NOT this — it's Filters → Vertical filter.",
|
|
439
|
+
"example": "The Log Explorer and Topology hierarchy panels — a virtualised tree of types/groups with severity icons and count badges under Type/Group/Saved Query tabs."
|
|
440
|
+
},
|
|
441
|
+
"side-menu-categories": {
|
|
442
|
+
"useWhen": "The left panel groups items into CATEGORIES with count badges and a favourite star, fronted by segmented tabs and an add (+) button. This is the dashboard-dropdown.vue form (MCollapse categories).",
|
|
443
|
+
"dontUse": "Don't use it for plain setting sections (side-menu-section), a deep hierarchy (side-menu-tree), or a searchable saved-query list (side-menu-list).",
|
|
444
|
+
"example": "The Dashboard picker — segmented Dashboard/NOC tabs + a round add button over MCollapse dashboard categories showing count badges and a favourite star."
|
|
445
|
+
},
|
|
446
|
+
"side-menu-list": {
|
|
447
|
+
"useWhen": "The left panel is a searchable FLAT list of saved views/reports with tabs, a Favorites star, active highlight, and per-row pencil inline-rename. This is the report-sidebar.vue / ExplorerSavedViewList form (MInput + MMenu).",
|
|
448
|
+
"dontUse": "Don't use it when items are naturally sectioned (side-menu-section), hierarchical (side-menu-tree), or category-grouped with counts (side-menu-categories).",
|
|
449
|
+
"example": "The Reports sidebar and the APM/RUM/Metric/Log Explorer saved-view lists — tabs + search + a flat list with a Favorites star and inline pencil rename per row."
|
|
450
|
+
},
|
|
451
|
+
"steps": {
|
|
452
|
+
"useWhen": "You are guiding the user through an ordered multi-step create/setup FLOW and must show progress: a count circle + label per step in completed (✓ filled) · current (filled + ring) · remaining (grey), with connectors filling --primary up to the current step. Bespoke in-product (no MSteps).",
|
|
453
|
+
"dontUse": "Don't use it for navigating between unordered sections (side-menu-*) or peer views (Tabs). Don't hand-roll yet another stepper — model it on the existing report/setup/2FA patterns.",
|
|
454
|
+
"example": "The Report Builder's horizontal 3-step wizard (Report Properties → Visualizations & Preview → Schedule); also the Product Setup Guide vertical steps and the 2FA Step 1/2/3 indicator."
|
|
455
|
+
},
|
|
456
|
+
"breadcrumb": {
|
|
457
|
+
"useWhen": "You need to show the user's LOCATION plus a way up — a back chevron + a path trail (e.g. Reports / Compliance / PCI-DSS Audit) with the current crumb bold. Lives in the Page header (hosted by Toolbars).",
|
|
458
|
+
"dontUse": "Don't use it for a graph traversal/expansion trail (that's graph-breadcrumb), for just going back one level (back-button), or for actions (a toolbar holds actions, not location).",
|
|
459
|
+
"example": "The compliance report header trail — Reports / Compliance / PCI-DSS Audit — with a back chevron (compliance-breadcrumb.vue)."
|
|
460
|
+
},
|
|
461
|
+
"back-button": {
|
|
462
|
+
"useWhen": "The user only needs to go BACK one level. This is the smallest nav atom — a chevron-left MIcon inside a FlotoLink (router :to) — FlotoBackButton, also the Page header's back-button slot.",
|
|
463
|
+
"dontUse": "Don't use it when the user needs to see where they are or jump multiple levels up (use breadcrumb), or to switch modules/sections (primary-nav / side-menu-*).",
|
|
464
|
+
"example": "The chevron-left back control in a detail page's Page header back-button slot (FlotoBackButton), returning to the list view."
|
|
465
|
+
},
|
|
466
|
+
"user-menu": {
|
|
467
|
+
"useWhen": "App-level chrome for the signed-in account: a header avatar opening an MPopover with My Profile / Product Setup Guide / Documentation, the theme toggle (Dark/Light/Auto), and Logout.",
|
|
468
|
+
"dontUse": "Don't use it for module/section navigation (primary-nav / side-menu-*) or for alerts/system notices (notification-dropdown). It's account chrome, not page wayfinding.",
|
|
469
|
+
"example": "The top-app-header avatar (user-dropdown.vue) → My Profile, theme Dark/Light/Auto toggle, and Logout."
|
|
470
|
+
},
|
|
471
|
+
"notification-dropdown": {
|
|
472
|
+
"useWhen": "App-level chrome to surface alerts/system notices: a header bell + MBadge count opening Alerts / System Notification tabs (MTab) over a RecycleScroller list with View all / Clear all.",
|
|
473
|
+
"dontUse": "Don't use it for account actions (user-menu), global search (omnibox), or in-page content navigation. It's an app-header notifier only.",
|
|
474
|
+
"example": "The app-header bell with an unread MBadge (notification-dropdown.vue) → Alerts / System Notification tabs, list, and View all / Clear all."
|
|
475
|
+
},
|
|
476
|
+
"omnibox": {
|
|
477
|
+
"useWhen": "You need a global search / command palette: a category picker + CodeMirror query editor + Execute (enter) with parse-error and clear. App-header chrome for cross-product querying.",
|
|
478
|
+
"dontUse": "Don't use it for the per-panel search inside a side menu (that's the side-menu-list/tree search input), for account chrome (user-menu), or for notifications (notification-dropdown).",
|
|
479
|
+
"example": "The global search bar in the app header (omnibox/searchbar.vue) — pick a category, type a query in the CodeMirror editor, press Enter to Execute."
|
|
480
|
+
},
|
|
481
|
+
"noc-player": {
|
|
482
|
+
"useWhen": "You need to auto-cycle a wallboard through dashboards: a rotator with logo + prev/next around the current dashboard title + a countdown + play/pause. For NOC/wallboard viewing.",
|
|
483
|
+
"dontUse": "Don't use it to pick or manage dashboards (side-menu-categories / dashboard-dropdown) or to step through time (timeline-scrollbar). It's a hands-off rotation player.",
|
|
484
|
+
"example": "The NOC wallboard rotator (noc-player.vue) — ObserveOps logo, prev/next around the current dashboard title, countdown, and play/pause."
|
|
485
|
+
},
|
|
486
|
+
"timeline-scrollbar": {
|
|
487
|
+
"useWhen": "You need a TEMPORAL navigator that steps through time-bucketed snapshots: single (chevron) + batch (double-chevron) step controls around a time window. Used in NetRoute for stepping historical snapshots.",
|
|
488
|
+
"dontUse": "Don't use it to rotate dashboards (noc-player) or as a general page nav. It navigates time, not views.",
|
|
489
|
+
"example": "The NetRoute timeline scrollbar (timeline-scrollbar.vue) — single and double-chevron controls stepping the time-bucketed path snapshots."
|
|
490
|
+
},
|
|
491
|
+
"graph-breadcrumb": {
|
|
492
|
+
"useWhen": "You are traversing/expanding a graph and need to show the expansion trail as closable rounded MTags of expanded nodes, each removable to collapse that branch. A Breadcrumb variant for graph views.",
|
|
493
|
+
"dontUse": "Don't use it for a normal page location trail (breadcrumb) or for going back one level (back-button). It's specific to graph node expansion.",
|
|
494
|
+
"example": "The NetRoute graph view's expansion trail (graph-view.vue) — closable rounded MTags of the expanded graph nodes."
|
|
495
|
+
},
|
|
496
|
+
"metric-picker": {
|
|
497
|
+
"useWhen": "Cross-reference only — a Metric Explorer picker (⊕-add + drag) for choosing metrics. It LOOKS like a side menu but is a PICKER, not wayfinding; catalogued under DropdownPicker.",
|
|
498
|
+
"dontUse": "Don't treat it as navigation. For sectioned/tree/category/list left panels use the side-menu-* forms; for the picker behaviour itself see DropdownPicker.",
|
|
499
|
+
"example": "The Metric Explorer add-metric panel (⊕-add + drag) — referenced from Navigation but owned by DropdownPicker."
|
|
500
|
+
}
|
|
424
501
|
}
|
|
425
502
|
}
|
|
@@ -165,6 +165,31 @@
|
|
|
165
165
|
"useWhen": "a passive reveal on hover (no click) — +N overflow, quick peek",
|
|
166
166
|
"how": "trigger='hover' (often transition-name='slide-up')",
|
|
167
167
|
"example": "tags-list '+N' overflow (13x use hover)"
|
|
168
|
+
},
|
|
169
|
+
"click": {
|
|
170
|
+
"useWhen": "The anchored content is interactive and should open on an explicit click — a menu, picker, or mini-form the user deliberately opens. This is the default trigger (20× in the product) and the right choice for anything requiring interaction rather than a passive peek.",
|
|
171
|
+
"dontUse": "Don't use click for a passive '+N overflow' or quick-info peek that should reveal on hover (use trigger=hover); don't use it for a short non-interactive hint (use MTooltip); and don't use it for a center-interrupting task or confirmation (use MModal).",
|
|
172
|
+
"example": "The color picker (color-picker.vue) and date/time pickers open their panel on a click trigger; FlotoGridActions kebab menus also click-open."
|
|
173
|
+
},
|
|
174
|
+
"hover": {
|
|
175
|
+
"useWhen": "You want a passive reveal with no click — the '+N overflow' pill that shows hidden items, or a quick info peek. Common in the product (13×), usually paired with transition-name='slide-up'.",
|
|
176
|
+
"dontUse": "Don't use hover for menus or pickers that need deliberate interaction (use trigger=click); don't use it for a plain text hint (use MTooltip); don't use it when content must stay open while the user works inside it.",
|
|
177
|
+
"example": "The '+N' overflow reveal in tags-list.vue and interface-template.vue that surfaces the hidden tags/items on hover (13× of popovers use hover)."
|
|
178
|
+
},
|
|
179
|
+
"action-menu": {
|
|
180
|
+
"useWhen": "You need a kebab (ellipsis-v) menu of item actions opening a dark picker-action-dropdown panel, placement='bottomRight', transition-name='slide-up', each item calling hide() on select. This is the shared FlotoGridActions engine (_base-grid-actions.vue, 89×) — use for widget-header chrome (Full Screen · Share · Export as CSV) or the multi-select bulk-action bar's 'More' overflow.",
|
|
181
|
+
"dontUse": "Don't use it for a single table row's actions when you specifically need the Edit·Clone·Disable·Delete(red) set below a divider — that's the grid-row-actions variant; don't use it for a picker or mini-form (use rich-panel); don't hand-roll a select dropdown (use FlotoDropdownPicker).",
|
|
182
|
+
"example": "The widget-header kebab (widget-title.vue) with Full Screen · Share · Export as CSV, and the bulk-action bar 'More' overflow kebab (_base-bulk-action-bar.vue) that opens upward (topRight) with overlay-class bulk-action-bar-more."
|
|
183
|
+
},
|
|
184
|
+
"grid-row-actions": {
|
|
185
|
+
"useWhen": "A table ROW needs its per-row actions — Edit · Clone · Disable · divider · Delete(red). The 89× default of FlotoGridActions: ellipsis-v trigger, placement='bottomRight', a divider plus a danger item (isDanger -> text-secondary-red), each item calling hide().",
|
|
186
|
+
"dontUse": "Don't use it for widget chrome or multi-select toolbars (use the action-menu variants — widget-header kebab / bulk-action bar); don't use it for a picker/mini-form (use rich-panel); don't use it for a passive hover reveal (use hover).",
|
|
187
|
+
"example": "The grid row kebab across list tables — Edit · Clone · Disable · — · Delete (red, below a divider) — the 89× default rendered by _base-grid-actions.vue."
|
|
188
|
+
},
|
|
189
|
+
"rich-panel": {
|
|
190
|
+
"useWhen": "An interactive picker or small mini-form should float by its trigger. Use trigger='click' plus a custom overlay-class-name to style the floating panel.",
|
|
191
|
+
"dontUse": "Don't use it for a list of item actions (use action-menu / grid-row-actions); don't use it for a plain hint (use MTooltip); don't use it for a select-from-options field (use FlotoDropdownPicker, which uses MPopper internally); don't use it for a center-interrupting task (use MModal).",
|
|
192
|
+
"example": "The color picker (color-picker.vue) with overlay-class color-picker-popover, and the date/time picker panels (picker-overlay / picker-action-dropdown overlay classes)."
|
|
168
193
|
}
|
|
169
194
|
},
|
|
170
195
|
"placementVocabulary": "Ant names (bottomLeft/bottomRight/leftTop/bottom/top) — NOT the Tooltip's VTippy names (top-start). Not interchangeable.",
|
|
@@ -174,6 +174,21 @@
|
|
|
174
174
|
},
|
|
175
175
|
"size=small": {
|
|
176
176
|
"useWhen": "dense toolbars (segmented)"
|
|
177
|
+
},
|
|
178
|
+
"list": {
|
|
179
|
+
"useWhen": "Pick exactly one from a few options where labels may be longer, inside a form or settings panel — the default radio style, laid out vertically or inline. Used for form fields and mode choosers with descriptions.",
|
|
180
|
+
"dontUse": "Don't use for a compact side-by-side toggle (use segmented), for multi-select (Checkbox), instant on/off (Switch), or more than ~6 options / tight space / needs search (DropdownPicker).",
|
|
181
|
+
"example": "Severity Low / Medium / High on a form; a mode chooser with per-option descriptions."
|
|
182
|
+
},
|
|
183
|
+
"segmented": {
|
|
184
|
+
"useWhen": "A small set (2-5) of always-visible, mutually-exclusive choices that benefit from being compact and side-by-side — rendered as joined buttons via as-button (255x). This is also the Button family's segmented control.",
|
|
185
|
+
"dontUse": "Don't use for long labels or vertical form fields (use list), when each option needs an icon to be clear (use segmented-with-icons), for the alert-severity look (use severity-switch), or for >6 options (DropdownPicker).",
|
|
186
|
+
"example": "Time range 1h / 24h / 7d / 30d and chart view toggles in the metric explorer toolbars and anomaly/forecast/outlier modals."
|
|
187
|
+
},
|
|
188
|
+
"segmented-with-icons": {
|
|
189
|
+
"useWhen": "A segmented control where each segment reads better with an icon — view/mode toggles. Put the icon in the option slot (as-button + icon; without-icon-margin context, 14x).",
|
|
190
|
+
"dontUse": "Don't use when text labels alone are clear (plain segmented), for form fields with long labels (list), or for the borderless separator alert-severity look (severity-switch).",
|
|
191
|
+
"example": "Grid / list / map view toggle."
|
|
177
192
|
}
|
|
178
193
|
},
|
|
179
194
|
"do": [
|
|
@@ -120,6 +120,26 @@
|
|
|
120
120
|
"useWhen": "a single scheduled run",
|
|
121
121
|
"how": ":show-only-once",
|
|
122
122
|
"example": "a one-time discovery run"
|
|
123
|
+
},
|
|
124
|
+
"Once": {
|
|
125
|
+
"useWhen": "The job runs exactly one time at a chosen Start Date and Hours, with no recurrence. Reach it either from the segmented type control or by collapsing the whole component to this type with :show-only-once when recurrence never applies.",
|
|
126
|
+
"dontUse": "Don't use when the job should repeat on any cadence (use Daily/Weekly/Monthly), and don't use it as a plain date/time value picker inside a form — that's MDatePicker.",
|
|
127
|
+
"example": "A one-time, non-recurring network discovery run in discovery-schedules (ScheduleInput with :show-only-once collapsing to the Once sub-form: Start Date + Hours)."
|
|
128
|
+
},
|
|
129
|
+
"Daily": {
|
|
130
|
+
"useWhen": "The job repeats every day at one or more selected Hours from the Start Date onward — the simplest recurring cadence (same sub-form as Once: Start Date + Hours).",
|
|
131
|
+
"dontUse": "Don't use when the job should only run on certain weekdays (use Weekly) or on specific calendar dates/months (use Monthly), and don't use for a single non-repeating run (use Once / :show-only-once).",
|
|
132
|
+
"example": "A nightly device-config backup in backup-profile-form / device-inventory-schedule-backup, set to run every day at the chosen hour."
|
|
133
|
+
},
|
|
134
|
+
"Weekly": {
|
|
135
|
+
"useWhen": "The job repeats on specific weekdays — adds a Days (Mon–Sun) multi-select (FlotoDropdownPicker) on top of Start Date + Hours.",
|
|
136
|
+
"dontUse": "Don't use when the job runs every day regardless of weekday (use Daily) or when it must land on specific calendar dates within chosen months (use Monthly).",
|
|
137
|
+
"example": "A weekly compliance audit in compliance-audit-schedules that runs on selected weekdays (e.g. Mon/Wed/Fri) at a set hour."
|
|
138
|
+
},
|
|
139
|
+
"Monthly": {
|
|
140
|
+
"useWhen": "The job repeats on specific calendar dates within chosen months — adds Months (Jan–Dec) and Dates (1–31) multi-selects (FlotoDropdownPicker) on top of Start Date + Hours.",
|
|
141
|
+
"dontUse": "Don't use when a weekday cadence is enough (use Weekly) or a plain every-day/one-off run suffices (use Daily/Once); don't overload it for chart time windows (that's TimeRangePicker).",
|
|
142
|
+
"example": "A monthly compliance/report run in report-form or compliance-audit-schedules scheduled for specific dates (e.g. the 1st) across selected months."
|
|
123
143
|
}
|
|
124
144
|
},
|
|
125
145
|
"do": [
|
|
@@ -191,6 +191,11 @@
|
|
|
191
191
|
"tags": {
|
|
192
192
|
"useWhen": "free-type tags — but prefer LooseTags",
|
|
193
193
|
"example": "the 2 real usages (LooseTags / object-tag-picker)"
|
|
194
|
+
},
|
|
195
|
+
"single": {
|
|
196
|
+
"useWhen": "You specifically need the raw Ant a-select single-select primitive (mode=default) — the low-level combobox with optional show-search and allow-clear. Effectively a reference/primitive case; in this product a real single select is almost never MSelect.",
|
|
197
|
+
"dontUse": "For any actual single-select in a form or filter bar, use FlotoDropdownPicker (the product norm, 510x) instead — it handles search, virtualized lists, custom triggers, and inline-add. Also avoid relying on allow-clear here: the clear × renders blank (fas icon not registered, F4) and overlaps the chevron (F5); use FlotoDropdownPicker when you need a clearable select.",
|
|
198
|
+
"example": "Low-level primitive only — no product single-select ships on MSelect; every real dropdown (column selector, severity picker, monitor/group selection) uses FlotoDropdownPicker."
|
|
194
199
|
}
|
|
195
200
|
},
|
|
196
201
|
"do": [
|
|
@@ -50,5 +50,49 @@
|
|
|
50
50
|
"dropdown-picker",
|
|
51
51
|
"tag"
|
|
52
52
|
],
|
|
53
|
-
"storybook": "Molecules/TagsList"
|
|
53
|
+
"storybook": "Molecules/TagsList",
|
|
54
|
+
"decisionFlow": [
|
|
55
|
+
"You don't pick this directly — it's the READ-ONLY display of chosen values INSIDE a DropdownPicker / multi-select trigger.",
|
|
56
|
+
"Need users to ADD/REMOVE free-text tags? -> LooseTags (input), not selected-pills.",
|
|
57
|
+
"Showing a status/severity, or a standalone labelled chip? -> Tag / Severity, not selected-pills."
|
|
58
|
+
],
|
|
59
|
+
"variants": [
|
|
60
|
+
{
|
|
61
|
+
"name": "read-only-pills",
|
|
62
|
+
"what": "teal key:value pills for the current selection, display-only"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "overflow-popover",
|
|
66
|
+
"what": "a '+N' pill that opens a popover listing the remaining selected values"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"sizes": [
|
|
70
|
+
{
|
|
71
|
+
"name": "default",
|
|
72
|
+
"value": "—",
|
|
73
|
+
"note": "single size; matches the picker trigger"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"states": [
|
|
77
|
+
{
|
|
78
|
+
"name": "default",
|
|
79
|
+
"what": "pills within max-items shown inline"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "overflow",
|
|
83
|
+
"what": "selection exceeds max-items -> '+N' pill + popover"
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"usageRules": {
|
|
87
|
+
"read-only-pills": {
|
|
88
|
+
"useWhen": "showing the current multi-selection inside a picker/multi-select trigger (display-only)",
|
|
89
|
+
"dontUse": "letting users type/add tags (-> LooseTags); a standalone status chip (-> Tag/Severity)",
|
|
90
|
+
"example": "the chosen monitors/tags shown in a FlotoDropdownPicker trigger"
|
|
91
|
+
},
|
|
92
|
+
"overflow-popover": {
|
|
93
|
+
"useWhen": "the selection exceeds the trigger's max-items — collapse the rest behind a '+N' pill + popover",
|
|
94
|
+
"dontUse": "when all pills fit (show them inline)",
|
|
95
|
+
"example": "'MySQL, PostgreSQL +3' in a multi-select filter value"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
54
98
|
}
|
|
@@ -193,5 +193,52 @@
|
|
|
193
193
|
"unknown",
|
|
194
194
|
"suspended",
|
|
195
195
|
"none"
|
|
196
|
-
]
|
|
196
|
+
],
|
|
197
|
+
"usageRules": {
|
|
198
|
+
"dot": {
|
|
199
|
+
"useWhen": "Default. You have a monitor/alert severity LEVEL (critical/major/warning/clear/up/down/maintenance/…) and need the compact colour indicator in a dense context — a grid cell, list row, topology node, or inline beside a name — where a coloured dot plus hover tooltip conveys the level without eating horizontal space. Pass `severity` directly, or `objectId`(+`instance`/`counter`) to live-resolve.",
|
|
200
|
+
"dontUse": "Don't use in an a11y-sensitive standalone context where the dot is the only signal (WCAG 1.4.1, F2) — add `displayText` (dot+label) or keep the tooltip. For a status STRING (running/failed/poweredoff) use MStatusTag, not this. For counts per level use count-box; for a left row rule use stripe.",
|
|
201
|
+
"example": "The severity dot beside each monitor in the Inventory monitor list and on topology graph nodes, resolving live from the monitor's objectId via the DB worker."
|
|
202
|
+
},
|
|
203
|
+
"dot+label": {
|
|
204
|
+
"useWhen": "You want the dot AND the capitalized level text — set `displayText=true`. Preferred for accessibility (satisfies WCAG 1.4.1 so severity isn't colour-only) and for standalone contexts with room for a word: detail panels, alert headers, cards where the reader shouldn't have to hover to learn the level.",
|
|
205
|
+
"dontUse": "Don't use in tight grid cells or icon rails where the label wraps or crowds the layout — use the bare `dot` (with tooltip) there. Don't use for choosing a level (that's picker) or for aggregate counts (count-box).",
|
|
206
|
+
"example": "The alert detail header showing the dot followed by 'Critical' / 'Major', so the level reads without hovering."
|
|
207
|
+
},
|
|
208
|
+
"solid-chip": {
|
|
209
|
+
"useWhen": "You need a filled pill — background `--severity-<level>` with white text (the plain/solid mode) — for a high-emphasis, standalone severity badge that must stand out on its own, e.g. a prominent alert-severity badge in a header or banner where a small dot would be too subtle.",
|
|
210
|
+
"dontUse": "Don't use in dense tables/lists where a filled pill per row is visually heavy — use `dot`. Don't confuse with MStatusTag's `tag-*` pills: those map status STRINGS; solid-chip is still the Severity component rendering a severity LEVEL. Don't hardcode the fill — use `--severity-<level>`.",
|
|
211
|
+
"example": "A filled critical/major severity badge in an alert banner or summary header, using the --severity-<level> background with white text."
|
|
212
|
+
},
|
|
213
|
+
"text": {
|
|
214
|
+
"useWhen": "You have a numeric or value string that should be tinted by severity — coloured `--severity-<level>` text in JetBrains Mono (`.text` mode). Use for metric values, thresholds, or counts whose colour must communicate the level while keeping the number readable, e.g. a monitored value shown in critical red.",
|
|
215
|
+
"dontUse": "Don't use for a categorical level indicator where a dot reads faster (`dot`/`dot+label`). Don't rely on colour alone for the number's meaning if the value must be understood by colour-blind users — pair with a label. Don't hardcode the colour; use the `--severity-<level>` token.",
|
|
216
|
+
"example": "A KPI/threshold metric value rendered in --severity-critical red monospaced text when it breaches the critical threshold."
|
|
217
|
+
},
|
|
218
|
+
"bg-fill": {
|
|
219
|
+
"useWhen": "You need to tint a whole row or cell by severity — `--severity-<level>-lighter` background tint + 1px `--severity-<level>` border (generateSeverityBg / `.bg`). Use to make an entire alert/monitor row scannable by severity at a glance in a grid or list.",
|
|
220
|
+
"dontUse": "Don't use when only the indicator needs colour (use `dot`) or when a left edge rule suffices (use `stripe`) — a full-cell tint is heavier. Avoid on already-dense tables where the tint fights other status colours. Don't hardcode; use the `-lighter` + border tokens.",
|
|
221
|
+
"example": "An alert grid where each critical/major row is tinted with the matching --severity-<level>-lighter background so operators triage by scanning colour."
|
|
222
|
+
},
|
|
223
|
+
"stripe": {
|
|
224
|
+
"useWhen": "You want a coloured left rule down a list row or card (`severity-stripe.vue`) to band items by severity without tinting the whole surface. Per the decisionFlow: 'Need a coloured stripe down a list row/card? → severity-stripe.' Shown both as a standalone bar and as a table/list left-rule row.",
|
|
225
|
+
"dontUse": "Don't use when the full row should be tinted (that's bg-fill) or when a compact inline mark is enough (dot). Don't use to pick a level (picker) or to show counts (count-box).",
|
|
226
|
+
"example": "The coloured left-edge rule on each alert/notification list row (and the standalone severity bar), banding rows by --severity-<level>."
|
|
227
|
+
},
|
|
228
|
+
"picker": {
|
|
229
|
+
"useWhen": "You need to let the USER choose a severity level — `severity-picker.vue` / `compliance-severity-picker`. Per the decisionFlow: 'Let the user pick a severity level (policy/condition forms)? → severity-picker.' Use in alert-policy and condition/threshold forms where an author sets which level a rule maps to.",
|
|
230
|
+
"dontUse": "Don't use to merely DISPLAY a resolved level (use `dot`/`dot+label`). Don't hand-roll a level dropdown — the picker already renders the --severity-* swatches.",
|
|
231
|
+
"example": "The severity selector in an alert-policy / threshold-condition form (and compliance-severity-picker in compliance rules) where the author assigns critical/major/warning to a condition."
|
|
232
|
+
},
|
|
233
|
+
"count-box": {
|
|
234
|
+
"useWhen": "You need to show COUNTS per severity on a dashboard — `dashboard/severity-count-box.vue`. Per the decisionFlow: 'Show counts per severity on a dashboard? → severity-count-box.' Use for the at-a-glance tally of how many objects sit at each level.",
|
|
235
|
+
"dontUse": "Don't use for a single object's level (that's `dot`/`dot+label`) or to pick a level (picker). Don't rebuild an aggregate tile from bare dots — count-box already pairs each --severity-<level> with its number.",
|
|
236
|
+
"example": "The dashboard summary box tallying counts of critical / major / warning / clear monitors across the environment."
|
|
237
|
+
},
|
|
238
|
+
"switch": {
|
|
239
|
+
"useWhen": "You need an alert-severity TOGGLE control (severity-switch) — a switch-style control for enabling/setting severity, catalogued under Atoms/Radio. Use where a form toggles severity handling rather than displaying or free-picking a level.",
|
|
240
|
+
"dontUse": "Don't use to display a resolved severity (use `dot`) or to pick from the full list of levels in a form (use `picker`). See Atoms/Radio for the switch's own variants/states — this is a cross-reference, not a distinct Severity render mode.",
|
|
241
|
+
"example": "The alert severity toggle (severity-switch) in alert/notification settings, cross-referenced from Atoms/Radio."
|
|
242
|
+
}
|
|
243
|
+
}
|
|
197
244
|
}
|
|
@@ -230,6 +230,36 @@
|
|
|
230
230
|
"useWhen": "each row has detail",
|
|
231
231
|
"how": "expandable + detailRow slot",
|
|
232
232
|
"example": "discovered services, trace spans, interface details"
|
|
233
|
+
},
|
|
234
|
+
"basic": {
|
|
235
|
+
"useWhen": "You have a plain dataset to render as columns + rows with sortable headers — either data already in memory (`MGrid` with `:data` + `:columns`) or a fetched/paginated/searchable list page (the default, via `FlotoPaginatedCrud`, which wraps MGrid and owns fetch/paging/search/filters). The main `.k-grid` data-grid header (transparent, UPPERCASE, 600) is the standard chrome.",
|
|
236
|
+
"dontUse": "Don't use a grid for a handful of static key/values — use a definition list / cards instead. If rows need multi-select bulk operations use `selectable`; if each row has drill-down detail use `expandable`; if rows must be grouped with counts use `grouping`; if the dataset is large/server-driven use `pagination` with server paging.",
|
|
237
|
+
"example": "Settings list views and inventory monitor lists rendered via FlotoPaginatedCrud; drill-down sub-tables and preview grids rendered via MGrid :data :columns."
|
|
238
|
+
},
|
|
239
|
+
"grouping": {
|
|
240
|
+
"useWhen": "Rows should be bucketed under group headers with per-group counts. Drive it with `default-group` (the grouping column(s)); the grid renders grouped rows with counts. Hide the grouping UI with `.hide-grouping` when needed.",
|
|
241
|
+
"dontUse": "Don't use grouping to show nested record hierarchy — that's the `tree` variant. Don't use it for cross-tab metric summaries with a merged spanning group-header — that's the `pivot` variant. For a flat sorted list, plain `basic` is enough.",
|
|
242
|
+
"example": "Alert / event lists grouped by a column (e.g. by severity or source) with a count badge per group."
|
|
243
|
+
},
|
|
244
|
+
"cell-types": {
|
|
245
|
+
"useWhen": "Columns need rich, non-plain-text rendering. Each column renders through a named slot (`status`, `name`, `tags`, `severity`, `value`, `duration`, `action`, `monitorType`, `timestamp`, `count`, …), so a cell can be a status tag, a severity dot, tags, a sparkline, a color-coded threshold cell (`color-coded-cell.vue`, heatmap-style / `relative-percent` inline bar), or a row-actions kebab (`FlotoGridActions`).",
|
|
246
|
+
"dontUse": "Don't reach for custom cell slots when a column is plain sortable text — leave it as `basic`. Don't put a bulk multi-select checkbox here (that's `selectable`) or the row expander (that's `expandable`); those are dedicated props/columns, not cell slots.",
|
|
247
|
+
"example": "Monitor grid cells: a status tag (MStatusTag), a severity dot, tags, a value sparkline, and a trailing kebab cell (FlotoGridActions) for per-row actions."
|
|
248
|
+
},
|
|
249
|
+
"pagination": {
|
|
250
|
+
"useWhen": "The dataset spans multiple pages. Use client paging (`paging` + `default-page-size`) for in-memory lists; use server paging (`external-take` / `external-skip` + `total-count` + `@data-state-change`) to fetch only the visible page for large/server-driven datasets. FlotoPaginatedCrud wires this up for fetched list pages.",
|
|
251
|
+
"dontUse": "Don't client-load huge datasets — server-page them. Don't hand-roll paging controls; MGrid / FlotoPaginatedCrud own paging, sort, and filter. For live socket/widget-pushed feeds use the streaming grid (`api-socket-grid`, no paging) rather than paginating.",
|
|
252
|
+
"example": "Large inventory / settings list pages server-paged through FlotoPaginatedCrud, fetching only the current page from the API."
|
|
253
|
+
},
|
|
254
|
+
"tree": {
|
|
255
|
+
"useWhen": "Data is genuinely hierarchical — parent rows with nested child rows across levels. Use the `tabular-content-grid` tree (`expandable` with a `detailRow` of nested child rows, chevron + indentation per level).",
|
|
256
|
+
"dontUse": "Don't use `tree` for a single row's flat detail panel — plain `expandable` is enough. Don't use it for flat grouped buckets (`grouping`) or cross-tab metric summaries (`pivot`).",
|
|
257
|
+
"example": "SNMP OID / MIB trees — expand a parent OID to reveal indented child OID rows level by level."
|
|
258
|
+
},
|
|
259
|
+
"pivot": {
|
|
260
|
+
"useWhen": "You need a report/pivot grid where metrics are grouped under a merged group-header row (`report-pivot-group-header`, ~1rem) that spans the metric columns — the transposed/cross-tab report layout.",
|
|
261
|
+
"dontUse": "Don't use `pivot` for ordinary grouped list rows with counts — that's `grouping`. Don't use it for a single-record transposed key/value view (`column-grid-view` / `overview-layout`) or for plain paginated lists (`basic` / `pagination`).",
|
|
262
|
+
"example": "Report widgets that summarize metrics across dimensions with a merged group-header spanning the metric columns."
|
|
233
263
|
}
|
|
234
264
|
},
|
|
235
265
|
"do": [
|
|
@@ -212,6 +212,31 @@
|
|
|
212
212
|
"useWhen": "the user should resume their last tab",
|
|
213
213
|
"how": "<MPersistedTab module-key> + :value/@change",
|
|
214
214
|
"example": "module-level tab sets"
|
|
215
|
+
},
|
|
216
|
+
"line": {
|
|
217
|
+
"useWhen": "The default and only base tab style in the product: switching between sibling VIEWS of one context (Overview / Performance / Logs) with a line/top/default a-tabs. Use for every basic tab set unless a class-based variant applies on top.",
|
|
218
|
+
"dontUse": "Don't use tabs to navigate to separate pages (use the router/menu). For a compact 2-4-way toggle inline in a form use MRadioGroup as-button; for pick-from-many field options use FlotoDropdownPicker. Never reach for Ant card/editable-card/vertical/size tabs — the product is line/top/default only.",
|
|
219
|
+
"example": "An entity detail page switching between Overview / Performance / Logs sibling views with <MTab v-model><MTabPane key tab>."
|
|
220
|
+
},
|
|
221
|
+
"no-border": {
|
|
222
|
+
"useWhen": "The dominant class variant (21x): the tab bar sits on a card/panel that already has its own edges, so the tabs' own --border-color bottom rule would double up. Add class=\"no-border\" to drop that bottom border.",
|
|
223
|
+
"dontUse": "Don't use when the tabs are the top-level divider of a bare page region that needs the bottom rule to separate bar from content — keep the default line border. Not a substitute for sticky-tab (scrolling) or a way to remove the active ink bar.",
|
|
224
|
+
"example": "Detail-panel tabs inside a card, e.g. a device/monitor detail panel where the card frame already provides the edge."
|
|
225
|
+
},
|
|
226
|
+
"sticky-tab": {
|
|
227
|
+
"useWhen": "The tabs head a long scrolling content area (8x) and must stay visible as the pane scrolls. Add class=\"sticky-tab\" to pin the tab bar to the top of the scroll region.",
|
|
228
|
+
"dontUse": "Don't add it to short panes that don't scroll — it's pure overhead. It doesn't remove borders (compose with no-border if the pane is also a card) and isn't for page-level navigation.",
|
|
229
|
+
"example": "A settings or entity detail pane that scrolls, where Overview/Performance/Logs tabs stay pinned while the long content scrolls beneath."
|
|
230
|
+
},
|
|
231
|
+
"with-counts": {
|
|
232
|
+
"useWhen": "A tab label needs to summarize a live count of the items in its pane. Append the number to the label STRING as `Label (N)` (e.g. :tab=`Alerts (${count})`), not a separate badge component. Keep labels short noun + count.",
|
|
233
|
+
"dontUse": "Don't build a separate count badge component or sentence-case/punctuate the label — the product convention is the '(N)' suffix appended to the string. Don't use for static labels that never carry a count.",
|
|
234
|
+
"example": "Correlated alert detail tabs: Alerts (12) / Logs (5) / Metrics — count appended to each tab label string."
|
|
235
|
+
},
|
|
236
|
+
"with-icons": {
|
|
237
|
+
"useWhen": "A tab needs a leading icon for a view switcher: use the tab SLOT with a product MIcon plus text (<span slot=\"tab\"><MIcon/> Label>). For icon-only tabs use the topology-hierarchy-tab pattern.",
|
|
238
|
+
"dontUse": "Don't hand-draw an SVG — use a real product icon (MIcon from the product library). Don't use icon-only tabs without an accessible name (a11y). Skip icons entirely for plain short noun labels where text alone is clear.",
|
|
239
|
+
"example": "A topology/hierarchy view switcher whose tabs carry a leading MIcon, and icon-only switching via the topology-hierarchy-tab class."
|
|
215
240
|
}
|
|
216
241
|
},
|
|
217
242
|
"do": [
|
|
@@ -182,6 +182,51 @@
|
|
|
182
182
|
},
|
|
183
183
|
"rounded": {
|
|
184
184
|
"useWhen": "a fully-rounded pill look (cosmetic)"
|
|
185
|
+
},
|
|
186
|
+
"tag-red": {
|
|
187
|
+
"useWhen": "Color-coding a negative/critical category label with a red tint — the most common colored tag (75×). Applied as a class (MTag class=\"tag-red\"), legible in both themes.",
|
|
188
|
+
"dontUse": "Don't use the color `variant` prop (variant=\"error\" is broken/illegible — F2). If the chip is driven by a status STRING (error/down/failed/critical/stopped/offline), use MStatusTag instead — its TAG_MAP resolves those to tag-red automatically.",
|
|
189
|
+
"example": "A red-tinted 'Failed' job-run label or a 'Critical'/'Down' state chip in an inventory or alert grid."
|
|
190
|
+
},
|
|
191
|
+
"tag-green": {
|
|
192
|
+
"useWhen": "Color-coding a positive/success category with a green tint (57×). Apply as MTag class=\"tag-green\".",
|
|
193
|
+
"dontUse": "Don't use variant=\"success\" (broken — F2). For a status STRING (up/success/active/enabled/completed/online), let MStatusTag map it to tag-green instead of hand-applying the class.",
|
|
194
|
+
"example": "A green 'Up'/'Enabled'/'Succeeded' chip in a monitor or job status grid."
|
|
195
|
+
},
|
|
196
|
+
"tag-yellow": {
|
|
197
|
+
"useWhen": "Color-coding a warning or transitional state with a yellow tint (15×). Apply as MTag class=\"tag-yellow\".",
|
|
198
|
+
"dontUse": "Don't use variant=\"warning\" (broken — F2). Note MStatusTag's TAG_MAP maps halted/paused/queued/aborted/starting to tag-yellow, but it lacks true severity 'warning' — for severity LEVELS use the Severity component, not this class.",
|
|
199
|
+
"example": "A yellow 'Paused'/'Queued'/'Halted' job-run state chip."
|
|
200
|
+
},
|
|
201
|
+
"tag-orange": {
|
|
202
|
+
"useWhen": "Color-coding a caution/intermediate state with an orange tint (9×). Apply as MTag class=\"tag-orange\".",
|
|
203
|
+
"dontUse": "Don't use variant=\"orange\" (broken — F2). Prefer tag-yellow for transient/queued states and tag-red for hard failures; orange is for the in-between (suspended/fair).",
|
|
204
|
+
"example": "An orange 'Suspended' monitor state or a 'Fair' quality-rating chip."
|
|
205
|
+
},
|
|
206
|
+
"tag-purple": {
|
|
207
|
+
"useWhen": "A rarely-used purple tint reserved for the 'unreachable' condition (1× — maps from --severity-unreachable). Apply as MTag class=\"tag-purple\".",
|
|
208
|
+
"dontUse": "Don't reach for purple as a generic color — it carries the 'unreachable' meaning. Use tag-red/tag-green/tag-yellow for ordinary category coding, and the Severity component for severity levels.",
|
|
209
|
+
"example": "A purple 'Unreachable' chip for a monitor that cannot be contacted (statusMap: unreachable → tag-purple)."
|
|
210
|
+
},
|
|
211
|
+
"tag-unknown": {
|
|
212
|
+
"useWhen": "A neutral 'unknown' tint (2×) for indeterminate state — text is --severity-unknown on a light tint. Apply as MTag class=\"tag-unknown\".",
|
|
213
|
+
"dontUse": "Don't use for a plain neutral metadata label — that's tag-primary. Reserve tag-unknown for genuinely unknown/indeterminate status.",
|
|
214
|
+
"example": "An 'Unknown' status chip where a monitor's state can't be determined (statusMap: unknown → tag-unknown)."
|
|
215
|
+
},
|
|
216
|
+
"tag-primary": {
|
|
217
|
+
"useWhen": "A neutral chip (NOT blue) — the default gray tag on --tag-bg-color, for read-only category/metadata labels and neutral states (49×). Apply as MTag class=\"tag-primary\" (or forcePrimary on MStatusTag).",
|
|
218
|
+
"dontUse": "Don't use it for a semantic status — pick tag-red/green/yellow (or MStatusTag) so the color carries meaning. Don't confuse it with a blue/brand chip; it renders neutral gray.",
|
|
219
|
+
"example": "A neutral device-category or environment metadata chip, or a 'Maintenance'/'Connected'/'Standby' state (statusMap maps those to tag-primary)."
|
|
220
|
+
},
|
|
221
|
+
"MStatusTag": {
|
|
222
|
+
"useWhen": "The chip is driven by a status STRING (up/down/critical/paused/success/failed…) — MStatusTag looks the value up in TAG_MAP and renders the right tag-* color + capitalized label automatically. Always rounded and non-closable.",
|
|
223
|
+
"dontUse": "For true severity LEVELS (critical/major/warning/clear) use the Severity component — TAG_MAP lacks major/warning/clear and silently falls through to a plain gray tag (F7). For a static hand-picked color label, apply a tag-* class directly rather than routing through a status string. Beware F7: poweredoff→'Up', poweredon→'Down' (intentional inversion), and unmapped statuses render a silent plain tag.",
|
|
224
|
+
"example": "A monitor's Up/Down state in the monitor status sidebar and instance grids: <MStatusTag :status=\"row.status\" />."
|
|
225
|
+
},
|
|
226
|
+
"used-count-pill": {
|
|
227
|
+
"useWhen": "A rounded neutral COUNT chip — primary-text on a tint, always :rounded (48×) — for showing how many times something is used/referenced.",
|
|
228
|
+
"dontUse": "Don't use it to convey status or severity (use MStatusTag or a tag-* color class). It's a neutral count pill, not a semantic color, and it's distinct from the tag-* color classes.",
|
|
229
|
+
"example": "A '3 used' count pill next to a template/credential in a usage list."
|
|
185
230
|
}
|
|
186
231
|
},
|
|
187
232
|
"insteadOf": [
|
|
@@ -236,5 +236,37 @@
|
|
|
236
236
|
],
|
|
237
237
|
"doc": "Organisms/Toolbars/Accessibility",
|
|
238
238
|
"$note": "Catalogue-wide gap SF-001 = no visible :focus-visible ring; tracked in findings/."
|
|
239
|
+
},
|
|
240
|
+
"usageRules": {
|
|
241
|
+
"app-header": {
|
|
242
|
+
"useWhen": "You need the global top bar that appears on every authenticated screen — the layout-level chrome carrying the logo (home link), global omnibox search, permission-gated health-monitoring/NCM-approval icons, the notification dropdown, the BUILD:<version> tag, and the user menu. It comes from the layout (header.vue), not per-page.",
|
|
243
|
+
"dontUse": "Don't hand-build or duplicate it inside a page — it's a layout composition, not a propful component. For a specific list/detail page's title + actions use the Page header; for a dashboard widget's chrome use the Widget header.",
|
|
244
|
+
"example": "The persistent ObserveOps top bar with the Motadata logo, the omnibox global search button, notification bell, BUILD version tag, and the user avatar dropdown — rendered once by src/components/layout/header.vue across the whole app."
|
|
245
|
+
},
|
|
246
|
+
"page-header": {
|
|
247
|
+
"useWhen": "At the top of any list or detail page that needs a back link + title + right-side action buttons (FlotoPageHeader). Use it for every list/detail page (54× in product); use mainHeader for the main title-panel style vs an inner panel, and the slots (title-append for counts, additional-rows) for context rows.",
|
|
248
|
+
"dontUse": "Don't use it for a dashboard widget's title strip (use Widget header) or for controls sitting directly above a data grid like search/filter/columns/Add (use Grid toolbar). Don't create a bespoke per-screen header component.",
|
|
249
|
+
"example": "A resource-detail or list page top bar: a back button returning to the list, the page title with a count appended below it, and right-aligned primary actions like an Add/Create button — e.g. the Monitors or Alerts list page header."
|
|
250
|
+
},
|
|
251
|
+
"widget-header": {
|
|
252
|
+
"useWhen": "For a dashboard widget's chrome (widget-title.vue): the widget title + a time-range pill + the kebab of widget actions (edit/clone/remove/share/fullscreen/CSV-export) plus metric-analysis. Use it inside dashboard widgets (58× in product); tune with excludedActions/additionalActions, hideTimeline, backgroundColor to tint the time pill.",
|
|
253
|
+
"dontUse": "Don't use it as a page-level header (use Page header) or for bulk row operations (use Bulk action bar). The kebab itself is the FlotoGridActions action-menu archetype catalogued under Popover — don't re-implement it.",
|
|
254
|
+
"example": "The title strip of a dashboard chart widget: the widget name on the left, a time-range pill (e.g. 'Last 24 Hours') and a ⋮ kebab exposing Edit / Clone / Remove / Fullscreen / Export CSV on the right."
|
|
255
|
+
},
|
|
256
|
+
"bulk-action-bar": {
|
|
257
|
+
"useWhen": "When the user has selected N rows in a grid and you need a floating toolbar (role=toolbar) showing the selected count, a Clear control, and inline primary actions plus a 'More' overflow menu (_base-bulk-action-bar). It appears once selectedCount ≥ minSelection (default 2). Put destructive bulk actions in --secondary-red, separated by the __danger-zone divider.",
|
|
258
|
+
"dontUse": "Don't use it for single-row row actions (that's the FlotoGridActions kebab) or for the always-visible grid controls like search/filter/columns/Add (use Grid toolbar). Don't scatter bulk actions without the danger-zone separation for destructive ones.",
|
|
259
|
+
"example": "Selecting multiple monitors in a grid surfaces a floating bar reading 'N selected' with a Clear (×), inline actions like Enable/Disable, and a 'More' overflow — with Delete rendered as a red danger action below a divider (e.g. the rediscover bulk-provision toolbar variant)."
|
|
260
|
+
},
|
|
261
|
+
"grid-toolbar": {
|
|
262
|
+
"useWhen": "For the always-visible control strip directly above a data grid: search (MInput), a filter button, the Column chooser, and an Add/Create action. It's a composition (default-grid.vue), assembled from the named parts — compose the Molecules/Filters component for filtering rather than re-implementing it.",
|
|
263
|
+
"dontUse": "Don't build it as a single propful wrapper — assemble MInput + filter MButton + ColumnSelector + WidgetGridFilters. Don't duplicate a filter inside it (compose Filters). For selection-driven operations use the Bulk action bar; for page title/actions use the Page header.",
|
|
264
|
+
"example": "The controls above a list grid: a search box, a Filter button opening the quick-filter/filter-bar molecule, the eye-icon column chooser, and an 'Add' button — e.g. above the Monitors or Alerts VirtualTable grid."
|
|
265
|
+
},
|
|
266
|
+
"column-chooser": {
|
|
267
|
+
"useWhen": "To let users show/hide grid columns via the eye-button dropdown (column-selector.vue, a FlotoDropdownPicker multi-select) — the most-used toolbar piece (174×). Use maxAllowedSelection to cap selections, hideResetOption to hide 'Reset Column Preference', and the trigger slot to replace the eye button; persist via MPersistedColumns.",
|
|
268
|
+
"dontUse": "Don't rely on it to reorder columns — reordering is grid-header drag, not the chooser. It only toggles visibility. Don't use it for the broader grid controls (search/filter/Add) — that's the Grid toolbar it lives inside.",
|
|
269
|
+
"example": "The eye-icon button above a grid opening a checklist of available columns so the user can hide/show fields; selections persist to localStorage per widget id via MPersistedColumns (e.g. customizing the Alerts grid columns)."
|
|
270
|
+
}
|
|
239
271
|
}
|
|
240
272
|
}
|
|
@@ -125,6 +125,21 @@
|
|
|
125
125
|
"useWhen": "a chart/series hover",
|
|
126
126
|
"how": "overlay-class-name='chart-like-tooltip'",
|
|
127
127
|
"example": "metric chart point"
|
|
128
|
+
},
|
|
129
|
+
"default": {
|
|
130
|
+
"useWhen": "You need the standard dark hover/focus bubble for a short, non-interactive hint — most commonly the info-circle idiom: an info-circle MIcon in the trigger slot with explanatory text in the default slot. This is the 94x workhorse (73x use the top-start default placement). Also covers the rich hover card: a small non-interactive title + a few key/values in the default slot.",
|
|
131
|
+
"dontUse": "Don't use for content with buttons/links/inputs (it dismisses on mouse-out — use Popover instead). Don't use for the full text of a plain/truncated cell or label (use the native title='' attribute, ~59x, cheaper with no component). Switch to chart-like-tooltip when the hint must match a chart/graph surface (light bubble). Not for topology/graph edge or node tooltips (domain-specific graph components).",
|
|
132
|
+
"example": "The 'Polling interval ⓘ' field hint on settings/monitor forms — info-circle trigger revealing 'How often the monitor is polled.' Also the topology/host hover card (title + a few key/values, placement=right) shown in the Rich content story."
|
|
133
|
+
},
|
|
134
|
+
"chart-like-tooltip": {
|
|
135
|
+
"useWhen": "The tooltip should visually match a chart/graph surface — a LIGHT bubble (--chart-tooltip-background + page text) instead of the default dark one. Apply overlay-class-name='chart-like-tooltip'. Used for series/point hovers and info-tooltips that live on a chart canvas.",
|
|
136
|
+
"dontUse": "Don't use for ordinary UI field hints — the default dark bubble is correct there. Don't use for actual chart data-series hover cards rendered by the Highcharts chart layer (those are the chart TooltipBuilder / sparkline / heatmap tooltips, owned by the chart component, not MTooltip). Only 2x in the product, so reach for it deliberately.",
|
|
137
|
+
"example": "The traceroute Timeout info-tooltip (via tooltip-props with overlay-class-name='chart-like-tooltip'), giving a light chart-surface bubble on the traceroute chart."
|
|
138
|
+
},
|
|
139
|
+
"placements": {
|
|
140
|
+
"useWhen": "You need to steer where the bubble opens relative to the trigger via the `placement` prop (VTippy names: top-start default, top, top-end, bottom, bottom-start, left, right, plus -start/-end). Set it when layout constraints require the bubble to avoid clipping or overlapping neighbours — e.g. right for a rich card next to a node, left/bottom near panel edges.",
|
|
141
|
+
"dontUse": "Don't change placement just for style — top-start dominates (73x) and should stay the default unless the layout forces it. Don't use Ant placement names here (bottomLeft) — those belong to MPopover and are NOT interchangeable with VTippy names. Rare placements (bottomRight/topLeft/right) are 1-2x, so only override when genuinely needed.",
|
|
142
|
+
"example": "The Rich content host hover-card in topology uses placement='right' so the card opens beside the node; the Placements story stacks top-start/top/left/right/bottom/bottomRight/topLeft to show directional layout."
|
|
128
143
|
}
|
|
129
144
|
},
|
|
130
145
|
"do": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mtdt/observeops-ds-spec",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Machine-readable spec and AI operating contract for the Motadata ObserveOps design system \u2014 components, tokens, page recipes, layout structure, and the rules an AI tool follows to build ObserveOps UI faithfully.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"main": "index.js",
|