@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
package/AGENTS.md
CHANGED
|
@@ -24,7 +24,9 @@ system — never guessed.
|
|
|
24
24
|
## Hard rules (MUST)
|
|
25
25
|
|
|
26
26
|
1. **Components:** use only catalogued components (`index.json`). Pick with `selectHint` /
|
|
27
|
-
`decisionFlow`. Do not invent a component or pull one from another library.
|
|
27
|
+
`decisionFlow`. Do not invent a component or pull one from another library. **Build with the REAL
|
|
28
|
+
components** — the framework-agnostic Web Components `@mtdt/observeops-ds-elements` (`<obs-button
|
|
29
|
+
variant="primary">`, works in React/Vue/HTML); reconstructing from CSS classes is a fallback only.
|
|
28
30
|
2. **Configuration:** configure only with the documented `props` / `events` / `slots` / `apis` in the
|
|
29
31
|
registry. Do not invent prop names.
|
|
30
32
|
3. **Colour & spacing:** resolve every colour/space from tokens — `variables.json` /
|
|
@@ -272,6 +272,16 @@
|
|
|
272
272
|
"link(FlotoLink)": {
|
|
273
273
|
"useWhen": "the control navigates (route/URL/anchor)",
|
|
274
274
|
"dontUse": "for actions that change data/state (use a button)"
|
|
275
|
+
},
|
|
276
|
+
"danger": {
|
|
277
|
+
"useWhen": "Avoid in new work — it is a rare (3×) light/ghost style, NOT solid red (finding F2). For anything destructive prefer error + a confirm.",
|
|
278
|
+
"dontUse": "For real destructive actions (use error) or for a normal save (use primary); the ghost rendering under-signals danger.",
|
|
279
|
+
"example": "Legacy light ghost-danger action; migrate to error for delete/remove flows."
|
|
280
|
+
},
|
|
281
|
+
"icon-circle": {
|
|
282
|
+
"useWhen": "An icon-only action where a circular/standalone/floating affordance is wanted — overlay and floating controls (topology/chart overlays). Must provide an aria-label.",
|
|
283
|
+
"dontUse": "For a repeated in-table/toolbar icon action (use squared-button) or when the icon's meaning isn't obvious (use a labelled button). Note: renders as a 4px rounded square unless you add :rounded=false (finding F7).",
|
|
284
|
+
"example": "Topology / chart overlay controls (button-topology-overlay); floating map controls."
|
|
275
285
|
}
|
|
276
286
|
},
|
|
277
287
|
"insteadOf": [
|
|
@@ -421,5 +421,147 @@
|
|
|
421
421
|
"changelog": [
|
|
422
422
|
"2026-06-29: added to the Elements site — obs-dataviz-tooltip: all 28 chart/widget + live-graph tooltip reference reproductions (kind prop), real tokens (--chart-tooltip-background, --topology-graph-tooltip-bg, --severity-*).",
|
|
423
423
|
"2026-06-30: added a `block` prop (Full width) — the card stretches to its container instead of its intrinsic per-kind width; exposed as a Playground toggle + a Full-width Examples group, and documented kind/block in Details."
|
|
424
|
-
]
|
|
425
|
-
|
|
424
|
+
],
|
|
425
|
+
"usageRules": {
|
|
426
|
+
"bar-series": {
|
|
427
|
+
"useWhen": "Hovering a mark on a bar/line/area/column chart rendered by the Highcharts TooltipBuilder — metric-trend, top-N, time-series widgets, KPI-trend, or areasplinerange. Shows a title (category/date-time) plus one row per series (8x8 color square, series name, right-aligned unit-applied value); multi-series charts with sharedTooltip show every series at the hovered x with a crosshair.",
|
|
428
|
+
"dontUse": "When the mark is a slice (use donut-pie), a low-high band (use anomaly-band), or when you need a UI hint on a control rather than a chart mark (use MTooltip). Don't hand-build; content lives in tooltip-builder.js.",
|
|
429
|
+
"example": "Hovering a column in a metric-trend or Top-N time-series widget on an ObserveOps dashboard to read the per-series value at that timestamp."
|
|
430
|
+
},
|
|
431
|
+
"donut-pie": {
|
|
432
|
+
"useWhen": "Hovering a slice of an availability/status donut widget or a distribution pie. Highcharts renders it on the hc-tooltip-bg surface; pie omits the header row that bar/line keep.",
|
|
433
|
+
"dontUse": "For time-series or category columns use bar-series; for hex status grids use heatmap. Not for UI control hints (MTooltip).",
|
|
434
|
+
"example": "Hovering a segment of a monitor-availability status donut or a severity-distribution pie widget on a dashboard."
|
|
435
|
+
},
|
|
436
|
+
"bubble": {
|
|
437
|
+
"useWhen": "Hovering a bubble in a packed-bubble widget (category/tag distribution), rendered by bubble-options.vue on hc-tooltip-bg.",
|
|
438
|
+
"dontUse": "For x/y correlation points use scatter; for hierarchical area use treemap. Not a UI tooltip.",
|
|
439
|
+
"example": "Hovering a bubble in a category- or tag-distribution packed-bubble widget to read its grouped count."
|
|
440
|
+
},
|
|
441
|
+
"map-geo": {
|
|
442
|
+
"useWhen": "Hovering a region on a geo-map widget that plots monitor distribution by location (map-chart-options.vue, hc-tooltip-bg).",
|
|
443
|
+
"dontUse": "For RUM apdex/demographics country markers use geo-marker; for topology nodes use live-graph-node. Not for UI hints.",
|
|
444
|
+
"example": "Hovering a country/region on a monitor-distribution-by-location geo map widget."
|
|
445
|
+
},
|
|
446
|
+
"radar": {
|
|
447
|
+
"useWhen": "Hovering a point on a multi-axis radar comparison widget (radar-chart-options.vue, hc-tooltip-bg).",
|
|
448
|
+
"dontUse": "For single-axis trends use bar-series; for two-variable correlation use scatter.",
|
|
449
|
+
"example": "Hovering an axis vertex on a multi-metric radar comparison widget to read that axis's value."
|
|
450
|
+
},
|
|
451
|
+
"timeline-xrange": {
|
|
452
|
+
"useWhen": "Hovering a segment on an SLO timeline or availability timeline (x-range) rendered by timeline-chart-options.vue on hc-tooltip-bg.",
|
|
453
|
+
"dontUse": "For the colored alert/availability bar segment use availability-segment; for RUM resource timing use rum-waterfall. Not for UI hints.",
|
|
454
|
+
"example": "Hovering a state band on an SLO / availability timeline widget to read its window."
|
|
455
|
+
},
|
|
456
|
+
"gauge": {
|
|
457
|
+
"useWhen": "Hovering a solid-gauge, circular-progress, or KPI gauge widget (gauge.vue / circular-progress-options.vue, hc-tooltip-bg).",
|
|
458
|
+
"dontUse": "For a linear trend use bar-series; for an inline mini-trend use sparkline.",
|
|
459
|
+
"example": "Hovering the arc of a KPI solid-gauge or circular-progress widget to read the current value."
|
|
460
|
+
},
|
|
461
|
+
"sankey": {
|
|
462
|
+
"useWhen": "Hovering a node or link on a sankey/flow widget (traffic flow, dependency) rendered by sankey-options.vue on hc-tooltip-bg.",
|
|
463
|
+
"dontUse": "For topology link details use live-graph-edge or network-interface-edge; for hierarchy area use treemap.",
|
|
464
|
+
"example": "Hovering a flow band on a traffic-flow or dependency sankey widget."
|
|
465
|
+
},
|
|
466
|
+
"treemap": {
|
|
467
|
+
"useWhen": "Hovering a tile on a treemap widget (capacity/hierarchy) rendered by tree-map-with-levels.vue on hc-tooltip-bg.",
|
|
468
|
+
"dontUse": "For packed-bubble distribution use bubble; for a flow diagram use sankey.",
|
|
469
|
+
"example": "Hovering a rectangle in a capacity/hierarchy treemap widget to read its share."
|
|
470
|
+
},
|
|
471
|
+
"scatter": {
|
|
472
|
+
"useWhen": "Hovering a point on a scatter widget plotting x vs y per monitor (type:'scatter', hc-tooltip-bg).",
|
|
473
|
+
"dontUse": "For category distribution use bubble; for multi-axis comparison use radar.",
|
|
474
|
+
"example": "Hovering a point in an x-vs-y correlation scatter widget to read both coordinates for that monitor."
|
|
475
|
+
},
|
|
476
|
+
"anomaly-band": {
|
|
477
|
+
"useWhen": "Hovering an anomaly or forecast chart where each point is an actual value vs an expected low-high band (areasplinerange + isAnomalySeries; __getLowHighHtml). Used in anomaly/forecast widgets, metric-explorer, metric-insight; out-of-range points are colored.",
|
|
478
|
+
"dontUse": "For a plain single-value trend use bar-series (default value format). Anomaly-band is specifically the low-high range value cell.",
|
|
479
|
+
"example": "Hovering a metric-explorer anomaly chart to compare the actual value against the expected low-high band at that time."
|
|
480
|
+
},
|
|
481
|
+
"rum-waterfall": {
|
|
482
|
+
"useWhen": "Hovering a resource bar on a RUM session resource-timing waterfall (rum-resource-waterfall.vue, x-range, hc-tooltip-bg) to read start/end/duration.",
|
|
483
|
+
"dontUse": "For an APM/RUM trace flame graph span use flame-graph-span; for an SLO timeline use timeline-xrange.",
|
|
484
|
+
"example": "Hovering a resource row in a RUM page resource-timing waterfall to read its start, end, and duration."
|
|
485
|
+
},
|
|
486
|
+
"geo-marker": {
|
|
487
|
+
"useWhen": "Hovering a country/marker on a RUM apdex-or-demographics-by-country map or a Leaflet online map (apdex-rating-by-country-map.vue / leaflet-map.vue) to read region + severity + metrics.",
|
|
488
|
+
"dontUse": "For a monitor-distribution geo widget use map-geo; for topology nodes use live-graph-node.",
|
|
489
|
+
"example": "Hovering a country on the RUM apdex-by-country map to read its region, apdex severity, and metrics."
|
|
490
|
+
},
|
|
491
|
+
"log-pattern": {
|
|
492
|
+
"useWhen": "Hovering a log pattern count in the log pattern detection grid (log-pattern-detection-grid.vue) — shows a nested VALUE/COUNT/SHARE grid (popover + MGrid, hc-tooltip-bg).",
|
|
493
|
+
"dontUse": "For a generic chart series row use bar-series. This is the specific log distribution popover.",
|
|
494
|
+
"example": "Hovering a pattern's count in the Log pattern detection grid to see its value distribution (VALUE/COUNT/SHARE)."
|
|
495
|
+
},
|
|
496
|
+
"sparkline": {
|
|
497
|
+
"useWhen": "Hovering an inline sparkline cell in a grid or metric widget (sparkline-options.vue, hc-tooltip-bg mini) to read the point value on the mini-trend.",
|
|
498
|
+
"dontUse": "For a full-size trend chart use bar-series; for a gauge use gauge.",
|
|
499
|
+
"example": "Hovering an inline sparkline cell in a grid row or KPI widget to read the value at that point."
|
|
500
|
+
},
|
|
501
|
+
"heatmap": {
|
|
502
|
+
"useWhen": "Hovering a cell of a hex heatmap widget — monitor status grid, or SLO/APM/RUM heatmaps (heatmap-tooltip.vue). Surface is --chart-tooltip-background with a severity badge; convey severity by badge + label, not color alone.",
|
|
503
|
+
"dontUse": "For a segmented availability timeline bar use availability-segment; for a donut use donut-pie.",
|
|
504
|
+
"example": "Hovering a hex cell in the monitor-status heatmap widget to read the monitor and its severity badge."
|
|
505
|
+
},
|
|
506
|
+
"availability-segment": {
|
|
507
|
+
"useWhen": "Hovering a segment of an alert/availability timeline bar (segmented-cell-tooltip.vue) — shows start/end/duration + severity on --chart-tooltip-background with a severity badge.",
|
|
508
|
+
"dontUse": "For the stacked up/down percentage bar use availability-bar; for an SLO x-range timeline use timeline-xrange.",
|
|
509
|
+
"example": "Hovering a colored segment on an alert/availability timeline bar to read its start, end, duration, and severity."
|
|
510
|
+
},
|
|
511
|
+
"availability-bar": {
|
|
512
|
+
"useWhen": "Hovering a segment of a stacked up/down percentage bar (availability-bar.vue via MTooltip) — shows 'Status: %' on --tooltip-background-color.",
|
|
513
|
+
"dontUse": "For a segmented alert timeline with start/end/duration use availability-segment; for a status donut use donut-pie.",
|
|
514
|
+
"example": "Hovering the up or down portion of a stacked availability % bar to read 'Up: 99.2%'."
|
|
515
|
+
},
|
|
516
|
+
"live-graph-node": {
|
|
517
|
+
"useWhen": "Hovering a monitor node on a Topology map or Netroute path (topology/netroute node components) — canvas tooltip on --topology-graph-tooltip-bg (fixed-dark in both themes).",
|
|
518
|
+
"dontUse": "For a link/edge use live-graph-edge or network-interface-edge; for an APM service node use apm-service-node; for a netroute hop use netroute-node.",
|
|
519
|
+
"example": "Hovering a device node on the Topology map to read the monitor's summary."
|
|
520
|
+
},
|
|
521
|
+
"live-graph-edge": {
|
|
522
|
+
"useWhen": "Hovering a generic topology/netroute link (edge-tooltip.vue) — shows interface in/out and utilization on --topology-graph-tooltip-bg.",
|
|
523
|
+
"dontUse": "When the edge is a full network interface link (use network-interface-edge), an SD-WAN tunnel (sdn-tunnel-edge), an ACI link (cisco-aci-link), or a netroute transit edge (netroute-edge).",
|
|
524
|
+
"example": "Hovering a link on the topology map to read its in/out interface utilization."
|
|
525
|
+
},
|
|
526
|
+
"apm-service-node": {
|
|
527
|
+
"useWhen": "Hovering a node on the APM service map (servicemap-tooltip.vue) — throughput/latency/error on --topology-graph-tooltip-bg.",
|
|
528
|
+
"dontUse": "For a generic topology monitor node use live-graph-node; for a flame graph span use flame-graph-span.",
|
|
529
|
+
"example": "Hovering a service node on the APM service map to read its throughput, latency, and error rate."
|
|
530
|
+
},
|
|
531
|
+
"sdn-tunnel-edge": {
|
|
532
|
+
"useWhen": "Hovering an SD-WAN tunnel edge (sdn-tunnel-edge-tooltip.vue) — latency/loss/jitter KPIs plus health/color/site on --topology-graph-tooltip-bg.",
|
|
533
|
+
"dontUse": "For a plain interface edge use network-interface-edge; for an ACI fabric link use cisco-aci-link.",
|
|
534
|
+
"example": "Hovering an SD-WAN tunnel on the SDN topology to read its latency, loss, jitter, and health."
|
|
535
|
+
},
|
|
536
|
+
"cisco-aci-endpoint": {
|
|
537
|
+
"useWhen": "Hovering a Cisco ACI leaf-to-endpoint edge (cisco-aci-edge-tooltip.vue) — MAC/IPv4/IPv6/endpoint-group on --topology-graph-tooltip-bg.",
|
|
538
|
+
"dontUse": "For an ACI leaf-to-leaf fabric link use cisco-aci-link; for a generic interface edge use network-interface-edge.",
|
|
539
|
+
"example": "Hovering a leaf-to-endpoint connection on a Cisco ACI map to read the endpoint's MAC, IPv4/IPv6, and group."
|
|
540
|
+
},
|
|
541
|
+
"cisco-aci-link": {
|
|
542
|
+
"useWhen": "Hovering a Cisco ACI leaf-to-leaf fabric link (cisco-aci-link-edge-tooltip.vue) — node/pod/role/state/interface on --topology-graph-tooltip-bg.",
|
|
543
|
+
"dontUse": "For a leaf-to-endpoint edge use cisco-aci-endpoint; for a non-ACI interface link use network-interface-edge.",
|
|
544
|
+
"example": "Hovering a fabric link between two ACI leaves to read node, pod, role, state, and interface."
|
|
545
|
+
},
|
|
546
|
+
"network-interface-edge": {
|
|
547
|
+
"useWhen": "Hovering a network link on a topology map (network-interface-edge-tooltip.vue) — both-sides interface details: alias/status/IP/speed/traffic on --topology-graph-tooltip-bg.",
|
|
548
|
+
"dontUse": "For a generic edge with just in/out utilization use live-graph-edge; for SD-WAN tunnels use sdn-tunnel-edge; for ACI use cisco-aci-link.",
|
|
549
|
+
"example": "Hovering a network link on the topology map to read both interfaces' alias, status, IP, speed, and traffic."
|
|
550
|
+
},
|
|
551
|
+
"netroute-node": {
|
|
552
|
+
"useWhen": "Hovering a hop node on a Netroute path (netroute/node-tooltip.vue) — latency min/avg/max + loss + alerts on --topology-graph-tooltip-bg.",
|
|
553
|
+
"dontUse": "For a netroute transit edge use netroute-edge; for a topology monitor node use live-graph-node.",
|
|
554
|
+
"example": "Hovering a hop in a Netroute path to read its latency min/avg/max, loss, and alerts."
|
|
555
|
+
},
|
|
556
|
+
"netroute-edge": {
|
|
557
|
+
"useWhen": "Hovering a transit edge between hops on a Netroute path (netroute/edge-tooltip.vue) — latency/loss plus transit likelihood on --topology-graph-tooltip-bg.",
|
|
558
|
+
"dontUse": "For a hop node use netroute-node; for a generic topology edge use live-graph-edge.",
|
|
559
|
+
"example": "Hovering the transit segment between two Netroute hops to read latency, loss, and transit likelihood."
|
|
560
|
+
},
|
|
561
|
+
"flame-graph-span": {
|
|
562
|
+
"useWhen": "Hovering a span in a d3 flame graph (d3-flame-graph.vue) — APM trace drill-down or RUM view/action/long-task flame graphs. Shows name + self/total + % of trace; long-task adds source URL + invoker. Surface hc-tooltip-bg.",
|
|
563
|
+
"dontUse": "For a RUM resource-timing waterfall use rum-waterfall; for an APM service-map node use apm-service-node.",
|
|
564
|
+
"example": "Hovering a span in an APM trace flame graph to read its name, self/total time, and % of the trace."
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
@@ -216,6 +216,41 @@
|
|
|
216
216
|
"useWhen": "a time of day",
|
|
217
217
|
"how": "<MTimePicker v-model>",
|
|
218
218
|
"example": "daily run time"
|
|
219
|
+
},
|
|
220
|
+
"TimeRangePicker": {
|
|
221
|
+
"useWhen": "Selecting a TIME WINDOW for charts, dashboards, or log/metric explorers — relative presets (Last 5/15/30 Mins, Last 1/6/12/24/48 Hours, Today, Last Day, Last/This Week, Last/This Month) OR an absolute custom from/to range. This is the 42x hero control and the default answer for any observability time selection. Emits v-model { selectedKey, startDate, endDate, startTime, endTime }.",
|
|
222
|
+
"dontUse": "Don't use for a single date/date-time value in a form (use MDatePicker with :show-time), for a time-of-day schedule (MTimePicker), or when absolute custom ranges must be forbidden (use presets-only via :hide-custom-time-range). Don't hand-roll a relative-range dropdown — this is that control.",
|
|
223
|
+
"example": "The dashboard/metric-explorer/log-search time-window control — click the '24h' pill to open the preset list, or choose Custom for a dual-month absolute range with From/To time selects."
|
|
224
|
+
},
|
|
225
|
+
"presets-only": {
|
|
226
|
+
"useWhen": "You need TimeRangePicker but absolute custom ranges shouldn't be allowed — pass :hide-custom-time-range to drop the 'Custom' option and expose only the relative presets. The dominant configured variant (24x). Use for widgets/contexts where only relative windows make sense.",
|
|
227
|
+
"dontUse": "Don't use when users legitimately need to pick an absolute from/to calendar range — use the full TimeRangePicker (Custom enabled). Don't reach for a separate component; this is just TimeRangePicker with one prop.",
|
|
228
|
+
"example": "Widgets and panels where only relative rolling windows are valid — the preset list (Last 24 Hours, Last Week, etc.) with no absolute calendar."
|
|
229
|
+
},
|
|
230
|
+
"excluded-options": {
|
|
231
|
+
"useWhen": "You want TimeRangePicker but must hide specific preset keys that don't apply to the context — pass :excluded-options with an array of preset keys (e.g. ['today']) to drop just those presets while keeping the rest. A real, common variant (7x).",
|
|
232
|
+
"dontUse": "Don't use to remove the Custom range wholesale — that's :hide-custom-time-range (presets-only). Don't use if you need every preset; only reach for it when specific presets are invalid for the view.",
|
|
233
|
+
"example": "A view where a preset like 'Today' is meaningless is dropped via :excluded-options=\"['today']\" while the remaining relative windows stay available."
|
|
234
|
+
},
|
|
235
|
+
"MDatePicker": {
|
|
236
|
+
"useWhen": "A single date or date+time value in a FORM field. In the product it is ALWAYS used with :show-time (12-hour hh:mm A), so treat it as the date-TIME field with a calendar icon. Constrain with :min-date (7x) or :disabled-date, add :allow-clear for an × (9x).",
|
|
237
|
+
"dontUse": "Don't use for selecting a chart/dashboard time WINDOW — that's TimeRangePicker. Don't use for a bare time-of-day (use MTimePicker) or a presets-free custom range popover (DateTimePopover). Don't pass an empty string '' as the value — moment parses it to 'Invalid date'; pass null/undefined or a moment.",
|
|
238
|
+
"example": "A maintenance-window start or schedule date-time field: <MDatePicker :show-time :min-date :allow-clear v-model> opening a single-month calendar with a 12-hour time spinner."
|
|
239
|
+
},
|
|
240
|
+
"MTimePicker": {
|
|
241
|
+
"useWhen": "Just a time of day (e.g. a daily run time / schedule), rendered as a 12-hour picker with a clock icon (allow-clear default true). Documented for reference — wraps a-time-picker.",
|
|
242
|
+
"dontUse": "Don't reach for it as a standalone control in practice: the product uses NO standalone time picker — time-of-day is entered via MDatePicker :show-time or inside the TimeRangePicker custom view (which uses a custom dropdown-based TimePicker). Don't use for a date or date-time value (MDatePicker) or a time window (TimeRangePicker). Don't pass '' as the value (parses to Invalid date).",
|
|
243
|
+
"example": "A daily run-time / schedule time-of-day field (12-hour hh:mm A) — reference pattern; in real product code time-of-day arrives via MDatePicker show-time or the range custom view instead."
|
|
244
|
+
},
|
|
245
|
+
"TimeRangeSlider": {
|
|
246
|
+
"useWhen": "You need a draggable TIMELINE SCRUBBER over an existing time window — a horizontal rail with tick dots, time-mark labels, and two square handles that widen/narrow the selected window by dragging (min/max auto-expand ~4x the current duration). Emits the same shape as TimeRangePicker with selectedKey:'custom'.",
|
|
247
|
+
"dontUse": "Don't use as the primary way to pick a window when users expect presets — pair it with or defer to TimeRangePicker. Don't use in forms or for discrete date/time values. Only 2x — a specialized scrubber, not the default.",
|
|
248
|
+
"example": "The dashboard timeline scrubber and the alert-correlation drawer — drag the two handles to reshape the visible time window."
|
|
249
|
+
},
|
|
250
|
+
"DateTimePopover": {
|
|
251
|
+
"useWhen": "A custom absolute from/to range as a FORM field with NO presets — a lighter custom-range-only popover (built on MPopover + FlotoFormItem). Emits { startDate, endDate, startTime, endTime }.",
|
|
252
|
+
"dontUse": "Don't use when relative presets are wanted (use TimeRangePicker or presets-only) or for a single date-time value (MDatePicker). Rare (1x) — only when you specifically need an absolute from/to inside a form without the preset machinery.",
|
|
253
|
+
"example": "The SLO correction-profile form — a custom-range-only from/to popover with no relative presets."
|
|
219
254
|
}
|
|
220
255
|
},
|
|
221
256
|
"tokensUsed": [
|
|
@@ -332,4 +367,4 @@
|
|
|
332
367
|
"2026-06-30: matched the per-variant footer pattern (owner) — date-only shows a single centered \"Today\" link (not Now·Ok); time-only keeps Now·Ok; date-time keeps Now·select-time/date·Ok with the time spinner opening in the same popover.",
|
|
333
368
|
"2026-06-30: fixed field-calendar day states (owner) — selected (filled navy) and today (navy RING) were rendering identically; now distinct, plus a hover background on days. Applies to field-date and field-datetime (refactored day cells from inline styles to CSS classes so :hover works)."
|
|
334
369
|
]
|
|
335
|
-
}
|
|
370
|
+
}
|
|
@@ -133,6 +133,16 @@
|
|
|
133
133
|
"large-fullscreen(85-96%)": {
|
|
134
134
|
"useWhen": "complex MULTI-PANE flows (left nav + main form + right reference panel) — config/registration wizards",
|
|
135
135
|
"example": "APM Application Registration (width=96%); used ~30x at 90%/96%/85%/100%. Use a wide drawer, not a modal."
|
|
136
|
+
},
|
|
137
|
+
"FlotoDrawer": {
|
|
138
|
+
"useWhen": "You need a slide-in side panel to show the details of a record, or long/rich content contextual to the current context. Open it via the `open` prop (use .sync) or a `trigger` slot; give it a `title`, a scrollable body, and an `actions` footer with `{ hide }`. Default `width` is 40% — narrow to 360px for simple panels, widen to 50-70% for richer editors, or 85-96% for large multi-pane flows (left nav + main form + right reference panel) like config/registration wizards. It's the product's most-used overlay (99x).",
|
|
139
|
+
"dontUse": "Not for a short yes/no or destructive confirmation (use FlotoConfirmModal), nor a short focused task that should center-interrupt (use MModal). If the panel's whole purpose is an Add/Edit form with validation and a footer Save, reach for FlotoDrawerForm instead so MForm's default Submit is suppressed. Don't rely on backdrop-click to close (maskClosable:false) — use the built-in x or a footer Cancel.",
|
|
140
|
+
"example": "Incident details panel; view-detail / view-more drawers; gauge / compliance drilldown; credential / catalog selection drawers; APM Application Registration at width=96% (a wide multi-pane drawer, not a modal)."
|
|
141
|
+
},
|
|
142
|
+
"FlotoDrawerForm": {
|
|
143
|
+
"useWhen": "The panel is an Add/Edit FORM. It wraps a vertical FlotoForm with validation inside the drawer and suppresses MForm's default Submit so only the footer Save submits. Provide a `header` (title), fields in the body, and an `actions` footer exposing `{ hide, submit }`. Same open / width / scrolledContent props as FlotoDrawer (59x usage).",
|
|
144
|
+
"dontUse": "Not for a read-only detail view or non-form content — use plain FlotoDrawer there. Not for a short confirmation (FlotoConfirmModal) or a small center-interrupting task (MModal). Don't hand-roll a bare MForm inside a FlotoDrawer without suppressing its default Submit, or you get two submit buttons — that's exactly what FlotoDrawerForm solves.",
|
|
145
|
+
"example": "Most Add/Edit flows across the product; sync / runbook / firmware-upgrade approval drawers; attach-rules / attach-storage; the email-dispatch form."
|
|
136
146
|
}
|
|
137
147
|
},
|
|
138
148
|
"inProduct": {
|
|
@@ -333,6 +333,41 @@
|
|
|
333
333
|
},
|
|
334
334
|
"cap-selection": {
|
|
335
335
|
"useWhen": "limit count -> use maxValues, NOT maxAllowedSelection (dead, F2)"
|
|
336
|
+
},
|
|
337
|
+
"single": {
|
|
338
|
+
"useWhen": "Pick exactly one value from a list — the default and most common mode. Options are { key, text } and v-model binds the selected key. Trigger looks like a form field (asInput) unless overridden.",
|
|
339
|
+
"dontUse": "Don't use for choosing several values (use `multiple`), for free-form typed tags (use LooseTags), or for 2-3 always-visible exclusive options (use MRadio segmented) or a simple on/off (MSwitch).",
|
|
340
|
+
"example": "Choosing a monitor type, a template, or an owner; the severity picker; entity pickers like monitor-picker / user-picker / group-picker."
|
|
341
|
+
},
|
|
342
|
+
"not-searchable": {
|
|
343
|
+
"useWhen": "The list is short and fixed (≤ ~7 items) so the search box would just be noise — set `:searchable=\"false\"` (search defaults TRUE). Used 119×.",
|
|
344
|
+
"dontUse": "Don't disable search on long or dynamic lists where the user needs to filter — keep the default searchable behaviour there.",
|
|
345
|
+
"example": "A short fixed enum select such as a status or a small fixed set of options where scanning is faster than typing."
|
|
346
|
+
},
|
|
347
|
+
"text-only": {
|
|
348
|
+
"useWhen": "The trigger should be plain text rather than a form-field-looking input — set `textOnly` (asInput off). A lightweight, inline-looking trigger. Used 15×.",
|
|
349
|
+
"dontUse": "Don't use where the control should read as an editable form field (that's the default `asInput` input trigger). For fully custom triggers (button/avatar/pills) use the `trigger` slot instead.",
|
|
350
|
+
"example": "An inline, label-style select embedded in dense text or a toolbar where a boxed input would be visually heavy."
|
|
351
|
+
},
|
|
352
|
+
"read-only-pills": {
|
|
353
|
+
"useWhen": "A multi-select is disabled/read-only and you want to display the chosen values as teal SelectedItemPills instead of an editable trigger — the `multiple` + `disabled` presentation.",
|
|
354
|
+
"dontUse": "Don't use when the user still needs to edit the selection (keep the enabled `multiple` trigger). For an editable single value, use `single`.",
|
|
355
|
+
"example": "Monitoring Hours shown in a read-only/disabled state renders the selected hours as SelectedItemPills; any disabled multi-select summary."
|
|
356
|
+
},
|
|
357
|
+
"inline-add": {
|
|
358
|
+
"useWhen": "The user may need a value that isn't in the list yet — set `can-user-add-options` (+ `add-label`) to expose an inline add action in the search area that emits `add`.",
|
|
359
|
+
"dontUse": "Don't use for a closed/fixed set of options, or for truly free-form typed tags (use LooseTags for that).",
|
|
360
|
+
"example": "Pickers where the user can create a missing option on the fly (e.g. adding a tag/label that doesn't exist yet) and have it emitted via `add`."
|
|
361
|
+
},
|
|
362
|
+
"two-pane": {
|
|
363
|
+
"useWhen": "Options need explanatory context — set `useAfterMenuDescription` to render a two-pane layout: the option menu plus a description panel for the hovered item.",
|
|
364
|
+
"dontUse": "Don't use for simple lists where labels are self-explanatory; the extra description pane is wasted space there.",
|
|
365
|
+
"example": "A picker where each option needs a hovered-item description to disambiguate choices (e.g. selecting among options whose meaning isn't obvious from the label alone)."
|
|
366
|
+
},
|
|
367
|
+
"use-popover": {
|
|
368
|
+
"useWhen": "Anchor the dropdown with the kit's `MPopover` instead of the default `MPopper` (v-tooltip) — set `usePopover`. Used 26× where the MPopover overlay/positioning behaviour is needed.",
|
|
369
|
+
"dontUse": "Don't switch off the default unless you specifically need MPopover semantics; the standard trigger uses MPopper by default.",
|
|
370
|
+
"example": "Pickers embedded in contexts that already rely on the MPopover overlay kit for consistent positioning/stacking."
|
|
336
371
|
}
|
|
337
372
|
},
|
|
338
373
|
"insteadOf": [
|
|
@@ -163,5 +163,32 @@
|
|
|
163
163
|
"2026-07-01: made the row variant full-width (owner) — it was shrink-wrapping to a narrow box; now the host is block width:100% (like bar) and .frow fills the container in both the playground and examples.",
|
|
164
164
|
"2026-07-01: fixed buttons to match the product Button (border-radius 6px→4px via --btn-radius, primary weight 600→500) and added a native-control font-family reset — the <select>/<input> were rendering in the UA font (Arial), now Poppins.",
|
|
165
165
|
"2026-07-01: button font-weight 500→400 to match the real product Button (Ant default 400)."
|
|
166
|
-
]
|
|
167
|
-
|
|
166
|
+
],
|
|
167
|
+
"usageRules": {
|
|
168
|
+
"expression-builder": {
|
|
169
|
+
"useWhen": "You need real query logic — complex AND/OR conditions across one or more nested groups with typed operators. This is the most-used filter (FiltersContainer, 32×): a FilterTrigger input opens an MPopover with Pre/Post Filters tabs, 'Group(s) matching All/Any' → groups (Include/Exclude, matching All/Any) → conditions (field · operator · value, type-aware, Between → From/To), Add Condition (max 3) / Add New Group, and a Reset / Clear / Apply footer where Apply emits the query and renders it back into the trigger.",
|
|
170
|
+
"dontUse": "Don't use for a compact chip filter over a grid (→ Filter bar) or a small fixed set of facets (→ Filter row). Don't hand-roll a condition builder — always compose FiltersContainer. For plain text search of a list, use the Input 'search' type, not this.",
|
|
171
|
+
"example": "The nested AND/OR query builder popover opened from a search-style FilterTrigger over a grid — the 32× FiltersContainer usage, with Pre/Post Filter tabs and Include/Exclude groups matching All/Any."
|
|
172
|
+
},
|
|
173
|
+
"filter-bar": {
|
|
174
|
+
"useWhen": "You want a compact inline chip filter sitting directly over a grid. The Filter bar (FlotoFilterBar, ~50×) renders field·operator·value chips (default-chips declared by the module via defaultChips have no ×), a '+ Filter' button, a Match All/Any toggle, and Clear All; chips scroll horizontally while the segment picker floats position:fixed so it never clips.",
|
|
175
|
+
"dontUse": "Don't use when you need nested groups or AND/OR logic beyond a flat Match All/Any (→ Expression builder). Don't use for one-click presets (→ Quick filters) or a slide-in facet panel (→ Filter row). Not for plain text search (→ Input 'search' type).",
|
|
176
|
+
"example": "The inline chip bar over a data grid where the module seeds leading default-chips (e.g. Groups/Types/Severity via defaultChips) and users add field·operator·value chips with Match All/Any — the ~50× FlotoFilterBar usage."
|
|
177
|
+
},
|
|
178
|
+
"quick-filters": {
|
|
179
|
+
"useWhen": "You want to expose common, one-click preset filters. Quick filters (filter-quick-menu) is a thumbs-up button that opens a panel of PRESET filters as { key, label, condition }; picking one immediately applies that condition.",
|
|
180
|
+
"dontUse": "Don't use when users must author arbitrary conditions or groups (→ Expression builder) or maintain an evolving chip set over a grid (→ Filter bar). Not for facet multi-selects with Reset/Apply (→ Filter row).",
|
|
181
|
+
"example": "The thumbs-up preset menu beside a grid toolbar offering saved one-click filters ({ key, label, condition }) — click a preset to apply its condition instantly."
|
|
182
|
+
},
|
|
183
|
+
"filter-row": {
|
|
184
|
+
"useWhen": "You have a small, fixed set of facets to filter a list — a few multi-selects (e.g. Groups / Severity / Tags) plus Reset/Apply and a close ×, presented as a slide-in over the list.",
|
|
185
|
+
"dontUse": "Don't use for real query logic with nested AND/OR groups (→ Expression builder), for an inline chip bar over a grid (→ Filter bar), or for one-click presets (→ Quick filters).",
|
|
186
|
+
"example": "The slide-in Collection Filters panel over a monitoring list — a few multi-selects (Groups/Severity/Tags) with Reset/Apply and a close × (pattern e.g. metric-collection-filters.vue)."
|
|
187
|
+
},
|
|
188
|
+
"vertical-filter": {
|
|
189
|
+
"useWhen": "You need a faceted left-panel sidebar that filters (not navigates) a grid. The vertical filter is a search box atop collapsible MCollapse groups, each row a checkbox + optional status/type icon + label + count; checking rows narrows the grid. Used across APM Explorer, APM Error Tracker, RUM Sessions, and a richer NCM Explorer variant.",
|
|
190
|
+
"dontUse": "Don't confuse it with a Navigation side menu — it filters, so it lives in Filters (cross-referenced from Navigation → Side menu). Don't use it for a compact inline chip filter (→ Filter bar) or nested AND/OR logic (→ Expression builder).",
|
|
191
|
+
"example": "The APM Explorer / RUM Sessions left-panel faceted sidebar — a search over collapsible checkbox+count groups (with status/type icons) that filters the results grid; NCM Explorer uses the richer variant."
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -198,6 +198,31 @@
|
|
|
198
198
|
"layout": {
|
|
199
199
|
"useWhen": "vertical (label on top) for narrow/focused forms — drawers, modals, integration setup (Slack/Jira/ServiceNow), pickers; horizontal (label beside) for dense settings pages — Mail Server, Proxy, SNMP Trap, RADIUS, 2FA, My Profile",
|
|
200
200
|
"note": "set on the parent FlotoForm/MForm layout; drawers/modals -> vertical, full settings pages -> horizontal"
|
|
201
|
+
},
|
|
202
|
+
"text": {
|
|
203
|
+
"useWhen": "The field collects a short single-line string. Omit the default slot and set type=\"text\" (or leave type default) so FlotoFormItem renders its own built-in MInput; the wrapper still supplies label + validation + help/error.",
|
|
204
|
+
"dontUse": "Don't use for non-text controls (Select/Radio/Checkbox/picker/tag input — put those in the default slot), for multi-line prose (use textarea), or for numeric-only entry with steppers (use number).",
|
|
205
|
+
"example": "The 'Monitor name' / 'Name' text field on almost every create form, or 'Community String' on the SNMP settings form."
|
|
206
|
+
},
|
|
207
|
+
"number": {
|
|
208
|
+
"useWhen": "The field collects a numeric value; set type=\"number\" so the built-in MInput renders a number control. Pair with numeric rules like rules=\"required|numeric|min_value:1\".",
|
|
209
|
+
"dontUse": "Don't use for free-form text (use text) or for a value chosen from a fixed set (use custom-control with a radio/picker). Don't hand-roll min/max — express it in rules.",
|
|
210
|
+
"example": "The 'Polling Interval' field (with help 'In seconds. Lower values increase load.'), or 'Hours' / 'Threshold Counter' fields on create forms."
|
|
211
|
+
},
|
|
212
|
+
"textarea": {
|
|
213
|
+
"useWhen": "The field collects multi-line text — descriptions, notes, messages, scripts. Set type=\"textarea\" so the built-in MInput renders a multi-line box; the wrapper still gives label + validation.",
|
|
214
|
+
"dontUse": "Don't use for single-line strings (use text) or numbers (use number). Don't reach for a custom slot control — textarea is built in via type.",
|
|
215
|
+
"example": "A 'Description' field on a Group / profile create form, or a multi-line note on an integration setup panel."
|
|
216
|
+
},
|
|
217
|
+
"vertical": {
|
|
218
|
+
"useWhen": "Space is narrow or the flow is focused — drawers, modals, wizards, setup panels, and forms with long labels. Label stacks above a full-width control. Set layout=\"vertical\" on the parent FlotoForm/MForm. When unsure, vertical is the safe default (works at any width).",
|
|
219
|
+
"dontUse": "Don't use for a dense settings page with many short fields where label-to-value column alignment matters — that reads better horizontal.",
|
|
220
|
+
"example": "The Add/Edit drawers and integration setup forms — Slack, MS Teams, Jira, ServiceNow."
|
|
221
|
+
},
|
|
222
|
+
"horizontal": {
|
|
223
|
+
"useWhen": "A dense settings page with many short fields scanned top-to-bottom, where label-to-value alignment matters. Label sits in a left column, control to the right (tune with labelCol/wrapperCol). Set layout=\"horizontal\" on the parent FlotoForm/MForm.",
|
|
224
|
+
"dontUse": "Don't use in narrow containers like drawers/modals/wizards or with long labels — the two-column layout cramps; use vertical there.",
|
|
225
|
+
"example": "Mail Server, Proxy, SNMP Trap, RADIUS, Two-Factor Auth, and My Profile settings pages."
|
|
201
226
|
}
|
|
202
227
|
},
|
|
203
228
|
"notCovered": {
|
|
@@ -220,6 +220,11 @@
|
|
|
220
220
|
},
|
|
221
221
|
"FlotoFormItem": {
|
|
222
222
|
"useWhen": "any input in a form — adds the label + validation (the standard pattern, 1783x)"
|
|
223
|
+
},
|
|
224
|
+
"no-border-input": {
|
|
225
|
+
"useWhen": "A borderless field for inline editing — no visible box until interacted with, so the value reads like plain text in place. Rare (3x); use only where the field lives inside a larger surface and a border would add visual noise.",
|
|
226
|
+
"dontUse": "Don't use for normal form fields where users need to see the editable affordance — use the default bordered text input, or .material-input for a dense-but-visible underline. Reserve no-border for true inline-edit-in-place spots.",
|
|
227
|
+
"example": "An inline-editable label/title edited directly in place (e.g. renaming an item where the value sits inline, no form box), one of the ~3 borderless inline-edit spots."
|
|
223
228
|
}
|
|
224
229
|
},
|
|
225
230
|
"do": [
|
|
@@ -66,5 +66,14 @@
|
|
|
66
66
|
"Form view — monitor / policy / credential forms · Detail view — monitor / alert detail.",
|
|
67
67
|
"Dashboard view — dashboards / NOC · Explorer view — log / metric explorers.",
|
|
68
68
|
"Wizard flow — discovery / report setup / 2FA · Graph / Canvas — topology."
|
|
69
|
+
],
|
|
70
|
+
"decisionFlow": [
|
|
71
|
+
"Browsing/managing MANY records (a list you filter, sort, page)? -> List view (list-view recipe).",
|
|
72
|
+
"Create or edit ONE record? -> Form view (form-view) — off a list use a Drawer; complex/settings forms use a full page.",
|
|
73
|
+
"Viewing ONE record's details (status + related tabs)? -> Detail view (detail-view).",
|
|
74
|
+
"Metrics / an at-a-glance overview? -> Dashboard (dashboard-view, tiles).",
|
|
75
|
+
"Querying/exploring a dataset (filters + results, e.g. logs)? -> Explorer (explorer-view).",
|
|
76
|
+
"A guided, multi-step task? -> Wizard (wizard-flow).",
|
|
77
|
+
"Pick the archetype by what the page is FOR; don't invent a new page shape where one of these seven fits."
|
|
69
78
|
]
|
|
70
79
|
}
|
|
@@ -66,5 +66,45 @@
|
|
|
66
66
|
"Drawer 146 files · Modal 37 · Collapsible 19 · Popover 20+ · Expandable rows 9.",
|
|
67
67
|
"Dashboard tiles 5 · Bulk-action bar 2 · Resizable splits ~3 (settings / topology / apm trace).",
|
|
68
68
|
"Drawer is the default record surface; Modal for small confirms; Bulk-bar appears on selection."
|
|
69
|
-
]
|
|
69
|
+
],
|
|
70
|
+
"decisionFlow": [
|
|
71
|
+
"Short yes/no or destructive confirmation, or a small focused task that must center-interrupt? -> Modal (FlotoConfirmModal, variant=error for destructive; MModal for a short form). Keep it small.",
|
|
72
|
+
"A brief non-interactive hint? -> Tooltip. A small contextual menu / column-selector / rich mini-panel off a trigger? -> Popover (non-blocking).",
|
|
73
|
+
"Create/edit a record, or a panel-sized detail/drill-down contextual to a row (keep the list behind it)? -> Drawer (FlotoDrawerForm ~40% for forms; a WIDE drawer 85-96% for multi-pane flows or genuine deep dives). The product's default off-list surface.",
|
|
74
|
+
"A high-complexity record, a multi-step wizard, a settings section, or a screen that must be deep-linkable / own its route? -> a full PAGE/route (a page template), NOT a drawer or modal.",
|
|
75
|
+
"Optional, secondary detail on the current screen? -> Collapsible section or Expandable table row. Never collapse REQUIRED fields.",
|
|
76
|
+
"Other jobs: tiles in a grid -> Dashboard tiles; stick on scroll -> Affix; multi-select actions -> Bulk-action bar (appears on selection); split/resizable areas -> Resizable split."
|
|
77
|
+
],
|
|
78
|
+
"usageRules": {
|
|
79
|
+
"modal": {
|
|
80
|
+
"useWhen": "a short confirm/collect, or a focused task that must block until answered; destructive actions (variant=error, name the verb, not Yes/OK)",
|
|
81
|
+
"dontUse": "long/scrollable content or anything contextual to a record -> use a Drawer; a page-sized flow -> use a route",
|
|
82
|
+
"example": "Delete monitor? confirm; one-time API secret; quick Add-label form"
|
|
83
|
+
},
|
|
84
|
+
"drawer": {
|
|
85
|
+
"useWhen": "create/edit a record or a panel-sized detail off a list; keeps the list context behind the backdrop (~40% for forms, 85-96% wide for multi-pane / genuine deep dives)",
|
|
86
|
+
"dontUse": "a one-line confirm (-> Modal); a high-complexity record that deserves its own URL (-> page/route)",
|
|
87
|
+
"example": "Add Monitor / Edit Policy (FlotoDrawerForm); backup-compare deep dive (wide)"
|
|
88
|
+
},
|
|
89
|
+
"page-route": {
|
|
90
|
+
"useWhen": "a high-complexity record, a multi-step wizard, a settings section, or anything that must be deep-linkable / keep its own route",
|
|
91
|
+
"dontUse": "a quick edit off a list where a drawer keeps context better; a confirm (-> Modal)",
|
|
92
|
+
"example": "a full Settings policy form (hideSettingsMenu); a Report Builder wizard"
|
|
93
|
+
},
|
|
94
|
+
"popover": {
|
|
95
|
+
"useWhen": "a small, non-blocking contextual panel off a trigger — action menus, column selectors, sub-tabs, rich mini-panels",
|
|
96
|
+
"dontUse": "a center-interrupting task/confirm (-> Modal); long content (-> Drawer)",
|
|
97
|
+
"example": "row '...' action menu; column chooser"
|
|
98
|
+
},
|
|
99
|
+
"collapsible": {
|
|
100
|
+
"useWhen": "optional/secondary detail on the current screen the user can reveal",
|
|
101
|
+
"dontUse": "hiding REQUIRED fields; a whole record (-> Drawer)",
|
|
102
|
+
"example": "Advanced options section; expandable table-row detail"
|
|
103
|
+
},
|
|
104
|
+
"bulk-action-bar": {
|
|
105
|
+
"useWhen": "actions on a multi-selection in a grid/list; appears on selection",
|
|
106
|
+
"dontUse": "single-row actions (-> row menu / Popover)",
|
|
107
|
+
"example": "Delete Selected / Export on a checked table"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
70
110
|
}
|
|
@@ -90,5 +90,13 @@
|
|
|
90
90
|
"Every in-app page's content panel.",
|
|
91
91
|
"Two-pane → explorers, settings · Master-detail → alert/inventory records · Dashboard grid → dashboards.",
|
|
92
92
|
"Three-pane → metric / apm explorers · Chart-over-grid → trap viewer / log dashboards."
|
|
93
|
+
],
|
|
94
|
+
"decisionFlow": [
|
|
95
|
+
"Start EVERY page with a Page header (title + primary action). Then the body picks ONE content layout:",
|
|
96
|
+
"A flat list of records? -> Single column (Toolbar/Filter bar + Table + pager).",
|
|
97
|
+
"A tree/hierarchy on the left + detail on the right? -> Two-pane (master-detail).",
|
|
98
|
+
"A list where selecting a row opens a record beside/over it? -> Master-detail (list + Drawer).",
|
|
99
|
+
"Metric tiles? -> Dashboard grid. A chart above a supporting table? -> Chart-over-grid.",
|
|
100
|
+
"Only escalate to Three-pane when a saved-views rail AND a picker are BOTH needed. Don't combine two content layouts on one screen."
|
|
93
101
|
]
|
|
94
102
|
}
|
|
@@ -119,6 +119,21 @@
|
|
|
119
119
|
"k-link(class)": {
|
|
120
120
|
"useWhen": "subtle clickable text inside a table/grid",
|
|
121
121
|
"note": "--page-text-color, hover -> pagination-active; not brand-colored (25x)"
|
|
122
|
+
},
|
|
123
|
+
"text-link": {
|
|
124
|
+
"useWhen": "Inline INTERNAL navigation that takes the user somewhere via a route — links inside content/prose, menu items, breadcrumb segments, the app logo, or a clickable value that opens a detail view. First-match default of the FlotoLink decision flow once you've ruled out actions and external URLs. Add class=\"text-primary\" so it reads as a link (bare links inherit text color, F2).",
|
|
125
|
+
"dontUse": "Not for actions like save/delete/apply/change-state (use MButton) or for external/new-tab URLs (use a plain <a href target=_blank>, FlotoLink is internal-only). Use as-button instead when the internal nav must look like a prominent CTA, or k-link for subtle in-grid text.",
|
|
126
|
+
"example": "A breadcrumb segment, or 'go to the inventory list' inline in content; the navbar/header/user-menu logo and menu navigation links."
|
|
127
|
+
},
|
|
128
|
+
"external": {
|
|
129
|
+
"useWhen": "The destination is an external URL or should open in a new tab — documentation, help, or downloadable files. FlotoLink/RouterLink can't resolve external URLs, so hand-author a plain anchor: <a href target=\"_blank\" rel=\"noopener noreferrer\">. The rel is required (SF-004).",
|
|
130
|
+
"dontUse": "Don't use FlotoLink here (internal-only, can't resolve external URLs). For internal route navigation use text-link or as-button instead. Never omit rel=noopener noreferrer on a target=_blank link (reverse tabnabbing, SF-004).",
|
|
131
|
+
"example": "A documentation or help link that opens Motadata docs in a new tab."
|
|
132
|
+
},
|
|
133
|
+
"k-link": {
|
|
134
|
+
"useWhen": "A subtle clickable text inside a table/grid that shouldn't shout — neutral --page-text-color with a hover affordance instead of brand color, so it blends into dense grid rows and pagination. Applied as class=\"k-link\" (25× in the app).",
|
|
135
|
+
"dontUse": "Don't use for prominent or standalone inline links (use text-link with text-primary), for CTAs (as-button), or for actions (MButton). Not for external URLs.",
|
|
136
|
+
"example": "A subtle clickable cell value or pagination link inside a data grid."
|
|
122
137
|
}
|
|
123
138
|
},
|
|
124
139
|
"linkClasses": {
|
|
@@ -152,6 +152,11 @@
|
|
|
152
152
|
},
|
|
153
153
|
"counter": {
|
|
154
154
|
"useWhen": "scope suggestions to a specific entity (dominant real usage)"
|
|
155
|
+
},
|
|
156
|
+
"editable": {
|
|
157
|
+
"useWhen": "The user should free-type values and press Enter to create tags on a form; existing tags are offered as suggestions. This is the default mode. Values are lowercased, trimmed, and de-duped. v-model is an array of strings.",
|
|
158
|
+
"dontUse": "Don't use to pick from a fixed known set with search (use asDropdown), to show a list read-only (use disabled), or just to display a single label/count/status (use MTag / MStatusTag).",
|
|
159
|
+
"example": "Adding free-form tags to a monitor (the Monitor tags input)."
|
|
155
160
|
}
|
|
156
161
|
},
|
|
157
162
|
"usage": {
|
|
@@ -141,5 +141,17 @@
|
|
|
141
141
|
],
|
|
142
142
|
"doc": "Molecules/Menu/Accessibility",
|
|
143
143
|
"$note": "Catalogue-wide gap SF-001 = no visible :focus-visible ring; tracked in findings/."
|
|
144
|
+
},
|
|
145
|
+
"usageRules": {
|
|
146
|
+
"menu-primitive": {
|
|
147
|
+
"useWhen": "You need a vertical list of selectable icon+label rows rendered INSIDE another surface — a nav, a dropdown picker, a side menu, or a custom overlay. Reach for the MMenu primitive (MMenu / MMenuItem / MMenuDivider) as the shared building block; use MMenuDivider to group rows and the danger (--secondary-red) / positive (--secondary-green) item colours for destructive/affirmative rows. States it carries: hover (--neutral-lighter), selected (--primary on --code-tag-background-color).",
|
|
148
|
+
"dontUse": "Don't use the bare primitive when you specifically need a '...' trigger opening ACTIONS on a grid row/object — use the Context / Action menu (FlotoGridActions) which adds the ellipsis trigger and permission gating. Don't use it to pick a VALUE (single/multi) — that's Dropdown picker / Select. Don't use it for navigation to a destination — that's Primary nav / Side menu / Tabs. Never hand-roll a <ul> dropdown to replace it.",
|
|
149
|
+
"example": "The MMenu list that renders the item rows inside the Primary nav, the Side menu, and the Dropdown picker overlays — the same primitive reused across all of them rather than a hand-rolled list."
|
|
150
|
+
},
|
|
151
|
+
"context-menu": {
|
|
152
|
+
"useWhen": "You need a '⋯' (ellipsis-v) trigger — or a button — that opens a menu of ACTIONS on a specific row/object: Edit, Duplicate, Delete, etc. Use FlotoGridActions (an MPopover placement bottomRight opening an MMenu of action items); pass the row as `resource`, actions as {key,name,icon,isDanger/redAction,greenAction,type:'divider'}, and gate items via create/edit/delete permission keys. Colour destructive actions red (isDanger/redAction) and affirmative ones green (greenAction), each keeping its icon+label so meaning isn't colour-only.",
|
|
153
|
+
"dontUse": "Don't use it just to render a static list of rows with no action-trigger — use the Menu primitive directly. Don't use it to select a VALUE from options — use Dropdown picker / Select. Don't use it to navigate somewhere — use Navigation. Avoid the 1x MDropdown pattern (rich-text editor table options) as the standard row-action surface; FlotoGridActions is the standard.",
|
|
154
|
+
"example": "The '⋯' actions menu on each row of a Floto grid (e.g. an alert/monitor/report list), opening Edit / Duplicate / Delete where Delete is red and the whole item set is filtered by the user's create/edit/delete permissions."
|
|
155
|
+
}
|
|
144
156
|
}
|
|
145
157
|
}
|
|
@@ -180,6 +180,26 @@
|
|
|
180
180
|
"drawer-instead": {
|
|
181
181
|
"useWhen": "content is long or contextual to a record -> use FlotoDrawer (158x), not a modal",
|
|
182
182
|
"example": "incident details, approval drawers"
|
|
183
|
+
},
|
|
184
|
+
"MModal": {
|
|
185
|
+
"useWhen": "A focused, self-contained task or short form must interrupt the flow until the user finishes or dismisses it. Open via the trigger slot ({ open }); build your own header (title + close x) and a footer ({ cancel, success }); size with width/centered, use confirmLoading for async Save.",
|
|
186
|
+
"dontUse": "Don't use for yes/no or destructive confirmations (use FlotoConfirmModal), and don't use for long or record-contextual content like details/edit-in-place (use FlotoDrawer). Don't rely on the x or backdrop-click to close — both are disabled (F1), so always include a footer Cancel.",
|
|
187
|
+
"example": "The metric-explorer Forecast / Anomaly / Compare / Arithmetic analysis modals, the Error modal, password-verify, chart capture, and linked-records detail dialogs."
|
|
188
|
+
},
|
|
189
|
+
"FlotoConfirmModal": {
|
|
190
|
+
"useWhen": "Confirming a yes/no or destructive action before it runs. Drive the open prop (boolean); use icon + message slots, successText/cancelText, variant=\"error\" for destructive; listen to @confirm / @hide. Cancel sits left, the action right.",
|
|
191
|
+
"dontUse": "Don't use for a focused task or form that needs body input (use MModal). Don't label the actions Yes/OK — name the verb (Delete, Save). For a brief success/error message, use a notification instead of a confirm modal.",
|
|
192
|
+
"example": "Delete confirmations across CRUD lists (paginated-crud), inline name edit, widgets, rediscover, domain-mapping, and trap-profile delete — Delete monitor? with error variant and Cancel/Delete."
|
|
193
|
+
},
|
|
194
|
+
"restrict-width": {
|
|
195
|
+
"useWhen": "You need a fixed wide modal (side-by-side comparison, wide tables) at 1020px regardless of the width prop. Apply overlay-class-name=\"restrict-width\" (forces content min = max = 1020px); often paired with scrollable-modal.",
|
|
196
|
+
"dontUse": "Don't use for normal-width dialogs (use the width prop on MModal). Beyond a wide fixed modal, prefer a FlotoDrawer (the 85–96% full-screen pattern) rather than forcing 1020px.",
|
|
197
|
+
"example": "The compare-metric and diff-view modals that show wide side-by-side content."
|
|
198
|
+
},
|
|
199
|
+
"no-padding-modal": {
|
|
200
|
+
"useWhen": "The content manages its own padding — a code editor, a full-bleed list, or an embedded form — and the default modal padding gets in the way. Apply overlay-class-name=\"no-padding-modal\" (body → 8px) or no-padding-confrim-modal (body → 0).",
|
|
201
|
+
"dontUse": "Don't use for standard form/text dialogs that expect the default inset padding. This only strips padding; for scrolling long content combine with scrollable-modal, and for wide content with restrict-width.",
|
|
202
|
+
"example": "The log-collection profile list, view-query, LAMA integration, and activation-code modals."
|
|
183
203
|
}
|
|
184
204
|
},
|
|
185
205
|
"inProduct": {
|