@treeui/mcp 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{chunk-CEDY3OJ4.js → chunk-VPOHUNDH.js} +721 -119
- package/dist/cli.cjs +721 -119
- package/dist/cli.js +1 -1
- package/dist/index.cjs +733 -124
- package/dist/index.js +13 -6
- package/package.json +3 -3
package/dist/cli.cjs
CHANGED
|
@@ -34,9 +34,9 @@ var import_server = require("@modelcontextprotocol/sdk/server/index.js");
|
|
|
34
34
|
|
|
35
35
|
// src/generated/treeui.catalog.json
|
|
36
36
|
var treeui_catalog_default = {
|
|
37
|
-
generatedAt: "0.
|
|
37
|
+
generatedAt: "0.34.1",
|
|
38
38
|
packageName: "@treeui/vue",
|
|
39
|
-
packageVersion: "0.
|
|
39
|
+
packageVersion: "0.34.1",
|
|
40
40
|
decisionGuides: [
|
|
41
41
|
{
|
|
42
42
|
id: "single-choice",
|
|
@@ -159,7 +159,7 @@ var treeui_catalog_default = {
|
|
|
159
159
|
],
|
|
160
160
|
notes: [
|
|
161
161
|
"Editing, not display. For read-only key/value display use TDescriptionList.",
|
|
162
|
-
"A write-only/sensitive mode (value never read back) is a
|
|
162
|
+
"A write-only/sensitive mode (value never read back) is a designed contract that is not yet shipped."
|
|
163
163
|
]
|
|
164
164
|
},
|
|
165
165
|
{
|
|
@@ -457,8 +457,8 @@ var treeui_catalog_default = {
|
|
|
457
457
|
"Put the lockup in the `header-start` slot, not `header`. Filling `header-start` switches the header to the shell's own grid, so the mark tracks `--tree-app-shell-sidebar-width` and animates with the collapse \u2014 no local column math.",
|
|
458
458
|
'The slot is scoped: use its `collapsed` binding to drop the wordmark and keep only the mark (`v-if="!collapsed"`), rather than hiding text with CSS.',
|
|
459
459
|
'Logo is `TAvatar` (`size`, `alt`, `initials` fallback) or a plain `<img>` sized with `--tree-size-icon-*`; name and subtitle are `TText` (`weight`, `tone="muted"`, `truncate`) \u2014 never raw `<strong>`/`<span>` with a local class.',
|
|
460
|
-
"TreeUI ships no `TBrand` component on purpose: the logo asset, the product name, and what survives collapse are product identity, which must stay in the
|
|
461
|
-
"Company and service logos
|
|
460
|
+
"TreeUI ships no `TBrand` component on purpose: the logo asset, the product name, and what survives collapse are product identity, which must stay in the consuming application. See DECISIONS.md \u2192 Portability Boundary.",
|
|
461
|
+
"Company and service logos are brand assets, not TreeUI icons \u2014 source them from your own brand assets rather than the icon registry."
|
|
462
462
|
]
|
|
463
463
|
},
|
|
464
464
|
{
|
|
@@ -496,7 +496,7 @@ var treeui_catalog_default = {
|
|
|
496
496
|
"`TNavMenuItem.icon` is `TIconInput`, so a component is accepted too. Prefer the name: `items` normally lives in a `ref`, a `computed`, or a route config, and a string is never made reactive \u2014 a component object there needs `markRaw` or Vue warns.",
|
|
497
497
|
"An item with no icon (or an unregistered name) falls back to a letter marker, and a `console.warn` lists the valid names \u2014 once per name, in production builds too. Give every item an icon before shipping a collapsible rail, or the collapsed state is a column of letters.",
|
|
498
498
|
"Icons the app needs but TreeUI does not ship are REGISTERED, not worked around: one `registerTreeIcons` call in `main.ts` and they are usable by name everywhere. Never hand-roll an `<svg>` \u2014 without the `absoluteStrokeWidth` correction its stroke scales with the icon (1.67px at size 20, 4px at 48), so it looks bolder than its neighbours at every size above 24.",
|
|
499
|
-
"Check the name is not already taken before registering it \u2014 `hasTreeIcon(name)` answers that. Registering one of the
|
|
499
|
+
"Check the name is not already taken before registering it \u2014 `hasTreeIcon(name)` answers that. Registering one of the 370 built-in names replaces that built-in everywhere, silently, which is a supported swap but never what you want when the goal was adding an icon.",
|
|
500
500
|
"Keep the icon vocabulary consistent: built-ins use TreeUI's descriptive kebab-case names, so register custom ones with the same convention.",
|
|
501
501
|
"Icon registration is process-wide state. In component tests that register icons, call `resetTreeIcons()` in an `afterEach` so one case's icons do not leak into the next.",
|
|
502
502
|
"Set `to` for the route target on each item \u2014 `TNavMenuItem` has no `href` and no `id`; identity is `value`.",
|
|
@@ -804,28 +804,41 @@ var treeui_catalog_default = {
|
|
|
804
804
|
"Tab/Shift+Tab order, Escape to close, Enter/Space to activate, arrow keys where the pattern expects them.",
|
|
805
805
|
"Overlays trap focus while open and restore it on close.",
|
|
806
806
|
"Clickable targets stay at or above 44\xD744px.",
|
|
807
|
-
"Form control boundaries clear 3:1 against every surface (WCAG 1.4.11); decorative edges are a separate token and are not held to it."
|
|
807
|
+
"Form control boundaries clear 3:1 against every surface (WCAG 1.4.11); decorative edges are a separate token and are not held to it.",
|
|
808
|
+
"A panel anchored to a trigger is rendered in a layer no ancestor can clip, and is pushed back inside the viewport \u2014 a control that is painted off-screen or behind a clip is not operable.",
|
|
809
|
+
"Every string a screen reader announces is a prop with a default, never a hard-coded literal; a control whose only name is English is unusable in any other language."
|
|
808
810
|
],
|
|
809
811
|
components: [
|
|
810
|
-
"TModal",
|
|
811
|
-
"TDrawer",
|
|
812
|
-
"TConfirmDialog",
|
|
813
|
-
"TDropdown",
|
|
814
|
-
"TTooltip",
|
|
815
812
|
"TAccordion",
|
|
816
|
-
"
|
|
817
|
-
"TTreeView",
|
|
818
|
-
"TToastProvider",
|
|
813
|
+
"TAppShell",
|
|
819
814
|
"TButton",
|
|
815
|
+
"TCanvasSurface",
|
|
816
|
+
"TCheckbox",
|
|
820
817
|
"TCodeBlock",
|
|
818
|
+
"TConfirmDialog",
|
|
819
|
+
"TDatePicker",
|
|
820
|
+
"TDrawer",
|
|
821
|
+
"TDropdown",
|
|
822
|
+
"TFileUpload",
|
|
823
|
+
"TFormField",
|
|
824
|
+
"TIconTile",
|
|
825
|
+
"TImage",
|
|
821
826
|
"TLinkTile",
|
|
822
827
|
"TMenu",
|
|
828
|
+
"TModal",
|
|
823
829
|
"TPopover",
|
|
824
|
-
"
|
|
830
|
+
"TSelect",
|
|
825
831
|
"TSkipLink",
|
|
826
|
-
"
|
|
827
|
-
"
|
|
828
|
-
"
|
|
832
|
+
"TStatGroup",
|
|
833
|
+
"TSteps",
|
|
834
|
+
"TTable",
|
|
835
|
+
"TTabs",
|
|
836
|
+
"TText",
|
|
837
|
+
"TToast",
|
|
838
|
+
"TToastProvider",
|
|
839
|
+
"TToggleGroup",
|
|
840
|
+
"TTooltip",
|
|
841
|
+
"TTreeView"
|
|
829
842
|
]
|
|
830
843
|
},
|
|
831
844
|
{
|
|
@@ -885,26 +898,45 @@ var treeui_catalog_default = {
|
|
|
885
898
|
"Spacing comes from the --tree-space-* scale, applied by layout components.",
|
|
886
899
|
"Compose TPage, TStack, TGrid, and TSplit before writing a custom layout div.",
|
|
887
900
|
"Forms align through TFormField + TStack + TGrid \u2014 labels, hints, and errors line up by contract.",
|
|
888
|
-
"Reading widths and page gutters come from TContainer/TPage, not local max-widths."
|
|
901
|
+
"Reading widths and page gutters come from TContainer/TPage, not local max-widths.",
|
|
902
|
+
"A surface takes its container's width: it never grows to the min-content of something inside it. Card, modal and timeline surfaces declare an explicit minmax(0, 1fr) track, and text that can lack a break opportunity wraps, so scrolling and truncation belong to the descendant that asked for them \u2014 never to every sibling on the surface."
|
|
889
903
|
],
|
|
890
904
|
components: [
|
|
891
|
-
"
|
|
892
|
-
"
|
|
893
|
-
"TSplit",
|
|
894
|
-
"TContainer",
|
|
895
|
-
"TSpacer",
|
|
896
|
-
"TPage",
|
|
897
|
-
"TPageHeader",
|
|
898
|
-
"TFormField",
|
|
905
|
+
"TAppShell",
|
|
906
|
+
"TBadge",
|
|
899
907
|
"TBrandLockup",
|
|
900
|
-
"
|
|
908
|
+
"TCanvasSurface",
|
|
909
|
+
"TCard",
|
|
910
|
+
"TCodeBlock",
|
|
911
|
+
"TConfirmDialog",
|
|
912
|
+
"TContainer",
|
|
901
913
|
"TDescriptionList",
|
|
902
|
-
"
|
|
914
|
+
"TEmptyState",
|
|
915
|
+
"TFormField",
|
|
916
|
+
"TGrid",
|
|
903
917
|
"THero",
|
|
918
|
+
"THide",
|
|
919
|
+
"TIconTile",
|
|
920
|
+
"TLinkTile",
|
|
921
|
+
"TList",
|
|
922
|
+
"TModal",
|
|
923
|
+
"TNavMenu",
|
|
924
|
+
"TPage",
|
|
925
|
+
"TPageHeader",
|
|
904
926
|
"TPageSurface",
|
|
927
|
+
"TSection",
|
|
905
928
|
"TShow",
|
|
906
|
-
"
|
|
907
|
-
"
|
|
929
|
+
"TSpacer",
|
|
930
|
+
"TSparkline",
|
|
931
|
+
"TSplit",
|
|
932
|
+
"TStack",
|
|
933
|
+
"TStat",
|
|
934
|
+
"TStatGroup",
|
|
935
|
+
"TSteps",
|
|
936
|
+
"TTable",
|
|
937
|
+
"TTabs",
|
|
938
|
+
"TText",
|
|
939
|
+
"TTimeline"
|
|
908
940
|
]
|
|
909
941
|
},
|
|
910
942
|
{
|
|
@@ -931,6 +963,7 @@ var treeui_catalog_default = {
|
|
|
931
963
|
"TColorSwatch",
|
|
932
964
|
"TDescriptionList",
|
|
933
965
|
"THero",
|
|
966
|
+
"TIconTile",
|
|
934
967
|
"TImage",
|
|
935
968
|
"TInput",
|
|
936
969
|
"TKeyValueEditor",
|
|
@@ -944,6 +977,7 @@ var treeui_catalog_default = {
|
|
|
944
977
|
"TSection",
|
|
945
978
|
"TSelect",
|
|
946
979
|
"TStat",
|
|
980
|
+
"TStatGroup",
|
|
947
981
|
"TSwitch",
|
|
948
982
|
"TTag",
|
|
949
983
|
"TTagInput",
|
|
@@ -951,6 +985,24 @@ var treeui_catalog_default = {
|
|
|
951
985
|
"TTextarea",
|
|
952
986
|
"TToast"
|
|
953
987
|
]
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
id: "branchline-icons",
|
|
991
|
+
title: "Icons drawn to a contract",
|
|
992
|
+
summary: "Branchline is the drawing contract behind every shipped icon: one grid, one weight, one closed modifier vocabulary. It is checked rather than reviewed \u2014 the build renders each glyph and fails when two names look alike at 16px or when a shape draws nothing.",
|
|
993
|
+
rules: [
|
|
994
|
+
"One grid: a 24x24 canvas with geometry inside a 1.5-22.5 trim area, so a 2u stroke never clips; four keylines carry the set \u2014 square 17.5, circle 18.5 diameter, wide 18x14, tall 14x18 \u2014 and positions land on a 0.25u step.",
|
|
995
|
+
"One weight: 2u stroke, round caps and joins, currentColor and fill=none, all declared on the root <svg>. A child that sets stroke or fill breaks absoluteStrokeWidth and fails the build.",
|
|
996
|
+
"Legible at the size it ships at: every pair of canonical icons is rendered at 16px and must differ by at least 5% of its ink. The rule is measured by branchline.test.ts, not judged by eye.",
|
|
997
|
+
"A modifier gets territory of its own, and the base keeps its size: it is drawn inside bases that enclose space (shield, file, folder, calendar, ticket, message, square, badge, search) and in a cleared corner otherwise, where the base is redrawn at full size with that corner interrupted so 5.5u of canvas stays clear around the mark.",
|
|
998
|
+
"Every shape earns its place: each node is removed and re-rendered, and a node that changes less than 1% of the glyph's ink fails the build. Geometry is never derived from the icon's name.",
|
|
999
|
+
"A family shares one base, drawn once and reused literally; a variant changes exactly one thing, in one place, by one rule.",
|
|
1000
|
+
"The metaphor is the conventional one \u2014 an icon is not the place to be original. A concept with no settled picture composes one from Branchline primitives, drawn deliberately rather than generated.",
|
|
1001
|
+
"One concept, one canonical name, one drawing. A synonym is an alias that shares its target's geometry byte for byte, so mic and microphone can never drift apart."
|
|
1002
|
+
],
|
|
1003
|
+
components: [
|
|
1004
|
+
"TIcon"
|
|
1005
|
+
]
|
|
954
1006
|
}
|
|
955
1007
|
],
|
|
956
1008
|
setup: {
|
|
@@ -965,7 +1017,7 @@ var treeui_catalog_default = {
|
|
|
965
1017
|
},
|
|
966
1018
|
vueSetup: {
|
|
967
1019
|
pluginInstall: {
|
|
968
|
-
import: "import TreeUIPlugin from '@treeui/vue'",
|
|
1020
|
+
import: "import { TreeUIPlugin } from '@treeui/vue'",
|
|
969
1021
|
usage: "app.use(TreeUIPlugin)"
|
|
970
1022
|
},
|
|
971
1023
|
individualImports: {
|
|
@@ -1588,7 +1640,7 @@ var treeui_catalog_default = {
|
|
|
1588
1640
|
name: "showCollapseButton",
|
|
1589
1641
|
type: "boolean",
|
|
1590
1642
|
default: "true",
|
|
1591
|
-
note: "Renders the built-in collapse toggle in the sidebar footer. Desktop only, and only when `collapsible` is set \u2014 no need to wire your own. Never rendered in the mobile drawer."
|
|
1643
|
+
note: "Renders the built-in collapse toggle in the sidebar footer. Desktop only, and only when `collapsible` is set \u2014 no need to wire your own. Never rendered in the mobile drawer, and never inside the auto-rail band (between `breakpoint` and `railBreakpoint`): there the width decides the state, so the button could not change anything, did nothing when pressed, and announced the manual preference instead of what was on screen. Its `aria-expanded` and `aria-label` are derived from the EFFECTIVE collapsed state, as the glyph already was."
|
|
1592
1644
|
},
|
|
1593
1645
|
{
|
|
1594
1646
|
name: "collapseLabel",
|
|
@@ -1672,7 +1724,7 @@ var treeui_catalog_default = {
|
|
|
1672
1724
|
},
|
|
1673
1725
|
{
|
|
1674
1726
|
name: "header-end",
|
|
1675
|
-
description: "Trailing header region for actions/controls, pinned to the far end of the row. Filling it adds `has-end`; in the plain flex header the content region's grow already pushes it to the end, and in the `has-start` grid it becomes a content-sized third column with the trailing padding.
|
|
1727
|
+
description: "Trailing header region for actions/controls, pinned to the far end of the row. Filling it adds `has-end`; in the plain flex header the content region's grow already pushes it to the end, and in the `has-start` grid it becomes a content-sized third column with the trailing padding. Trailing alignment is the shell's own job, so header actions need no `TStack justify=flex-end` wrapper around them.\n",
|
|
1676
1728
|
note: "AppShellSlotProps"
|
|
1677
1729
|
},
|
|
1678
1730
|
{
|
|
@@ -1726,6 +1778,7 @@ var treeui_catalog_default = {
|
|
|
1726
1778
|
"menu_and_drawer_close_buttons_are_44px: true"
|
|
1727
1779
|
],
|
|
1728
1780
|
behavior: [
|
|
1781
|
+
"scroller_is_a_containing_block: `.t-app-shell__main` (and `.t-app-shell__sidebar-body`) carry `position: relative`. Without it an absolutely positioned descendant with auto insets \u2014 `.t-visually-hidden`, which this library itself uses for the TProgress label \u2014 anchored to the initial block instead of the panel: it was neither clipped nor scrolled with the panel, and it extended the DOCUMENT's scroll. The shell is `100dvh`, so the document is not supposed to scroll at all; it did, leaving an empty band below the shell.",
|
|
1729
1782
|
"fills_viewport_full_width_and_height: true",
|
|
1730
1783
|
"resets_body_margin_while_a_shell_is_mounted: body:has(.t-app-shell) { margin: 0 } \u2014 a deliberate global rule, scoped so it only applies to pages that mount a shell",
|
|
1731
1784
|
"header_spans_full_width_above_sidebar_and_content: true",
|
|
@@ -1813,7 +1866,8 @@ var treeui_catalog_default = {
|
|
|
1813
1866
|
"brand-lockup"
|
|
1814
1867
|
],
|
|
1815
1868
|
practices: [
|
|
1816
|
-
"accessible-by-default"
|
|
1869
|
+
"accessible-by-default",
|
|
1870
|
+
"content-alignment"
|
|
1817
1871
|
]
|
|
1818
1872
|
},
|
|
1819
1873
|
{
|
|
@@ -2024,6 +2078,18 @@ var treeui_catalog_default = {
|
|
|
2024
2078
|
"lg"
|
|
2025
2079
|
],
|
|
2026
2080
|
description: "Changes min-height and font-size only; inline padding is constant across sizes."
|
|
2081
|
+
},
|
|
2082
|
+
{
|
|
2083
|
+
name: "truncate",
|
|
2084
|
+
type: "boolean",
|
|
2085
|
+
default: "false",
|
|
2086
|
+
description: "Keep the label on one line and clip it with an ellipsis. Opt-in: the default is to wrap, because a status pill that silently loses the end of its text is worse than a two-line pill. Pass `label` alongside it so the full text reaches the `title` tooltip."
|
|
2087
|
+
},
|
|
2088
|
+
{
|
|
2089
|
+
name: "label",
|
|
2090
|
+
type: "string",
|
|
2091
|
+
default: "undefined",
|
|
2092
|
+
description: "The badge text. Only needed with `truncate`, which puts it in `title`; otherwise use the default slot."
|
|
2027
2093
|
}
|
|
2028
2094
|
],
|
|
2029
2095
|
events: [],
|
|
@@ -2046,8 +2112,10 @@ var treeui_catalog_default = {
|
|
|
2046
2112
|
"tone_remaps_variant_color_variables: true",
|
|
2047
2113
|
"tone_overrides_variant_danger_palette: true",
|
|
2048
2114
|
"tone_neutral_has_no_stylesheet_rule: true",
|
|
2115
|
+
'tint_ink_is_the_on_soft_token: The `soft` and `danger` variants paint their label with the tone\'s `*-on-soft` colour, never the tone\'s full-strength colour. `*-on-soft` is derived to clear AA on that exact tint and deepens as the tint deepens; the full-strength tone on its own tint measured below AA for eight of the ten tone/theme pairs, including `variant="soft" tone="neutral"`, which is both defaults. The mapping is declared in `@treeui/tokens` as `NATIVE_BADGE_TONES` and the stylesheet is tested against it.',
|
|
2049
2116
|
"icon_wrapper_rendered_only_when_slot_filled: true",
|
|
2050
|
-
"icon_renders_before_default_slot: true"
|
|
2117
|
+
"icon_renders_before_default_slot: true",
|
|
2118
|
+
"never_wider_than_its_container: The badge carries `max-inline-size: 100%` and `min-inline-size: 0`, so a long label wraps inside the container instead of pushing it. Wrapped lines use the UI line height with block padding rather than `line-height: 1`, at which a second line's ascenders touched the pill's border."
|
|
2051
2119
|
],
|
|
2052
2120
|
selection: {
|
|
2053
2121
|
keywords: [],
|
|
@@ -2065,6 +2133,7 @@ var treeui_catalog_default = {
|
|
|
2065
2133
|
practices: [
|
|
2066
2134
|
"predictable-api",
|
|
2067
2135
|
"state-clarity",
|
|
2136
|
+
"content-alignment",
|
|
2068
2137
|
"token-driven"
|
|
2069
2138
|
]
|
|
2070
2139
|
},
|
|
@@ -2255,7 +2324,7 @@ var treeui_catalog_default = {
|
|
|
2255
2324
|
name: "href",
|
|
2256
2325
|
type: "string",
|
|
2257
2326
|
default: "undefined",
|
|
2258
|
-
note: 'Anchor attributes (`href`, `target`, `rel`, `download`) are declared props and are only rendered when `as="a"`. They were fallthrough before, which typechecked as an error in a consumer\'s `strictTemplates` build even though a link button is the documented use of `as
|
|
2327
|
+
note: 'Anchor attributes (`href`, `target`, `rel`, `download`) are declared props and are only rendered when `as="a"`. They were fallthrough before, which typechecked as an error in a consumer\'s `strictTemplates` build even though a link button is the documented use of `as`.\n'
|
|
2259
2328
|
},
|
|
2260
2329
|
{
|
|
2261
2330
|
name: "target",
|
|
@@ -2670,6 +2739,116 @@ var treeui_catalog_default = {
|
|
|
2670
2739
|
recipes: [],
|
|
2671
2740
|
practices: []
|
|
2672
2741
|
},
|
|
2742
|
+
{
|
|
2743
|
+
name: "TCanvasSurface",
|
|
2744
|
+
aliases: [],
|
|
2745
|
+
package: "@treeui/vue",
|
|
2746
|
+
kind: "data-display",
|
|
2747
|
+
category: "Data Display",
|
|
2748
|
+
status: "available",
|
|
2749
|
+
purpose: "A sized, repaintable, hit-testable canvas for a data-driven drawing \u2014 a diagram, a graph, a custom plot.",
|
|
2750
|
+
sourceFile: "packages/vue/src/components/TCanvasSurface.vue",
|
|
2751
|
+
storyFile: "apps/docs/src/stories/CanvasSurface.stories.ts",
|
|
2752
|
+
storyTitle: "Components/Data Display/Canvas Surface",
|
|
2753
|
+
manifestFile: "docs/ai/COMPONENTS/canvas-surface.yaml",
|
|
2754
|
+
props: [
|
|
2755
|
+
{
|
|
2756
|
+
name: "draw",
|
|
2757
|
+
type: "(frame: CanvasSurfaceFrame) => void",
|
|
2758
|
+
required: true,
|
|
2759
|
+
note: "Paints the whole surface. Called on mount, on resize and on every `redraw()`. The context arrives already scaled to CSS pixels, so the drawing never does device-ratio arithmetic; it is expected to clear what it does not repaint.\n"
|
|
2760
|
+
},
|
|
2761
|
+
{
|
|
2762
|
+
name: "height",
|
|
2763
|
+
type: "number | string",
|
|
2764
|
+
default: "320",
|
|
2765
|
+
note: "Number is px, string is any CSS length. A diagram has no intrinsic height, so it is declared."
|
|
2766
|
+
},
|
|
2767
|
+
{
|
|
2768
|
+
name: "cursor",
|
|
2769
|
+
type: "string",
|
|
2770
|
+
default: "undefined",
|
|
2771
|
+
note: "Pointer over the surface. This cannot come from a stylesheet: the sensitive area is a rectangle inside the bitmap and no selector knows where it is. Bind it to whatever the consumer's hit-test just decided.\n"
|
|
2772
|
+
},
|
|
2773
|
+
{
|
|
2774
|
+
name: "maxPixelRatio",
|
|
2775
|
+
type: "number",
|
|
2776
|
+
default: "2"
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
name: "ariaLabel",
|
|
2780
|
+
type: "string",
|
|
2781
|
+
default: "undefined",
|
|
2782
|
+
note: "Sets role=img. A bitmap says nothing on its own."
|
|
2783
|
+
},
|
|
2784
|
+
{
|
|
2785
|
+
name: "redrawKey",
|
|
2786
|
+
type: "unknown",
|
|
2787
|
+
default: "undefined",
|
|
2788
|
+
note: "Repaint whenever this changes \u2014 pass the data, a version counter, or the theme. Deep-watched."
|
|
2789
|
+
}
|
|
2790
|
+
],
|
|
2791
|
+
events: [],
|
|
2792
|
+
slots: [
|
|
2793
|
+
{
|
|
2794
|
+
name: "default",
|
|
2795
|
+
description: "The long form of the drawing \u2014 a list, a table, the same data as markup. It lives inside the `<canvas>` element, which the browser exposes to assistive technology and never paints.\n"
|
|
2796
|
+
}
|
|
2797
|
+
],
|
|
2798
|
+
a11y: [
|
|
2799
|
+
"Give it an ariaLabel; a canvas is opaque to assistive technology.",
|
|
2800
|
+
"Put the same information in the default slot as markup \u2014 it is the accessible form, not a fallback.",
|
|
2801
|
+
"Anything clickable inside the drawing needs a real control elsewhere, or a keyboard user cannot reach it."
|
|
2802
|
+
],
|
|
2803
|
+
behavior: [
|
|
2804
|
+
"repaints_on_demand_not_on_a_clock: true",
|
|
2805
|
+
"backing_store_follows_the_element: true",
|
|
2806
|
+
"pointer_events_reach_the_canvas: true",
|
|
2807
|
+
"ssr_safe: Nothing touches the DOM outside onMounted."
|
|
2808
|
+
],
|
|
2809
|
+
selection: {
|
|
2810
|
+
keywords: [
|
|
2811
|
+
"canvas",
|
|
2812
|
+
"diagram",
|
|
2813
|
+
"graph",
|
|
2814
|
+
"node and edge",
|
|
2815
|
+
"custom drawing",
|
|
2816
|
+
"plot",
|
|
2817
|
+
"topology",
|
|
2818
|
+
"map",
|
|
2819
|
+
"hit testing"
|
|
2820
|
+
],
|
|
2821
|
+
useWhen: [
|
|
2822
|
+
"The drawing is data-driven and no chart primitive expresses it \u2014 nodes and edges, a topology, a custom plot.",
|
|
2823
|
+
"Parts of the drawing are click or hover targets.",
|
|
2824
|
+
"It must repaint when the data, the locale or the theme changes."
|
|
2825
|
+
],
|
|
2826
|
+
avoidWhen: [
|
|
2827
|
+
"A line, area or bar chart says it \u2014 use TChart, which brings axes, legend, tooltip and an accessible table.",
|
|
2828
|
+
"The drawing is ornament \u2014 use useDecorativeCanvas, which gates the loop on visibility and reduced motion.",
|
|
2829
|
+
"The shape is an inline trend \u2014 use TSparkline."
|
|
2830
|
+
],
|
|
2831
|
+
alternatives: [
|
|
2832
|
+
{
|
|
2833
|
+
component: "TChart",
|
|
2834
|
+
when: "The data fits axes and categories."
|
|
2835
|
+
},
|
|
2836
|
+
{
|
|
2837
|
+
component: "useDecorativeCanvas",
|
|
2838
|
+
when: "It is decoration, not information."
|
|
2839
|
+
}
|
|
2840
|
+
]
|
|
2841
|
+
},
|
|
2842
|
+
setup: {
|
|
2843
|
+
required: [],
|
|
2844
|
+
notes: []
|
|
2845
|
+
},
|
|
2846
|
+
recipes: [],
|
|
2847
|
+
practices: [
|
|
2848
|
+
"accessible-by-default",
|
|
2849
|
+
"content-alignment"
|
|
2850
|
+
]
|
|
2851
|
+
},
|
|
2673
2852
|
{
|
|
2674
2853
|
name: "TCard",
|
|
2675
2854
|
aliases: [],
|
|
@@ -2743,6 +2922,9 @@ var treeui_catalog_default = {
|
|
|
2743
2922
|
"unnamed_section_root: The default `section` root has no accessible name, so assistive tech exposes it as generic rather than as a region. The component sets no `inheritAttrs: false` and has a single root, so `aria-label` / `aria-labelledby` passed by the consumer fall through to that root when a named region is wanted."
|
|
2744
2923
|
],
|
|
2745
2924
|
behavior: [
|
|
2925
|
+
"surface_never_inflated_by_a_descendant: The surface and its body declare `grid-template-columns: minmax(0, 1fr)`. An implicit `auto` track takes its minimum from the min-content of its items, so one unbreakable descendant \u2014 a table, a code block, a machine string \u2014 behind any wrapper widened the whole surface and laid every sibling out past the border: `TText truncate` never engaged, the TTable wrapper's `overflow-x` never scrolled, and anything aligned to the end was painted outside the surface or over the neighbouring card.",
|
|
2926
|
+
"title_wraps_instead_of_widening_the_card: `.t-card__title` carries `overflow-wrap: anywhere`. A title without spaces used to set the card's min-content width, and the `#header` slot was no way out because the same track was still `auto`.",
|
|
2927
|
+
"actions_shrink_and_wrap: `.t-card__actions` is `flex-shrink: 1; min-inline-size: 0; flex-wrap: wrap`. It was `flex-shrink: 0`, so in a narrow card the controls were laid out past the border instead of moving to the next line \u2014 the header already wraps, and the actions now follow it.",
|
|
2746
2928
|
"body_wrapper_class: t-card__body",
|
|
2747
2929
|
"header_render_condition: The `header.t-card__header` element renders when ANY of the `header` slot, a truthy `title` prop, or the `actions` slot is present. All three branches are independent \u2014 actions alone still produces a header.",
|
|
2748
2930
|
"footer_render_condition: The `footer.t-card__footer` element renders only when the `footer` slot is supplied.",
|
|
@@ -2785,6 +2967,7 @@ var treeui_catalog_default = {
|
|
|
2785
2967
|
practices: [
|
|
2786
2968
|
"interaction-feedback",
|
|
2787
2969
|
"predictable-api",
|
|
2970
|
+
"content-alignment",
|
|
2788
2971
|
"token-driven"
|
|
2789
2972
|
]
|
|
2790
2973
|
},
|
|
@@ -2801,6 +2984,18 @@ var treeui_catalog_default = {
|
|
|
2801
2984
|
storyTitle: "Components/Data Display/Chart",
|
|
2802
2985
|
manifestFile: "docs/ai/COMPONENTS/chart.yaml",
|
|
2803
2986
|
props: [
|
|
2987
|
+
{
|
|
2988
|
+
name: "axisValueFormat",
|
|
2989
|
+
type: "(value: number) => string",
|
|
2990
|
+
default: "undefined",
|
|
2991
|
+
description: "Formatter for the AXIS ticks only, falling back to `valueFormat`. The two have different jobs and the axis is the one with no room: a tooltip can spell `R$ 1.500.000.000,00` in full, while the same string on a y-axis at 320px eats the plot \u2014 and the space reserved for it is capped at 40% of the chart, so past that it clips. One formatter could not serve both."
|
|
2992
|
+
},
|
|
2993
|
+
{
|
|
2994
|
+
name: "yAxisWidth",
|
|
2995
|
+
type: "number",
|
|
2996
|
+
default: "undefined",
|
|
2997
|
+
description: "Fix the space reserved for the y-axis labels, in pixels. Left unset, the chart MEASURES the formatted ticks and reserves what they need \u2014 the margin used to be a flat 44px, which clipped a formatted `1,234,567`. Set it to line several charts up on a shared gutter."
|
|
2998
|
+
},
|
|
2804
2999
|
{
|
|
2805
3000
|
name: "type",
|
|
2806
3001
|
type: "TChartType",
|
|
@@ -2945,6 +3140,7 @@ var treeui_catalog_default = {
|
|
|
2945
3140
|
"point-click has no keyboard equivalent \u2014 do not make it the only way to reach a behavior."
|
|
2946
3141
|
],
|
|
2947
3142
|
behavior: [
|
|
3143
|
+
"edge_x_labels_anchor_with_a_class_not_an_attribute: The first and last x labels carry `is-anchor-start` / `is-anchor-end`, not a `text-anchor` ATTRIBUTE. CSS always beats a presentation attribute, so `.t-chart__axis-label--x { text-anchor: middle }` silently won and the anchoring never applied \u2014 the last label kept rendering centred and hanging off the SVG.",
|
|
2948
3144
|
"colors_auto_assign_from_chart_palette: --tree-color-chart-1..8, cycling by series index; per-series color overrides",
|
|
2949
3145
|
"zero_baseline_for_bar_and_area: the y domain is extended to include 0 for bar and area; line uses the data extent. minY overrides it.",
|
|
2950
3146
|
"y_domain_uses_nice_ticks: every type runs through niceScale, which rounds the min down and the max up to round numbers",
|
|
@@ -2971,7 +3167,7 @@ var treeui_catalog_default = {
|
|
|
2971
3167
|
],
|
|
2972
3168
|
avoidWhen: [
|
|
2973
3169
|
"A single value tells the story \u2014 use TStat.",
|
|
2974
|
-
"You only need an inline trend with no axes \u2014 use TSparkline.",
|
|
3170
|
+
"You only need an inline trend with no axes \u2014 use TSparkline (`fluid` fills the card width).",
|
|
2975
3171
|
"The data is a part-of-whole breakdown \u2014 use TDonutChart."
|
|
2976
3172
|
],
|
|
2977
3173
|
alternatives: [
|
|
@@ -3143,6 +3339,17 @@ var treeui_catalog_default = {
|
|
|
3143
3339
|
storyTitle: "Components/Data Display/CodeBlock",
|
|
3144
3340
|
manifestFile: "docs/ai/COMPONENTS/code-block.yaml",
|
|
3145
3341
|
props: [
|
|
3342
|
+
{
|
|
3343
|
+
name: "size",
|
|
3344
|
+
type: "TSize",
|
|
3345
|
+
default: "md",
|
|
3346
|
+
values: [
|
|
3347
|
+
"sm",
|
|
3348
|
+
"md",
|
|
3349
|
+
"lg"
|
|
3350
|
+
],
|
|
3351
|
+
description: "Density. Scales the type size and the padding of the `<pre>` by tokens, like every other sized component. `md` is what the block has always shipped; `sm` is for a block inside a dense surface \u2014 a table cell, a list row \u2014 where the fixed type size dominated the row."
|
|
3352
|
+
},
|
|
3146
3353
|
{
|
|
3147
3354
|
name: "code",
|
|
3148
3355
|
type: "string",
|
|
@@ -3191,7 +3398,10 @@ var treeui_catalog_default = {
|
|
|
3191
3398
|
'scroll_region: The `<pre>` is `role="region"` + `tabindex="0"` + `aria-label` (from `label`) so keyboard users can scroll it \u2014 the library does this for you.',
|
|
3192
3399
|
"copy_button_state: The copy button's aria-label reflects the copied state briefly."
|
|
3193
3400
|
],
|
|
3194
|
-
behavior: [
|
|
3401
|
+
behavior: [
|
|
3402
|
+
"copyable_reserves_the_toolbar_width: With the copy button rendered, `.t-code-block.is-copyable .t-code-block__pre` reserves its width as `padding-inline-end`. The toolbar floats over the code, so a wrapped line used to run underneath it and the characters behind the button were unreadable. This only became visible once `wrap` started breaking for real: before, the long token overflowed sideways and never reached the button.",
|
|
3403
|
+
'wrap_reduces_the_min_content: `.t-code-block.is-wrap .t-code-block__pre` uses `overflow-wrap: anywhere`, not `break-word`. `break-word` breaks only once a width is already settled, so wherever the block\'s width came from its content \u2014 a grid `auto` track, a table cell, a flex item without `min-width: 0` \u2014 the longest run without a break opportunity became the minimum width and pushed the container instead of wrapping. That is precisely the case `wrap` exists for: a URL, a token, a credential. Same semantics as `TText wrap="anywhere"`.'
|
|
3404
|
+
],
|
|
3195
3405
|
selection: {
|
|
3196
3406
|
keywords: [
|
|
3197
3407
|
"code",
|
|
@@ -3229,6 +3439,7 @@ var treeui_catalog_default = {
|
|
|
3229
3439
|
recipes: [],
|
|
3230
3440
|
practices: [
|
|
3231
3441
|
"accessible-by-default",
|
|
3442
|
+
"content-alignment",
|
|
3232
3443
|
"token-driven"
|
|
3233
3444
|
]
|
|
3234
3445
|
},
|
|
@@ -3750,6 +3961,7 @@ var treeui_catalog_default = {
|
|
|
3750
3961
|
"icon_slot_marked_aria_hidden: true"
|
|
3751
3962
|
],
|
|
3752
3963
|
behavior: [
|
|
3964
|
+
"surface_never_inflated_by_a_descendant: `.t-confirm-dialog` and its body declare `grid-template-columns: minmax(0, 1fr)`, and the icon variant uses `auto minmax(0, 1fr)`. It inherits TModal's title and description wrapping, which is what keeps confirm and cancel on the surface when the dialog names a long resource \u2014 it passes `title`/`description` as strings and exposes no `#header` slot, so there was no way around it from the API.",
|
|
3753
3965
|
"built_on_modal_contract: true",
|
|
3754
3966
|
"default_confirm_button_variant: danger",
|
|
3755
3967
|
"default_cancel_button_variant: ghost",
|
|
@@ -3795,7 +4007,8 @@ var treeui_catalog_default = {
|
|
|
3795
4007
|
"confirm-destructive-action"
|
|
3796
4008
|
],
|
|
3797
4009
|
practices: [
|
|
3798
|
-
"accessible-by-default"
|
|
4010
|
+
"accessible-by-default",
|
|
4011
|
+
"content-alignment"
|
|
3799
4012
|
]
|
|
3800
4013
|
},
|
|
3801
4014
|
{
|
|
@@ -4175,6 +4388,8 @@ var treeui_catalog_default = {
|
|
|
4175
4388
|
"focus_is_not_trapped_and_tab_leaves_the_open_calendar: true"
|
|
4176
4389
|
],
|
|
4177
4390
|
behavior: [
|
|
4391
|
+
'panel_is_teleported_to_the_body: The calendar panel renders through `<Teleport to="body">` and is placed with `position: fixed` from the trigger\'s viewport rect by `useAnchoredLayer`. It used to be absolutely positioned inside the root, so inside a `TModal` it was trapped in the surface and clipped. Query it from `document.body` in tests.',
|
|
4392
|
+
'month_title_capitalises_only_its_first_letter: `text-transform: capitalize` uppercased every word, which in most locales hits a particle in the middle of the title \u2014 pt-BR\'s "setembro de 2026" rendered as "Setembro De 2026". The rule is now `none` plus a `::first-letter` uppercase.',
|
|
4178
4393
|
"value_format: YYYY-MM-DD",
|
|
4179
4394
|
"controlled_and_uncontrolled_open: true",
|
|
4180
4395
|
"open_state_emits_are_deduped: true",
|
|
@@ -4223,7 +4438,9 @@ var treeui_catalog_default = {
|
|
|
4223
4438
|
]
|
|
4224
4439
|
},
|
|
4225
4440
|
recipes: [],
|
|
4226
|
-
practices: [
|
|
4441
|
+
practices: [
|
|
4442
|
+
"accessible-by-default"
|
|
4443
|
+
]
|
|
4227
4444
|
},
|
|
4228
4445
|
{
|
|
4229
4446
|
name: "TDateTimePicker",
|
|
@@ -4664,6 +4881,7 @@ var treeui_catalog_default = {
|
|
|
4664
4881
|
"Provide a meaningful ariaLabel describing what the chart shows."
|
|
4665
4882
|
],
|
|
4666
4883
|
behavior: [
|
|
4884
|
+
"legend_label_is_the_flexible_column: `.t-donut-chart__legend-label` is `flex: 1 1 0` with `min-width: 0` and an ellipsis, and `.t-donut-chart__legend-value` is `flex: 0 0 auto`. A 60-character label used to push the value out of the card. The full text is carried in `title`, since truncation hides data the chart is meant to show.",
|
|
4667
4885
|
"colors_auto_assign_from_chart_palette: --tree-color-chart-1..8, cycling by visible-segment index; per-segment color overrides",
|
|
4668
4886
|
"hovering_a_slice_dims_the_rest_and_updates_center: the other segments get is-dimmed, the hovered donut segment grows to thickness + 4, and its legend row gets is-active",
|
|
4669
4887
|
"hovering_a_legend_row_drives_the_same_highlight: legend items carry the same pointerenter/pointerleave handlers as the segments",
|
|
@@ -5237,6 +5455,48 @@ var treeui_catalog_default = {
|
|
|
5237
5455
|
storyTitle: "Components/Data Entry/FileUpload",
|
|
5238
5456
|
manifestFile: "docs/ai/COMPONENTS/file-upload.yaml",
|
|
5239
5457
|
props: [
|
|
5458
|
+
{
|
|
5459
|
+
name: "uploadingLabel",
|
|
5460
|
+
type: "string",
|
|
5461
|
+
default: "Uploading files",
|
|
5462
|
+
description: "Accessible name for the spinner shown while `loading`."
|
|
5463
|
+
},
|
|
5464
|
+
{
|
|
5465
|
+
name: "uploadedAnnouncement",
|
|
5466
|
+
type: "(name: string) => string",
|
|
5467
|
+
default: "(n) => `${n} uploaded.`",
|
|
5468
|
+
description: "What the live region announces when a file succeeds. A function, because the file name sits inside the sentence and its position differs by language."
|
|
5469
|
+
},
|
|
5470
|
+
{
|
|
5471
|
+
name: "failedAnnouncement",
|
|
5472
|
+
type: "(name: string) => string",
|
|
5473
|
+
default: "(n) => `${n} failed.`",
|
|
5474
|
+
description: "The same, for a failure. The error text is appended after it."
|
|
5475
|
+
},
|
|
5476
|
+
{
|
|
5477
|
+
name: "showRejections",
|
|
5478
|
+
type: "boolean",
|
|
5479
|
+
default: "true",
|
|
5480
|
+
description: "Render the built-in rejection messages. Turn it off when the product already surfaces `files-rejected` in its own alert \u2014 otherwise the user reads the same refusal twice, and the embedded copy is the one that cannot be placed where the product wants it. The event fires either way."
|
|
5481
|
+
},
|
|
5482
|
+
{
|
|
5483
|
+
name: "clearLabel",
|
|
5484
|
+
type: "string",
|
|
5485
|
+
default: "Clear all",
|
|
5486
|
+
description: "Label for the button that drops every selected file. It was hard-coded English with no way out."
|
|
5487
|
+
},
|
|
5488
|
+
{
|
|
5489
|
+
name: "removeLabel",
|
|
5490
|
+
type: "string",
|
|
5491
|
+
default: "Remove",
|
|
5492
|
+
description: "Label for a row's remove button."
|
|
5493
|
+
},
|
|
5494
|
+
{
|
|
5495
|
+
name: "removeAriaLabel",
|
|
5496
|
+
type: "(file: File) => string",
|
|
5497
|
+
default: "(f) => `Remove ${f.name}`",
|
|
5498
|
+
description: "Accessible name for a row's remove button. A function, not a string, because the file name sits INSIDE the sentence and its position differs by language \u2014 a prefix and a suffix cannot express that."
|
|
5499
|
+
},
|
|
5240
5500
|
{
|
|
5241
5501
|
name: "modelValue",
|
|
5242
5502
|
type: "File[]",
|
|
@@ -5445,6 +5705,7 @@ var treeui_catalog_default = {
|
|
|
5445
5705
|
"remove_and_retry_meet_the_44px_target: true"
|
|
5446
5706
|
],
|
|
5447
5707
|
behavior: [
|
|
5708
|
+
"a_rejection_follows_the_active_language: A rejection is held as DATA (the file and the reason) and formatted during render. It used to be stored as its rendered string, frozen at refusal time, so switching language afterwards left the old sentence on screen \u2014 the one piece of copy in this component that could not be retranslated.",
|
|
5448
5709
|
"accepts_files_from_input_drop_and_paste: true",
|
|
5449
5710
|
"multiple_false_replaces_existing_selection: true",
|
|
5450
5711
|
"accept_maxFiles_and_maxFileSize_apply_to_all_entry_points: true",
|
|
@@ -5496,7 +5757,9 @@ var treeui_catalog_default = {
|
|
|
5496
5757
|
recipes: [
|
|
5497
5758
|
"page-drop-target"
|
|
5498
5759
|
],
|
|
5499
|
-
practices: [
|
|
5760
|
+
practices: [
|
|
5761
|
+
"accessible-by-default"
|
|
5762
|
+
]
|
|
5500
5763
|
},
|
|
5501
5764
|
{
|
|
5502
5765
|
name: "TFlag",
|
|
@@ -5809,6 +6072,12 @@ var treeui_catalog_default = {
|
|
|
5809
6072
|
name: "dense",
|
|
5810
6073
|
type: "boolean",
|
|
5811
6074
|
default: "false"
|
|
6075
|
+
},
|
|
6076
|
+
{
|
|
6077
|
+
name: "balance",
|
|
6078
|
+
type: "boolean",
|
|
6079
|
+
default: "false",
|
|
6080
|
+
note: 'Let the last row divide itself among the items it has instead of leaving empty tracks to its right \u2014 five cards over four tracks read as "one card failed to load". `auto-fit` cannot do it: it collapses a track only when that track is empty on EVERY row, so the remainder row keeps the widths of the rows above it. Balanced mode lays out with flex, where each line sizes itself: full rows are identical to the grid, only the remainder is shared out. Ignored when `columns` is set, since a declared track count already answers the same question.\n'
|
|
5812
6081
|
}
|
|
5813
6082
|
],
|
|
5814
6083
|
events: [],
|
|
@@ -5822,6 +6091,7 @@ var treeui_catalog_default = {
|
|
|
5822
6091
|
],
|
|
5823
6092
|
behavior: [
|
|
5824
6093
|
"semantic_element_controlled_by_as: true",
|
|
6094
|
+
"balance_shares_the_last_row_instead_of_leaving_holes: true",
|
|
5825
6095
|
"fixed_columns_supported: true",
|
|
5826
6096
|
"auto_fit_columns_supported: true",
|
|
5827
6097
|
"dense_mode_uses_grid_auto_flow_dense: true"
|
|
@@ -6114,6 +6384,7 @@ var treeui_catalog_default = {
|
|
|
6114
6384
|
"calendar-plus",
|
|
6115
6385
|
"calendar-range",
|
|
6116
6386
|
"calendar-x",
|
|
6387
|
+
"campaign",
|
|
6117
6388
|
"carousel",
|
|
6118
6389
|
"catalog",
|
|
6119
6390
|
"chart-column",
|
|
@@ -6150,7 +6421,6 @@ var treeui_catalog_default = {
|
|
|
6150
6421
|
"companion",
|
|
6151
6422
|
"compass",
|
|
6152
6423
|
"connections",
|
|
6153
|
-
"contentpilot",
|
|
6154
6424
|
"copy",
|
|
6155
6425
|
"cpu",
|
|
6156
6426
|
"cpu-chip",
|
|
@@ -6396,8 +6666,6 @@ var treeui_catalog_default = {
|
|
|
6396
6666
|
"tickets",
|
|
6397
6667
|
"timeline",
|
|
6398
6668
|
"timer",
|
|
6399
|
-
"toggle-left",
|
|
6400
|
-
"toggle-right",
|
|
6401
6669
|
"token-input",
|
|
6402
6670
|
"token-output",
|
|
6403
6671
|
"trail",
|
|
@@ -6435,10 +6703,18 @@ var treeui_catalog_default = {
|
|
|
6435
6703
|
},
|
|
6436
6704
|
{
|
|
6437
6705
|
name: "size",
|
|
6438
|
-
type: "number |
|
|
6706
|
+
type: "number | TIconSize",
|
|
6439
6707
|
default: "20",
|
|
6440
|
-
|
|
6441
|
-
|
|
6708
|
+
values: [
|
|
6709
|
+
"sm",
|
|
6710
|
+
"md",
|
|
6711
|
+
"lg",
|
|
6712
|
+
"xl",
|
|
6713
|
+
"2xl",
|
|
6714
|
+
"<number of pixels>"
|
|
6715
|
+
],
|
|
6716
|
+
description: "A token name from the icon scale, or a pixel number.",
|
|
6717
|
+
note: '`size` used to be `number | string`, which meant `<TIcon size="sm" />`\ntype-checked, wrote width="sm" onto the svg, and left the icon unsized \u2014\nit then stretched to fill its container, measured at 300px in the report\nthat produced this change. It now takes either a NUMBER of pixels or one\nof the icon-scale token names, which map to the same values as\n--tree-size-icon-sm | -md | -lg | -xl | -2xl (16 / 20 / 24 / 32 / 48 px).\nAn unrecognised string is a compile error in TypeScript and, for\nJavaScript consumers, falls back to the default size with a console\nwarning in development rather than rendering at an arbitrary size.\nA free-form CSS length is no longer accepted: set width/height in CSS\nfrom the icon scale instead, which is what TLanguageSelect\'s switcher\nvariant does.\n'
|
|
6442
6718
|
},
|
|
6443
6719
|
{
|
|
6444
6720
|
name: "strokeWidth",
|
|
@@ -6468,7 +6744,7 @@ var treeui_catalog_default = {
|
|
|
6468
6744
|
behavior: [
|
|
6469
6745
|
"unknown_name_renders_nothing: An unregistered name makes `resolveTreeIcon` return `undefined`, and `TIcon`'s `v-if` then renders no element at all \u2014 no empty box, no placeholder, no error. A `console.warn` names the missing icon, suggests the `registerTreeIcons` call, and lists every valid name. It warns once per NAME (not per message \u2014 the message embeds the valid-name list, which changes on every registration), so a miss inside a render loop cannot flood the console. The warning is NOT gated on `process.env.NODE_ENV`: it fires in production builds too, deliberately, because a missing icon is a misconfiguration worth hearing about once and `process` is undefined in most browser bundles. Components with a marker fallback (TNavMenu) show that instead \u2014 see nav-menu.yaml.",
|
|
6470
6746
|
'absolute_stroke_width_math: Icons draw on `viewBox="0 0 24 24"` with the svg sized to `size`, so painted pixels = (stroke-width attribute) * size / 24. With `absoluteStrokeWidth` (the default) the attribute is set to `(strokeWidth * 24) / size`, which cancels the scale: at the default `strokeWidth: 2` the attribute is 2.4 at size 20, 1.5 at 32, and 1.0 at 48 \u2014 a constant 2px painted at every size. That is the entire point of the correction: a 48px icon sits beside a 20px one at the same optical weight. A `size` of 0 or a non-numeric value keeps the nominal stroke rather than producing NaN/Infinity. Setting `absoluteStrokeWidth: false` pins the attribute at `strokeWidth`, which is the hand-rolled behaviour: the painted stroke then scales WITH the icon (1.67px at 20, 2.67px at 32, 4px at 48 \u2014 double the library weight).',
|
|
6471
|
-
"icons_are_built_lazily_and_cached: Geometry lives in a data registry; a component is created on first lookup and reused after that, so an unused icon stays as DATA instead of becoming a `defineComponent`. Note what this does not claim: the geometry for all
|
|
6747
|
+
"icons_are_built_lazily_and_cached: Geometry lives in a data registry; a component is created on first lookup and reused after that, so an unused icon stays as DATA instead of becoming a `defineComponent`. Note what this does not claim: the geometry for all 370 built-ins is retained by any import of the package (the registry copies `builtinTreeIconNodes` into a `Map` at module scope, so a live reference exists and nothing tree-shakes it away \u2014 `sideEffects: false` does not change that). The saving is component construction, not bundle bytes.",
|
|
6472
6748
|
"resolved_per_render: TIcon resolves its name in a computed, not once at setup, so an icon registered after the component mounted still appears.",
|
|
6473
6749
|
"migration_aliases: Twelve compatibility names resolve to the same geometry as their canonical names: grid \u2192 layout-grid, share \u2192 share-nodes, chevron-updown \u2192 chevrons-up-down, refresh \u2192 refresh-cw, comment/chat \u2192 message-circle, check-square \u2192 square-check, help \u2192 circle-help, automations \u2192 zap, connections \u2192 external-link, persona \u2192 user-round, and close \u2192 x.",
|
|
6474
6750
|
"company_logos_are_app_owned: Company logos are not built-ins. When an application needs one, it imports the official SVG as its own component and passes or registers that component under an application-owned name."
|
|
@@ -6518,7 +6794,89 @@ var treeui_catalog_default = {
|
|
|
6518
6794
|
recipes: [
|
|
6519
6795
|
"nav-menu-icons"
|
|
6520
6796
|
],
|
|
6521
|
-
practices: [
|
|
6797
|
+
practices: [
|
|
6798
|
+
"branchline-icons"
|
|
6799
|
+
]
|
|
6800
|
+
},
|
|
6801
|
+
{
|
|
6802
|
+
name: "TIconTile",
|
|
6803
|
+
aliases: [],
|
|
6804
|
+
package: "@treeui/vue",
|
|
6805
|
+
kind: "display",
|
|
6806
|
+
category: "Data Display",
|
|
6807
|
+
status: "available",
|
|
6808
|
+
purpose: "A registered icon on a toned ground, sized and coloured so the glyph reads at phone size.",
|
|
6809
|
+
sourceFile: "packages/vue/src/components/TIconTile.vue",
|
|
6810
|
+
storyFile: "apps/docs/src/stories/IconTile.stories.ts",
|
|
6811
|
+
storyTitle: "Components/Data Display/IconTile",
|
|
6812
|
+
manifestFile: "docs/ai/COMPONENTS/icon-tile.yaml",
|
|
6813
|
+
props: [
|
|
6814
|
+
{
|
|
6815
|
+
name: "name",
|
|
6816
|
+
type: "TIconName",
|
|
6817
|
+
default: "undefined",
|
|
6818
|
+
description: "Registry name. Use the default slot for a glyph that is not registered."
|
|
6819
|
+
},
|
|
6820
|
+
{
|
|
6821
|
+
name: "tone",
|
|
6822
|
+
type: "TIconTileTone",
|
|
6823
|
+
default: "brand",
|
|
6824
|
+
values: [
|
|
6825
|
+
"brand",
|
|
6826
|
+
"neutral",
|
|
6827
|
+
"success",
|
|
6828
|
+
"warning",
|
|
6829
|
+
"danger",
|
|
6830
|
+
"info"
|
|
6831
|
+
],
|
|
6832
|
+
description: "Selects the `--tree-icon-tile-accent` / `--tree-icon-tile-soft` pair. The ink is the tone's full-strength colour on its own `*-soft` tint, which is the pairing that tint is derived for."
|
|
6833
|
+
},
|
|
6834
|
+
{
|
|
6835
|
+
name: "size",
|
|
6836
|
+
type: "TSize",
|
|
6837
|
+
default: "md",
|
|
6838
|
+
values: [
|
|
6839
|
+
"sm",
|
|
6840
|
+
"md",
|
|
6841
|
+
"lg"
|
|
6842
|
+
],
|
|
6843
|
+
description: "2rem / 2.75rem / 3.5rem. The glyph steps with the tile (16 / 20 / 24px) so the ink keeps its proportion of the pill."
|
|
6844
|
+
},
|
|
6845
|
+
{
|
|
6846
|
+
name: "label",
|
|
6847
|
+
type: "string",
|
|
6848
|
+
default: "undefined",
|
|
6849
|
+
description: "Accessible name. Omit it when the tile sits beside a heading that already says the same thing \u2014 the glyph is then decoration, and a screen reader reading it twice is noise."
|
|
6850
|
+
}
|
|
6851
|
+
],
|
|
6852
|
+
events: [],
|
|
6853
|
+
slots: [
|
|
6854
|
+
{
|
|
6855
|
+
name: "default"
|
|
6856
|
+
}
|
|
6857
|
+
],
|
|
6858
|
+
a11y: [
|
|
6859
|
+
"semantic_element: span",
|
|
6860
|
+
'role_img_only_when_named: With `label` the tile is `role="img"` with that name; without it, `aria-hidden`. There is no third state where a glyph is announced as nothing.',
|
|
6861
|
+
"contrast_floor: 3:1, measured. An icon is a non-text UI component under WCAG 1.4.11, so the floor is 3:1 and not the 4.5:1 a badge has to clear \u2014 a badge carries a word. `packages/tokens/src/icon-tile-contrast.test.ts` measures every tone in both themes and fails the build below the floor, the same way the badge's own floor is held."
|
|
6862
|
+
],
|
|
6863
|
+
behavior: [],
|
|
6864
|
+
selection: {
|
|
6865
|
+
keywords: [],
|
|
6866
|
+
useWhen: [],
|
|
6867
|
+
avoidWhen: [],
|
|
6868
|
+
alternatives: []
|
|
6869
|
+
},
|
|
6870
|
+
setup: {
|
|
6871
|
+
required: [],
|
|
6872
|
+
notes: []
|
|
6873
|
+
},
|
|
6874
|
+
recipes: [],
|
|
6875
|
+
practices: [
|
|
6876
|
+
"accessible-by-default",
|
|
6877
|
+
"content-alignment",
|
|
6878
|
+
"token-driven"
|
|
6879
|
+
]
|
|
6522
6880
|
},
|
|
6523
6881
|
{
|
|
6524
6882
|
name: "TImage",
|
|
@@ -6641,7 +6999,7 @@ var treeui_catalog_default = {
|
|
|
6641
6999
|
name: "modelValue",
|
|
6642
7000
|
type: "T",
|
|
6643
7001
|
default: "undefined",
|
|
6644
|
-
note: "Generic over `T extends string | number`, so a `ref<number>` binds without a cast and `update:modelValue` pays back a number. `<script setup>` was widening every model to `string | number`,
|
|
7002
|
+
note: "Generic over `T extends string | number`, so a `ref<number>` binds without a cast and `update:modelValue` pays back a number. `<script setup>` was widening every model to `string | number`, and widening makes a numeric field a type error under `strictTemplates`, with no correct way to write the binding. When `T` is `number` the component parses the raw input value and only falls back to the raw string when it does not parse.\n"
|
|
6645
7003
|
},
|
|
6646
7004
|
{
|
|
6647
7005
|
name: "size",
|
|
@@ -7353,7 +7711,9 @@ var treeui_catalog_default = {
|
|
|
7353
7711
|
"aria_current: `page` when `current`.",
|
|
7354
7712
|
"focus_visible: Focus ring on the tile."
|
|
7355
7713
|
],
|
|
7356
|
-
behavior: [
|
|
7714
|
+
behavior: [
|
|
7715
|
+
"default_slot_does_not_stretch_its_children: `.t-link-tile__body` is `align-items: flex-start`, not the `stretch` default. The default slot is where a consumer drops a TTag or a TBadge, and stretch made a four-character tag as wide as the description. Title and description are TText and still wrap to the available width."
|
|
7716
|
+
],
|
|
7357
7717
|
selection: {
|
|
7358
7718
|
keywords: [
|
|
7359
7719
|
"tile",
|
|
@@ -7389,6 +7749,7 @@ var treeui_catalog_default = {
|
|
|
7389
7749
|
practices: [
|
|
7390
7750
|
"interaction-feedback",
|
|
7391
7751
|
"accessible-by-default",
|
|
7752
|
+
"content-alignment",
|
|
7392
7753
|
"token-driven"
|
|
7393
7754
|
]
|
|
7394
7755
|
},
|
|
@@ -7435,7 +7796,8 @@ var treeui_catalog_default = {
|
|
|
7435
7796
|
"not_selectable: For a single-select list of options use TSelectableList instead."
|
|
7436
7797
|
],
|
|
7437
7798
|
behavior: [
|
|
7438
|
-
"
|
|
7799
|
+
"actions_take_their_own_line_in_a_narrow_container: Inside the existing `@container (max-width: 30rem)` query, `.t-list-item__actions` becomes `flex-basis: 100%; order: 2; flex-wrap: wrap; justify-content: flex-end`. Rigid actions used to squeeze the content column down to 40\u2013110px rather than moving below it \u2014 the meta already dropped to its own line, and the actions now follow the same rule. Actions are still never hidden or auto-collapsed into an overflow menu; that stays a deliberate consumer choice.",
|
|
7800
|
+
"responsive: On a container narrower than 30rem the row wraps: meta drops below the content while actions stay visible inline, and the leading slot stays on the first line of the content \u2014 the wrap is for the meta only. Actions are NEVER hidden or auto-collapsed into an overflow menu \u2014 compose a TMenu inside the actions slot deliberately if an overflow is wanted (uses a CSS container query; the list sets container-type).",
|
|
7439
7801
|
"no_overflow_ownership: TList does not create, own, or collapse an actions overflow."
|
|
7440
7802
|
],
|
|
7441
7803
|
selection: {
|
|
@@ -7598,7 +7960,7 @@ var treeui_catalog_default = {
|
|
|
7598
7960
|
kind: "overlay",
|
|
7599
7961
|
category: "Overlay",
|
|
7600
7962
|
status: "available",
|
|
7601
|
-
purpose: "Rich action menu in a popover \u2014 slot-driven compound with groups, icons, descriptions, meta, destructive items, link items, and a radio (workspace-switch) item, with roving focus and keyboard support. Built on TPopover, so anchoring and focus restore come from there
|
|
7963
|
+
purpose: "Rich action menu in a popover \u2014 slot-driven compound with groups, icons, descriptions, meta, destructive items, link items, and a radio (workspace-switch) item, with roving focus and keyboard support. Built on TPopover, so anchoring and focus restore come from there.",
|
|
7602
7964
|
sourceFile: "packages/vue/src/components/TMenu.vue",
|
|
7603
7965
|
storyFile: "apps/docs/src/stories/Menu.stories.ts",
|
|
7604
7966
|
storyTitle: "Components/Overlay/Menu",
|
|
@@ -7843,6 +8205,10 @@ var treeui_catalog_default = {
|
|
|
7843
8205
|
"escape_closes_when_enabled: true"
|
|
7844
8206
|
],
|
|
7845
8207
|
behavior: [
|
|
8208
|
+
"surface_never_inflated_by_a_descendant: The surface and its body declare `grid-template-columns: minmax(0, 1fr)`. An implicit `auto` track takes its minimum from the min-content of its items, so one unbreakable descendant \u2014 a table, a code block, a machine string \u2014 behind any wrapper widened the whole surface and laid every sibling out past the border: `TText truncate` never engaged, the TTable wrapper's `overflow-x` never scrolled, and anything aligned to the end was painted outside the surface or over the neighbouring card.",
|
|
8209
|
+
"only_the_body_scrolls: `.t-modal__surface` is a flex column with `overflow: hidden`, and `.t-modal__body` is the single scroller (`flex: 1 1 auto; min-block-size: 0; overflow: auto`). The whole surface used to scroll, so on a short viewport the footer's actions sat below the fold and the title scrolled away with the content. A flex column also removes the implicit `auto` track, which is the other half of the inflation above.",
|
|
8210
|
+
"title_and_description_wrap: `.t-modal__title` and `.t-modal__description` carry `overflow-wrap: anywhere` \u2014 `anywhere`, not `break-word`, because only `anywhere` reduces the min-content. A confirm dialog exists to name the thing being deleted, and a resource name without a break opportunity used to push confirm and cancel off the surface at any width, desktop included.",
|
|
8211
|
+
"a_child_overlay_must_be_teleported: Because the surface now clips, a panel rendered inside it would be cut off. TSelect's listbox and TDatePicker's panel teleport to the body for exactly this reason; a consumer composing its own overlay inside a modal should do the same with `useAnchoredLayer`.",
|
|
7846
8212
|
"uses_teleport_to_body: true",
|
|
7847
8213
|
"locks_body_scroll_while_open: true",
|
|
7848
8214
|
"overlay_click_closes_when_enabled: true",
|
|
@@ -7887,7 +8253,8 @@ var treeui_catalog_default = {
|
|
|
7887
8253
|
],
|
|
7888
8254
|
practices: [
|
|
7889
8255
|
"accessible-by-default",
|
|
7890
|
-
"predictable-api"
|
|
8256
|
+
"predictable-api",
|
|
8257
|
+
"content-alignment"
|
|
7891
8258
|
]
|
|
7892
8259
|
},
|
|
7893
8260
|
{
|
|
@@ -8233,6 +8600,7 @@ var treeui_catalog_default = {
|
|
|
8233
8600
|
"aria_disabled: on link items when disabled"
|
|
8234
8601
|
],
|
|
8235
8602
|
behavior: [
|
|
8603
|
+
"labels_wrap_rather_than_scroll_the_sidebar: `.t-nav-menu__list` and `.t-nav-menu__copy` declare `grid-template-columns: minmax(0, 1fr)`, and the label and description carry `overflow-wrap: anywhere`. A sidebar is the one place a horizontal scrollbar is never the right answer, and an item label without a break opportunity used to give it one.",
|
|
8236
8604
|
"can_be_controlled_or_uncontrolled: true",
|
|
8237
8605
|
"can_inherit_collapsed_state_from_sidebar: true",
|
|
8238
8606
|
"supports_rich_item_rendering_via_slot: true"
|
|
@@ -8280,7 +8648,8 @@ var treeui_catalog_default = {
|
|
|
8280
8648
|
"responsive-navigation"
|
|
8281
8649
|
],
|
|
8282
8650
|
practices: [
|
|
8283
|
-
"interaction-feedback"
|
|
8651
|
+
"interaction-feedback",
|
|
8652
|
+
"content-alignment"
|
|
8284
8653
|
]
|
|
8285
8654
|
},
|
|
8286
8655
|
{
|
|
@@ -8299,7 +8668,7 @@ var treeui_catalog_default = {
|
|
|
8299
8668
|
{
|
|
8300
8669
|
name: "modelValue",
|
|
8301
8670
|
type: "number | null",
|
|
8302
|
-
note: "`null` is REAL, not an error state: clearing the field is empty, and the component emits `null` for it. So `v-model` needs a `ref<number | null>`, and a `ref<number>` is a genuine type error under
|
|
8671
|
+
note: "`null` is REAL, not an error state: clearing the field is empty, and the component emits `null` for it. So `v-model` needs a `ref<number | null>`, and a `ref<number>` is a genuine type error under `strictTemplates` rather than a gap in the library \u2014 here the binding is what has to widen, not the model. The opposite of TInput/TTabs/TToggleGroup, where the library's own model type was too wide and no narrow ref could bind it.\n"
|
|
8303
8672
|
},
|
|
8304
8673
|
{
|
|
8305
8674
|
name: "min",
|
|
@@ -8547,6 +8916,7 @@ var treeui_catalog_default = {
|
|
|
8547
8916
|
"Actions area holds standard focusable controls (e.g. TButton) \u2014 no custom roles added."
|
|
8548
8917
|
],
|
|
8549
8918
|
behavior: [
|
|
8919
|
+
"slot_presence_is_read_during_render: The template tests `$slots.title` / `$slots.subtitle` directly instead of a `computed` over `useSlots()`. The computed cached its first answer, so a `v-if`'d title slot that appeared later never rendered, and one that disappeared left an empty `<h1>` behind. This is the arrangement TCard already used for `$slots.header`.",
|
|
8550
8920
|
"title_and_subtitle_optional: true",
|
|
8551
8921
|
"heading_level_controlled_by_level: true",
|
|
8552
8922
|
"actions_area_right_aligned_and_wraps: true",
|
|
@@ -9567,14 +9937,14 @@ var treeui_catalog_default = {
|
|
|
9567
9937
|
props: [
|
|
9568
9938
|
{
|
|
9569
9939
|
name: "modelValue",
|
|
9570
|
-
type: "
|
|
9571
|
-
default: ""
|
|
9940
|
+
type: "T",
|
|
9941
|
+
default: "undefined"
|
|
9572
9942
|
},
|
|
9573
9943
|
{
|
|
9574
9944
|
name: "options",
|
|
9575
|
-
type: "TSelectOption[]",
|
|
9945
|
+
type: "TSelectOption<T>[]",
|
|
9576
9946
|
default: "[]",
|
|
9577
|
-
note: "Array of { label: string; value:
|
|
9947
|
+
note: "Array of { label: string; value: T; disabled?: boolean }"
|
|
9578
9948
|
},
|
|
9579
9949
|
{
|
|
9580
9950
|
name: "open",
|
|
@@ -9670,7 +10040,9 @@ var treeui_catalog_default = {
|
|
|
9670
10040
|
"outside_click_closes_dropdown: true",
|
|
9671
10041
|
"focus_restores_on_close: true",
|
|
9672
10042
|
"numeric_values_supported_without_string_coercion: true",
|
|
9673
|
-
"listbox_flips_above_trigger_when_space_below_is_insufficient: true"
|
|
10043
|
+
"listbox_flips_above_trigger_when_space_below_is_insufficient: true",
|
|
10044
|
+
"option_label_wraps_instead_of_being_clipped: `.t-select__option` carries `overflow-wrap: anywhere`, so a label without a break opportunity wraps inside the listbox rather than overflowing it and being cut off.",
|
|
10045
|
+
"listbox_is_teleported_to_the_body: The listbox renders through `<Teleport to=\"body\">` and is placed with `position: fixed` from the trigger's viewport rect by the `useAnchoredLayer` composable, matching the trigger's width. It used to be positioned inside the root, which meant ANY ancestor with `overflow` clipped it \u2014 the TTable wrapper cut it off and a modal trapped it. Consequences for tests: the listbox is not a descendant of the component's root element, so query it from `document.body`."
|
|
9674
10046
|
],
|
|
9675
10047
|
selection: {
|
|
9676
10048
|
keywords: [
|
|
@@ -9708,6 +10080,7 @@ var treeui_catalog_default = {
|
|
|
9708
10080
|
],
|
|
9709
10081
|
practices: [
|
|
9710
10082
|
"interaction-feedback",
|
|
10083
|
+
"accessible-by-default",
|
|
9711
10084
|
"predictable-api",
|
|
9712
10085
|
"token-driven"
|
|
9713
10086
|
]
|
|
@@ -10181,7 +10554,9 @@ var treeui_catalog_default = {
|
|
|
10181
10554
|
"Hit area is `--tree-size-control-lg` (48px) tall, above the 44px target floor.",
|
|
10182
10555
|
"The label must say where it goes; the library does not supply one."
|
|
10183
10556
|
],
|
|
10184
|
-
behavior: [
|
|
10557
|
+
behavior: [
|
|
10558
|
+
"hidden_link_paints_no_shadow: `.t-skip-link:not(:focus-visible)` sets `box-shadow: none`. The box is translated off-screen while hidden, but a 14px offset with a 34px blur is not: it painted a grey smudge in the top-left of every header, at every width, all the time. The shadow belongs to the focused state, which is when the link is actually on screen."
|
|
10559
|
+
],
|
|
10185
10560
|
selection: {
|
|
10186
10561
|
keywords: [
|
|
10187
10562
|
"skip link",
|
|
@@ -10406,6 +10781,12 @@ var treeui_catalog_default = {
|
|
|
10406
10781
|
default: "false",
|
|
10407
10782
|
note: "Marker on the final point (line/area)."
|
|
10408
10783
|
},
|
|
10784
|
+
{
|
|
10785
|
+
name: "fluid",
|
|
10786
|
+
type: "boolean",
|
|
10787
|
+
default: "false",
|
|
10788
|
+
note: "Fill the parent's width; `width` stays the viewBox. The height is unchanged on purpose \u2014 a sparkline is a band, and growing in both directions turns it into a chart that lies about its precision. Strokes use `non-scaling-stroke`, so the pen keeps its declared width.\n"
|
|
10789
|
+
},
|
|
10409
10790
|
{
|
|
10410
10791
|
name: "ariaLabel",
|
|
10411
10792
|
type: "string",
|
|
@@ -10421,7 +10802,8 @@ var treeui_catalog_default = {
|
|
|
10421
10802
|
behavior: [
|
|
10422
10803
|
"no_axes_or_legend: true",
|
|
10423
10804
|
"flat_series_renders_centered: true",
|
|
10424
|
-
"scales_to_intrinsic_width_and_height: true"
|
|
10805
|
+
"scales_to_intrinsic_width_and_height: true",
|
|
10806
|
+
"fluid_fills_parent_width: true"
|
|
10425
10807
|
],
|
|
10426
10808
|
selection: {
|
|
10427
10809
|
keywords: [
|
|
@@ -10461,7 +10843,9 @@ var treeui_catalog_default = {
|
|
|
10461
10843
|
recipes: [
|
|
10462
10844
|
"metric-dashboard"
|
|
10463
10845
|
],
|
|
10464
|
-
practices: [
|
|
10846
|
+
practices: [
|
|
10847
|
+
"content-alignment"
|
|
10848
|
+
]
|
|
10465
10849
|
},
|
|
10466
10850
|
{
|
|
10467
10851
|
name: "TSpinner",
|
|
@@ -10820,6 +11204,33 @@ var treeui_catalog_default = {
|
|
|
10820
11204
|
storyTitle: "Components/Data Display/Stat",
|
|
10821
11205
|
manifestFile: "docs/ai/COMPONENTS/stat.yaml",
|
|
10822
11206
|
props: [
|
|
11207
|
+
{
|
|
11208
|
+
name: "variant",
|
|
11209
|
+
type: "TStatVariant",
|
|
11210
|
+
default: "card (plain inside a TStatGroup)",
|
|
11211
|
+
values: [
|
|
11212
|
+
"card",
|
|
11213
|
+
"plain"
|
|
11214
|
+
],
|
|
11215
|
+
description: "Whether the tile draws its own card. `plain` keeps the padding, the type and the tones and drops the border, radius, shadow and background. Inside a `TStatGroup` the default flips to `plain`, because the group owns the surface; an explicit value always wins. A stat drawing its own card inside a TCard is a card within a card \u2014 doubled frame, summed padding, and eight of them read as eight objects rather than one row of figures."
|
|
11216
|
+
},
|
|
11217
|
+
{
|
|
11218
|
+
name: "metaPlacement",
|
|
11219
|
+
type: "'top' | 'bottom'",
|
|
11220
|
+
default: "top",
|
|
11221
|
+
description: 'Where the `meta` note sits. `top` shares the label\'s line; `bottom` puts it under the value, for the reading order of an indicator with a footnote. It is also a height fix: on the shared line a long label and a long note do not fit, the note wraps onto a line of its own ABOVE the value, and that one tile grows \u2014 the grid then stretches the whole row and every sibling shows an empty band. With `bottom` the DOM follows the visual order, so the announced order is label, value, note. Different from `emphasis="value"`, which promotes the FIGURE and takes the label down with it.'
|
|
11222
|
+
},
|
|
11223
|
+
{
|
|
11224
|
+
name: "size",
|
|
11225
|
+
type: "TSize",
|
|
11226
|
+
default: "md",
|
|
11227
|
+
values: [
|
|
11228
|
+
"sm",
|
|
11229
|
+
"md",
|
|
11230
|
+
"lg"
|
|
11231
|
+
],
|
|
11232
|
+
description: "Density. `sm` lowers the value's floor from 1.5rem to 1.125rem and tightens the padding, which is what lets two stats share a row on a phone \u2014 at the default floor a formatted negative currency does not fit, so a grid of six indicators collapsed into one tall column. The value still scales to its card through the container query, not to the viewport."
|
|
11233
|
+
},
|
|
10823
11234
|
{
|
|
10824
11235
|
name: "label",
|
|
10825
11236
|
type: "string",
|
|
@@ -10866,6 +11277,16 @@ var treeui_catalog_default = {
|
|
|
10866
11277
|
name: "loading",
|
|
10867
11278
|
type: "boolean",
|
|
10868
11279
|
default: "false"
|
|
11280
|
+
},
|
|
11281
|
+
{
|
|
11282
|
+
name: "emphasis",
|
|
11283
|
+
type: "TStatEmphasis",
|
|
11284
|
+
default: "label",
|
|
11285
|
+
values: [
|
|
11286
|
+
"label",
|
|
11287
|
+
"value"
|
|
11288
|
+
],
|
|
11289
|
+
note: 'Which half leads. `label` is the dashboard reading \u2014 the eye is scanning for what is measured. `value` puts the figure first, for a marketing band where the number IS the argument; it also keeps a row of figures on one baseline, because the labels above them no longer have to be the same height. Visual order only: the DOM keeps label before value, so the announcement stays "Requests served, 4.2M".\n'
|
|
10869
11290
|
}
|
|
10870
11291
|
],
|
|
10871
11292
|
events: [],
|
|
@@ -10892,6 +11313,7 @@ var treeui_catalog_default = {
|
|
|
10892
11313
|
],
|
|
10893
11314
|
behavior: [
|
|
10894
11315
|
"value_and_trend_are_optional: true",
|
|
11316
|
+
"emphasis_reorders_visually_not_in_the_dom: true",
|
|
10895
11317
|
"icon_slot_adds_visual_emphasis: true",
|
|
10896
11318
|
"trend_indicator_changes_with_direction: true",
|
|
10897
11319
|
"loading_renders_internal_skeleton_placeholders: true"
|
|
@@ -10929,6 +11351,76 @@ var treeui_catalog_default = {
|
|
|
10929
11351
|
"metric-dashboard"
|
|
10930
11352
|
],
|
|
10931
11353
|
practices: [
|
|
11354
|
+
"content-alignment",
|
|
11355
|
+
"token-driven"
|
|
11356
|
+
]
|
|
11357
|
+
},
|
|
11358
|
+
{
|
|
11359
|
+
name: "TStatGroup",
|
|
11360
|
+
aliases: [],
|
|
11361
|
+
package: "@treeui/vue",
|
|
11362
|
+
kind: "layout",
|
|
11363
|
+
status: "available",
|
|
11364
|
+
purpose: "A row of indicators sharing one surface, with a hairline between cells.",
|
|
11365
|
+
sourceFile: "packages/vue/src/components/TStatGroup.vue",
|
|
11366
|
+
manifestFile: "docs/ai/COMPONENTS/stat-group.yaml",
|
|
11367
|
+
props: [
|
|
11368
|
+
{
|
|
11369
|
+
name: "label",
|
|
11370
|
+
type: "string",
|
|
11371
|
+
default: "undefined",
|
|
11372
|
+
description: 'Accessible name for the band. Sets `aria-label` on a `role="group"`, so the row is announced as one unit rather than as a run of unrelated figures.'
|
|
11373
|
+
},
|
|
11374
|
+
{
|
|
11375
|
+
name: "columns",
|
|
11376
|
+
type: "number",
|
|
11377
|
+
default: "undefined",
|
|
11378
|
+
description: "Fixed track count. Leave unset to let `minItemWidth` decide."
|
|
11379
|
+
},
|
|
11380
|
+
{
|
|
11381
|
+
name: "minItemWidth",
|
|
11382
|
+
type: "string",
|
|
11383
|
+
default: "12rem",
|
|
11384
|
+
description: "Smallest a cell may get before a track is dropped. Same meaning as on TGrid."
|
|
11385
|
+
},
|
|
11386
|
+
{
|
|
11387
|
+
name: "balance",
|
|
11388
|
+
type: "boolean",
|
|
11389
|
+
default: "false",
|
|
11390
|
+
description: "Let the last row share itself out. Off by default here, unlike TGrid, and deliberately: a stat's value scales to its own cell (`container-type: inline-size`), so a lone cell stretched across the last row prints a number visibly larger than its siblings', and size on a dashboard reads as importance. An orphan beside empty space is the lesser mistake. The real fix for a band is a track count that divides the figures \u2014 set `columns`, or a `minItemWidth` that lands on one."
|
|
11391
|
+
}
|
|
11392
|
+
],
|
|
11393
|
+
events: [],
|
|
11394
|
+
slots: [
|
|
11395
|
+
{
|
|
11396
|
+
name: "default"
|
|
11397
|
+
}
|
|
11398
|
+
],
|
|
11399
|
+
a11y: [
|
|
11400
|
+
"semantic_element: div",
|
|
11401
|
+
"role: group",
|
|
11402
|
+
"naming: `label` is what makes the band a named unit. Without it the group has no accessible name and is announced as an unlabelled grouping."
|
|
11403
|
+
],
|
|
11404
|
+
behavior: [
|
|
11405
|
+
'children_render_plain_without_being_told: The group provides a context that TStat reads, so every child defaults to `variant="plain"` inside it. The alternative is the consumer repeating `variant="plain"` on all eight, which is the alignment busywork this library exists to absorb \u2014 and which goes wrong on the ninth one added later. An explicit `variant` on a child still wins.',
|
|
11406
|
+
"the_track_is_a_TGrid: Composed, not re-implemented, so `columns`, `minItemWidth` and `balance` behave exactly as they do everywhere else. `gap` is 0: the cells have to meet for the hairline to be a shared edge, and the breathing room comes from each cell's own padding.",
|
|
11407
|
+
"hairlines_survive_reflow: Every cell carries a start and a top line as pseudo-elements, and the track is pulled back one pixel so the outermost pair falls outside the clipped box. A cell that reflows onto a new row keeps its top line and becomes the first of its row, where its start line is the one being clipped \u2014 nothing hanging on the outer edge, nothing doubled between neighbours. `:nth-child` cannot express this, because which cell starts a row depends on a track count only the browser knows.",
|
|
11408
|
+
"pseudo_elements_not_borders: A border would land on the child's own `border-width`. The contract is that a cell in a band measures as frameless from the outside \u2014 `border-width` is actually 0 \u2014 so the lines are drawn beside the cell rather than on it."
|
|
11409
|
+
],
|
|
11410
|
+
selection: {
|
|
11411
|
+
keywords: [],
|
|
11412
|
+
useWhen: [],
|
|
11413
|
+
avoidWhen: [],
|
|
11414
|
+
alternatives: []
|
|
11415
|
+
},
|
|
11416
|
+
setup: {
|
|
11417
|
+
required: [],
|
|
11418
|
+
notes: []
|
|
11419
|
+
},
|
|
11420
|
+
recipes: [],
|
|
11421
|
+
practices: [
|
|
11422
|
+
"accessible-by-default",
|
|
11423
|
+
"content-alignment",
|
|
10932
11424
|
"token-driven"
|
|
10933
11425
|
]
|
|
10934
11426
|
},
|
|
@@ -10941,7 +11433,7 @@ var treeui_catalog_default = {
|
|
|
10941
11433
|
kind: "navigation",
|
|
10942
11434
|
category: "Navigation",
|
|
10943
11435
|
status: "available",
|
|
10944
|
-
purpose: "
|
|
11436
|
+
purpose: "Ordered sequence \u2014 a wizard to operate, or a described flow to read.",
|
|
10945
11437
|
sourceFile: "packages/vue/src/components/TSteps.vue",
|
|
10946
11438
|
storyFile: "apps/docs/src/stories/Steps.stories.ts",
|
|
10947
11439
|
storyTitle: "Components/Navigation/Steps",
|
|
@@ -10985,7 +11477,20 @@ var treeui_catalog_default = {
|
|
|
10985
11477
|
{
|
|
10986
11478
|
name: "interactive",
|
|
10987
11479
|
type: "boolean",
|
|
10988
|
-
default: "false"
|
|
11480
|
+
default: "false",
|
|
11481
|
+
note: "Whether a step can be picked. False \u2014 the default \u2014 renders inert boxes: no button in the accessibility tree, no disabled wash, and no step elected current unless `modelValue`/`defaultValue` or an item `status` says so. A described sequence used to render one dead control per step, at 60% opacity, with the first step ringed as if the reader were standing on it.\n"
|
|
11482
|
+
},
|
|
11483
|
+
{
|
|
11484
|
+
name: "columns",
|
|
11485
|
+
type: "number",
|
|
11486
|
+
default: "undefined",
|
|
11487
|
+
note: "Fixed steps per row, horizontal only. Use for a sequence with a shape (3 + 3)."
|
|
11488
|
+
},
|
|
11489
|
+
{
|
|
11490
|
+
name: "minItemWidth",
|
|
11491
|
+
type: "string",
|
|
11492
|
+
default: "14rem",
|
|
11493
|
+
note: "Width at which a step stops shrinking and the strip wraps. Same axis as TGrid."
|
|
10989
11494
|
}
|
|
10990
11495
|
],
|
|
10991
11496
|
events: [
|
|
@@ -11001,10 +11506,13 @@ var treeui_catalog_default = {
|
|
|
11001
11506
|
a11y: [
|
|
11002
11507
|
"semantic_root: ol",
|
|
11003
11508
|
"current_step_uses_aria_current_step: true",
|
|
11004
|
-
"interactive_variant_uses_buttons: true"
|
|
11509
|
+
"interactive_variant_uses_buttons: true",
|
|
11510
|
+
"static_variant_emits_no_control: true"
|
|
11005
11511
|
],
|
|
11006
11512
|
behavior: [
|
|
11007
11513
|
"can_be_controlled_or_uncontrolled: true",
|
|
11514
|
+
"static_variant_elects_no_current_step: true",
|
|
11515
|
+
"shared_box_class_is_t_steps_box: true",
|
|
11008
11516
|
"status_can_be_explicit_or_computed: true",
|
|
11009
11517
|
"alias_export_available: true"
|
|
11010
11518
|
],
|
|
@@ -11035,7 +11543,10 @@ var treeui_catalog_default = {
|
|
|
11035
11543
|
]
|
|
11036
11544
|
},
|
|
11037
11545
|
recipes: [],
|
|
11038
|
-
practices: [
|
|
11546
|
+
practices: [
|
|
11547
|
+
"accessible-by-default",
|
|
11548
|
+
"content-alignment"
|
|
11549
|
+
]
|
|
11039
11550
|
},
|
|
11040
11551
|
{
|
|
11041
11552
|
name: "TSwitch",
|
|
@@ -11142,11 +11653,23 @@ var treeui_catalog_default = {
|
|
|
11142
11653
|
storyTitle: "Components/Data Display/Table",
|
|
11143
11654
|
manifestFile: "docs/ai/COMPONENTS/table.yaml",
|
|
11144
11655
|
props: [
|
|
11656
|
+
{
|
|
11657
|
+
name: "stackBelow",
|
|
11658
|
+
type: "TBreakpoint",
|
|
11659
|
+
default: "undefined",
|
|
11660
|
+
values: [
|
|
11661
|
+
"sm",
|
|
11662
|
+
"md",
|
|
11663
|
+
"lg",
|
|
11664
|
+
"xl"
|
|
11665
|
+
],
|
|
11666
|
+
description: "Below this CONTAINER width the grid becomes one block per row: the column marked `stack=\"title\"` is the block's heading, the rest sit under it, and each value carries its column's label because the header row is gone. Above it the table is unchanged, horizontal scroll included. Measured on the wrapper and not the viewport \u2014 a table can sit in a narrow panel on a wide screen, which is the case a media query cannot see. A breakpoint name and not a free length: a container query cannot read a custom property in its condition, so an arbitrary value would need a ResizeObserver per table."
|
|
11667
|
+
},
|
|
11145
11668
|
{
|
|
11146
11669
|
name: "columns",
|
|
11147
11670
|
type: "TTableColumn[]",
|
|
11148
11671
|
required: true,
|
|
11149
|
-
description: "Array of column definitions with key, label, sortable, align, and
|
|
11672
|
+
description: "Array of column definitions with key, label, sortable, align, width, and minWidth."
|
|
11150
11673
|
},
|
|
11151
11674
|
{
|
|
11152
11675
|
name: "rows",
|
|
@@ -11188,6 +11711,35 @@ var treeui_catalog_default = {
|
|
|
11188
11711
|
type: "(row, index) => 'default' | 'muted'",
|
|
11189
11712
|
required: false,
|
|
11190
11713
|
description: "Semantic per-row state applied by data, not position, so it survives sorting. `muted` recesses a row (e.g. a resource that no longer exists) via `t-table__row--muted`, written at compound specificity so it wins over the zebra/hover rules."
|
|
11714
|
+
},
|
|
11715
|
+
{
|
|
11716
|
+
name: "rowHref",
|
|
11717
|
+
type: "(row: Record<string, unknown>, index: number) => string | undefined",
|
|
11718
|
+
default: "undefined",
|
|
11719
|
+
description: 'The row NAVIGATES: a real `href` per row, rendered as an `<a>` in the first cell and stretched over the whole row via `::after`, so ctrl/middle-click, "open in new tab", and the status-bar URL all work and the accessible role is `link`. Mutually exclusive with `rowTo` and `rowActivatable` \u2014 dev builds warn. The affordance follows the RESOLVED target: a row whose function returns `undefined` renders no link and gets no pointer.'
|
|
11720
|
+
},
|
|
11721
|
+
{
|
|
11722
|
+
name: "rowTo",
|
|
11723
|
+
type: "(row: Record<string, unknown>, index: number) => string | undefined",
|
|
11724
|
+
default: "undefined",
|
|
11725
|
+
description: "Same as `rowHref`, resolved through the app's RouterLink instead of a plain `<a>`."
|
|
11726
|
+
},
|
|
11727
|
+
{
|
|
11728
|
+
name: "rowLabel",
|
|
11729
|
+
type: "(row: Record<string, unknown>, index: number) => string",
|
|
11730
|
+
default: "undefined",
|
|
11731
|
+
description: "Accessible name for the row's activator, per row \u2014 used by BOTH `rowHref`/`rowTo` and `rowActivatable`. Required with the former and strongly advised with the latter: without it the name is every cell concatenated, repeated for every row."
|
|
11732
|
+
},
|
|
11733
|
+
{
|
|
11734
|
+
name: "rowActivatable",
|
|
11735
|
+
type: "boolean",
|
|
11736
|
+
default: "false",
|
|
11737
|
+
description: 'The row ACTIVATES something that is not a route \u2014 a modal, a selection. Renders a real `<button>` in the first cell, stretched over the row the same way `rowHref` does, rather than `role="button"` on the `<tr>`, which would make every cell presentational and destroy the table\'s grid semantics. Mutually exclusive with `rowHref`/`rowTo` \u2014 dev builds warn.'
|
|
11738
|
+
},
|
|
11739
|
+
{
|
|
11740
|
+
name: "expandedRow",
|
|
11741
|
+
type: "string | number | null",
|
|
11742
|
+
description: "Key of the row whose detail panel is open, matched against the identity `rowKey` resolves."
|
|
11191
11743
|
}
|
|
11192
11744
|
],
|
|
11193
11745
|
events: [
|
|
@@ -11195,6 +11747,11 @@ var treeui_catalog_default = {
|
|
|
11195
11747
|
name: "sort",
|
|
11196
11748
|
description: "Emitted when a sortable column header is clicked.",
|
|
11197
11749
|
payload: "TTableSortState"
|
|
11750
|
+
},
|
|
11751
|
+
{
|
|
11752
|
+
name: "row-activate",
|
|
11753
|
+
description: "Emitted when an activatable row is activated without navigating \u2014 see `rowActivatable`.",
|
|
11754
|
+
payload: "[row: Record<string, unknown>, index: number]"
|
|
11198
11755
|
}
|
|
11199
11756
|
],
|
|
11200
11757
|
slots: [
|
|
@@ -11209,6 +11766,10 @@ var treeui_catalog_default = {
|
|
|
11209
11766
|
{
|
|
11210
11767
|
name: "empty",
|
|
11211
11768
|
description: "Content shown when rows array is empty."
|
|
11769
|
+
},
|
|
11770
|
+
{
|
|
11771
|
+
name: "detail",
|
|
11772
|
+
description: "Detail panel for the expanded row, rendered as a `<tr>` adjacent to its own row. Receives `{ row, index }`."
|
|
11212
11773
|
}
|
|
11213
11774
|
],
|
|
11214
11775
|
a11y: [
|
|
@@ -11219,7 +11780,11 @@ var treeui_catalog_default = {
|
|
|
11219
11780
|
"keyboard: Sortable headers are focusable and activated with Enter or Space.",
|
|
11220
11781
|
"scope: col on all th elements."
|
|
11221
11782
|
],
|
|
11222
|
-
behavior: [
|
|
11783
|
+
behavior: [
|
|
11784
|
+
'roles_are_declared_rather_than_implied: `role` is on the table, both rowgroups, every row, every column header and every cell. Each is the element\'s own implicit role, so nothing changes while `display: table` holds \u2014 they exist to survive stacked mode, where `display: block` drops the implicit table semantics in several screen readers and the block would be announced as a run of unrelated text. Measured in the accessibility tree: a stacked cell reads as "Saldo real R$ 1.284,30", carrying its column.',
|
|
11785
|
+
"containment_is_scoped_to_tables_that_use_it: `container-type: inline-size` applies `contain: layout inline-size style`, so it is set only on a wrapper carrying a `stack-below` modifier rather than on every table in the library.",
|
|
11786
|
+
"a_row_link_covers_the_whole_block: Outside stacked mode every cell after the first is raised above the stretched-link overlay, because those are neighbouring columns and one may hold a button. Stacked, those same cells are plain text under the title, and raising them punched a hole in the link. Inside the container query only cells that actually contain something focusable are raised \u2014 and never the first, which holds the overlay: positioning it makes it the overlay's containing block, and `inset: 0` then covers that cell alone."
|
|
11787
|
+
],
|
|
11223
11788
|
selection: {
|
|
11224
11789
|
keywords: [
|
|
11225
11790
|
"table",
|
|
@@ -11254,7 +11819,9 @@ var treeui_catalog_default = {
|
|
|
11254
11819
|
],
|
|
11255
11820
|
practices: [
|
|
11256
11821
|
"interaction-feedback",
|
|
11257
|
-
"
|
|
11822
|
+
"accessible-by-default",
|
|
11823
|
+
"state-clarity",
|
|
11824
|
+
"content-alignment"
|
|
11258
11825
|
]
|
|
11259
11826
|
},
|
|
11260
11827
|
{
|
|
@@ -11274,7 +11841,7 @@ var treeui_catalog_default = {
|
|
|
11274
11841
|
name: "modelValue",
|
|
11275
11842
|
type: "T",
|
|
11276
11843
|
default: "undefined",
|
|
11277
|
-
note: "The value of the currently active tab; use with v-model. Generic over `T extends string`, so a `ref<'overview' | 'logs'>` keeps its literal union instead of being widened to `string` \u2014
|
|
11844
|
+
note: "The value of the currently active tab; use with v-model. Generic over `T extends string`, so a `ref<'overview' | 'logs'>` keeps its literal union instead of being widened to `string` \u2014 widening makes the binding an error under `strictTemplates`, with no correct way to write it.\n"
|
|
11278
11845
|
},
|
|
11279
11846
|
{
|
|
11280
11847
|
name: "defaultValue",
|
|
@@ -11324,6 +11891,7 @@ var treeui_catalog_default = {
|
|
|
11324
11891
|
"aria_controls_aria_labelledby_pairing: true"
|
|
11325
11892
|
],
|
|
11326
11893
|
behavior: [
|
|
11894
|
+
"overflowing_tabs_scroll_within_their_own_strip: `.t-tabs__list` is `overflow-x: auto` with `overscroll-behavior-x: contain`. Tabs that did not fit pushed the PAGE sideways, which moves every other element on screen to solve a problem belonging to one component. TTabList scrolls the active tab into view whenever the active value changes, so a tab reached by keyboard or restored from a model value is never left off-strip.",
|
|
11327
11895
|
"arrow_left_right_moves_focus: true",
|
|
11328
11896
|
"home_focuses_first_tab: true",
|
|
11329
11897
|
"end_focuses_last_tab: true",
|
|
@@ -11363,7 +11931,9 @@ var treeui_catalog_default = {
|
|
|
11363
11931
|
"router-backed-tabs"
|
|
11364
11932
|
],
|
|
11365
11933
|
practices: [
|
|
11366
|
-
"interaction-feedback"
|
|
11934
|
+
"interaction-feedback",
|
|
11935
|
+
"accessible-by-default",
|
|
11936
|
+
"content-alignment"
|
|
11367
11937
|
]
|
|
11368
11938
|
},
|
|
11369
11939
|
{
|
|
@@ -11701,6 +12271,17 @@ var treeui_catalog_default = {
|
|
|
11701
12271
|
],
|
|
11702
12272
|
note: "Break axis for a string with no break opportunity \u2014 an id, ARN, API key or hash is one long word, so it overflows its box. `truncate` is the wrong answer when the string IS what the reader came to copy: an ellipsis makes an id useless. `anywhere` breaks at any character (and sets `min-inline-size: 0`, without which a flex or grid child still refuses to shrink below its longest word and never breaks); `break-word` only breaks a word that would otherwise overflow. Ignored when `truncate` is set.\n"
|
|
11703
12273
|
},
|
|
12274
|
+
{
|
|
12275
|
+
name: "align",
|
|
12276
|
+
type: "TTextAlign",
|
|
12277
|
+
default: "undefined",
|
|
12278
|
+
values: [
|
|
12279
|
+
"start",
|
|
12280
|
+
"center",
|
|
12281
|
+
"end"
|
|
12282
|
+
],
|
|
12283
|
+
note: "How the LINES sit inside the box, which is the other half of `TStack align` \u2014 that one centres the box, and a centred box only looks centred while it is narrow: at full width the paragraph inside reads left-aligned. Renders block, because `text-align` does nothing on an inline box that shrink-wraps its content. Logical values, so `start`/`end` follow the writing direction. Combined with `measure`, `center` also centres the capped block itself.\n"
|
|
12284
|
+
},
|
|
11704
12285
|
{
|
|
11705
12286
|
name: "balance",
|
|
11706
12287
|
type: "boolean",
|
|
@@ -11741,6 +12322,7 @@ var treeui_catalog_default = {
|
|
|
11741
12322
|
"Choose `as` to convey the correct semantics (e.g. headings via h1\u2013h6); TText adds only visual styling."
|
|
11742
12323
|
],
|
|
11743
12324
|
behavior: [
|
|
12325
|
+
'the_wrap_axis_outranks_preserve_whitespace: `.t-text.t-text--wrap-anywhere` is qualified with `.t-text` so it matches the (0,2,0) specificity of `.t-text.is-pre-wrap`, and wins by order. Without it `preserveWhitespace` silently downgraded `wrap="anywhere"` to `break-word`, which is the one thing `anywhere` exists to do differently: only `anywhere` reduces the min-content.',
|
|
11744
12326
|
"semantic_element_controlled_by_as: true",
|
|
11745
12327
|
"token_driven_size_tone_weight: true",
|
|
11746
12328
|
"truncate_takes_precedence_over_preserve_whitespace: true"
|
|
@@ -11762,6 +12344,7 @@ var treeui_catalog_default = {
|
|
|
11762
12344
|
practices: [
|
|
11763
12345
|
"accessible-by-default",
|
|
11764
12346
|
"predictable-api",
|
|
12347
|
+
"content-alignment",
|
|
11765
12348
|
"token-driven"
|
|
11766
12349
|
]
|
|
11767
12350
|
},
|
|
@@ -11778,6 +12361,12 @@ var treeui_catalog_default = {
|
|
|
11778
12361
|
storyTitle: "Components/Data Entry/Textarea",
|
|
11779
12362
|
manifestFile: "docs/ai/COMPONENTS/textarea.yaml",
|
|
11780
12363
|
props: [
|
|
12364
|
+
{
|
|
12365
|
+
name: "spellcheck",
|
|
12366
|
+
type: "boolean",
|
|
12367
|
+
default: "undefined",
|
|
12368
|
+
description: 'A real `<textarea>` attribute that the declared surface was missing. It matters most with `family="mono"`: a JSON or config editor wants the spell-checker to stop underlining keys, ARNs and identifiers.'
|
|
12369
|
+
},
|
|
11781
12370
|
{
|
|
11782
12371
|
name: "modelValue",
|
|
11783
12372
|
type: "string",
|
|
@@ -11851,7 +12440,7 @@ var treeui_catalog_default = {
|
|
|
11851
12440
|
"sans",
|
|
11852
12441
|
"mono"
|
|
11853
12442
|
],
|
|
11854
|
-
note: "Font family of the editable content, same vocabulary as TText. `mono` is for machine text \u2014 JSON, a policy document, a payload \u2014 which otherwise
|
|
12443
|
+
note: "Font family of the editable content, same vocabulary as TText. `mono` is for machine text \u2014 JSON, a policy document, a payload \u2014 which otherwise needs a one-off `.mono` font-family rule in product CSS. Applied to the `<textarea>`, not the label wrapper, which also holds the loading spinner.\n"
|
|
11855
12444
|
}
|
|
11856
12445
|
],
|
|
11857
12446
|
events: [
|
|
@@ -11951,6 +12540,7 @@ var treeui_catalog_default = {
|
|
|
11951
12540
|
"timestamp_uses_time_element_when_provided: true"
|
|
11952
12541
|
],
|
|
11953
12542
|
behavior: [
|
|
12543
|
+
"content_stays_inside_the_container: `.t-timeline` and `.t-timeline__content` declare `grid-template-columns: minmax(0, 1fr)`, and the title and description carry `overflow-wrap: anywhere`. Together they stop an unbreakable string from setting the column's min-content and carrying the whole entry across the container.",
|
|
11954
12544
|
"items_render_in_order_given: true",
|
|
11955
12545
|
"line_hidden_on_last_item: true",
|
|
11956
12546
|
"marker_tone_defaults_to_neutral: true"
|
|
@@ -11966,7 +12556,9 @@ var treeui_catalog_default = {
|
|
|
11966
12556
|
notes: []
|
|
11967
12557
|
},
|
|
11968
12558
|
recipes: [],
|
|
11969
|
-
practices: [
|
|
12559
|
+
practices: [
|
|
12560
|
+
"content-alignment"
|
|
12561
|
+
]
|
|
11970
12562
|
},
|
|
11971
12563
|
{
|
|
11972
12564
|
name: "TToast",
|
|
@@ -11981,6 +12573,12 @@ var treeui_catalog_default = {
|
|
|
11981
12573
|
storyTitle: "Components/Feedback/Toast",
|
|
11982
12574
|
manifestFile: "docs/ai/COMPONENTS/toast.yaml",
|
|
11983
12575
|
props: [
|
|
12576
|
+
{
|
|
12577
|
+
name: "closeLabel",
|
|
12578
|
+
type: "string",
|
|
12579
|
+
default: "Dismiss notification",
|
|
12580
|
+
description: "Accessible name for the dismiss button, on `TToastProvider` as the instance default and on a single toast's options to override it. It was hard-coded English, which left the toast's only control unreadable to a screen reader in any other language."
|
|
12581
|
+
},
|
|
11984
12582
|
{
|
|
11985
12583
|
name: "toast",
|
|
11986
12584
|
type: "ToastItem",
|
|
@@ -12040,6 +12638,7 @@ var treeui_catalog_default = {
|
|
|
12040
12638
|
"confirm-destructive-action"
|
|
12041
12639
|
],
|
|
12042
12640
|
practices: [
|
|
12641
|
+
"accessible-by-default",
|
|
12043
12642
|
"token-driven"
|
|
12044
12643
|
]
|
|
12045
12644
|
},
|
|
@@ -12060,7 +12659,7 @@ var treeui_catalog_default = {
|
|
|
12060
12659
|
name: "modelValue",
|
|
12061
12660
|
type: "TToggleGroupModel<T, M> \u2014 `T` in single mode, `T[]` in multiple",
|
|
12062
12661
|
default: "undefined",
|
|
12063
|
-
note: "Generic over the option type AND the selection mode, so the model is the type the
|
|
12662
|
+
note: "Generic over the option type AND the selection mode, so the model is the type the binding actually has: `<TToggleGroup v-model=\"view\">` with a `ref<'grid' | 'list'>` binds, and `selectionMode=\"multiple\"` binds a `('grid' | 'list')[]`. It was `string | string[]` in and `string | string[] | undefined` out, which no literal-union ref could bind under `strictTemplates` \u2014 the same defect as TTabs/TInput, and invisible to any build that does not typecheck templates against the published types. `undefined` was never actually emitted.\n"
|
|
12064
12663
|
},
|
|
12065
12664
|
{
|
|
12066
12665
|
name: "options",
|
|
@@ -12121,6 +12720,7 @@ var treeui_catalog_default = {
|
|
|
12121
12720
|
"activation_keys_select_option: true"
|
|
12122
12721
|
],
|
|
12123
12722
|
behavior: [
|
|
12723
|
+
'selected_item_repaints_its_descendants_secondary_text: `.t-toggle-group__item.is-selected` rebinds `--tree-color-text-muted` to `--tree-color-brand-contrast`. Only the inherited colour used to change, so a `TText tone="muted"` in the `#option` slot kept reading the muted token and measured 1.18:1 (light) and 1.09:1 (dark) over the brand fill, where `xs` text needs 4.5:1. Rebinding the token is what keeps a slot the library does not control legible; `brand-contrast` is the only value that clears AA in both themes (5.19:1 / 6.21:1) \u2014 a `color-mix` at 85% still measured 4.18:1.',
|
|
12124
12724
|
"single_and_multiple_modes: true",
|
|
12125
12725
|
"variant_changes_visual_style_only: true",
|
|
12126
12726
|
"visible_option_set_expected: true"
|
|
@@ -12161,7 +12761,9 @@ var treeui_catalog_default = {
|
|
|
12161
12761
|
]
|
|
12162
12762
|
},
|
|
12163
12763
|
recipes: [],
|
|
12164
|
-
practices: [
|
|
12764
|
+
practices: [
|
|
12765
|
+
"accessible-by-default"
|
|
12766
|
+
]
|
|
12165
12767
|
},
|
|
12166
12768
|
{
|
|
12167
12769
|
name: "TTooltip",
|
|
@@ -13310,25 +13912,25 @@ var treeui_catalog_default = {
|
|
|
13310
13912
|
{
|
|
13311
13913
|
cssVar: "--tree-color-status-success",
|
|
13312
13914
|
path: "color.status.success",
|
|
13313
|
-
value: "#
|
|
13915
|
+
value: "#197d36",
|
|
13314
13916
|
category: "color",
|
|
13315
13917
|
derived: false,
|
|
13316
13918
|
description: "Themed semantic color, resolved per [data-tree-theme].",
|
|
13317
13919
|
themeValues: {
|
|
13318
|
-
light: "#
|
|
13319
|
-
dark: "#
|
|
13920
|
+
light: "#197d36",
|
|
13921
|
+
dark: "#5bae5e"
|
|
13320
13922
|
}
|
|
13321
13923
|
},
|
|
13322
13924
|
{
|
|
13323
13925
|
cssVar: "--tree-color-status-warning",
|
|
13324
13926
|
path: "color.status.warning",
|
|
13325
|
-
value: "#
|
|
13927
|
+
value: "#946300",
|
|
13326
13928
|
category: "color",
|
|
13327
13929
|
derived: false,
|
|
13328
13930
|
description: "Themed semantic color, resolved per [data-tree-theme].",
|
|
13329
13931
|
themeValues: {
|
|
13330
|
-
light: "#
|
|
13331
|
-
dark: "#
|
|
13932
|
+
light: "#946300",
|
|
13933
|
+
dark: "#c99227"
|
|
13332
13934
|
}
|
|
13333
13935
|
},
|
|
13334
13936
|
{
|
|
@@ -13634,25 +14236,25 @@ var treeui_catalog_default = {
|
|
|
13634
14236
|
{
|
|
13635
14237
|
cssVar: "--tree-color-status-success-hover",
|
|
13636
14238
|
path: "color.status.success-hover",
|
|
13637
|
-
value: "#
|
|
14239
|
+
value: "#15672c",
|
|
13638
14240
|
category: "color",
|
|
13639
14241
|
derived: true,
|
|
13640
14242
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13641
14243
|
themeValues: {
|
|
13642
|
-
light: "#
|
|
13643
|
-
dark: "#
|
|
14244
|
+
light: "#15672c",
|
|
14245
|
+
dark: "#79bd7b"
|
|
13644
14246
|
}
|
|
13645
14247
|
},
|
|
13646
14248
|
{
|
|
13647
14249
|
cssVar: "--tree-color-status-success-press",
|
|
13648
14250
|
path: "color.status.success-press",
|
|
13649
|
-
value: "#
|
|
14251
|
+
value: "#115525",
|
|
13650
14252
|
category: "color",
|
|
13651
14253
|
derived: true,
|
|
13652
14254
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13653
14255
|
themeValues: {
|
|
13654
|
-
light: "#
|
|
13655
|
-
dark: "#
|
|
14256
|
+
light: "#115525",
|
|
14257
|
+
dark: "#8fc892"
|
|
13656
14258
|
}
|
|
13657
14259
|
},
|
|
13658
14260
|
{
|
|
@@ -13664,31 +14266,31 @@ var treeui_catalog_default = {
|
|
|
13664
14266
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13665
14267
|
themeValues: {
|
|
13666
14268
|
light: "#dfede3",
|
|
13667
|
-
dark: "#
|
|
14269
|
+
dark: "#2a3a35"
|
|
13668
14270
|
}
|
|
13669
14271
|
},
|
|
13670
14272
|
{
|
|
13671
14273
|
cssVar: "--tree-color-status-success-soft-hover",
|
|
13672
14274
|
path: "color.status.success-soft-hover",
|
|
13673
|
-
value: "#
|
|
14275
|
+
value: "#c3ddcb",
|
|
13674
14276
|
category: "color",
|
|
13675
14277
|
derived: true,
|
|
13676
14278
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13677
14279
|
themeValues: {
|
|
13678
|
-
light: "#
|
|
13679
|
-
dark: "#
|
|
14280
|
+
light: "#c3ddcb",
|
|
14281
|
+
dark: "#314a3b"
|
|
13680
14282
|
}
|
|
13681
14283
|
},
|
|
13682
14284
|
{
|
|
13683
14285
|
cssVar: "--tree-color-status-success-border",
|
|
13684
14286
|
path: "color.status.success-border",
|
|
13685
|
-
value: "#
|
|
14287
|
+
value: "#419359",
|
|
13686
14288
|
category: "color",
|
|
13687
14289
|
derived: true,
|
|
13688
14290
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13689
14291
|
themeValues: {
|
|
13690
|
-
light: "#
|
|
13691
|
-
dark: "#
|
|
14292
|
+
light: "#419359",
|
|
14293
|
+
dark: "#4f9154"
|
|
13692
14294
|
}
|
|
13693
14295
|
},
|
|
13694
14296
|
{
|
|
@@ -13706,49 +14308,49 @@ var treeui_catalog_default = {
|
|
|
13706
14308
|
{
|
|
13707
14309
|
cssVar: "--tree-color-status-success-on-soft",
|
|
13708
14310
|
path: "color.status.success-on-soft",
|
|
13709
|
-
value: "#
|
|
14311
|
+
value: "#187733",
|
|
13710
14312
|
category: "color",
|
|
13711
14313
|
derived: true,
|
|
13712
14314
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13713
14315
|
themeValues: {
|
|
13714
|
-
light: "#
|
|
13715
|
-
dark: "#
|
|
14316
|
+
light: "#187733",
|
|
14317
|
+
dark: "#63b266"
|
|
13716
14318
|
}
|
|
13717
14319
|
},
|
|
13718
14320
|
{
|
|
13719
14321
|
cssVar: "--tree-color-status-success-on-soft-hover",
|
|
13720
14322
|
path: "color.status.success-on-soft-hover",
|
|
13721
|
-
value: "#
|
|
14323
|
+
value: "#156b2e",
|
|
13722
14324
|
category: "color",
|
|
13723
14325
|
derived: true,
|
|
13724
14326
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13725
14327
|
themeValues: {
|
|
13726
|
-
light: "#
|
|
13727
|
-
dark: "#
|
|
14328
|
+
light: "#156b2e",
|
|
14329
|
+
dark: "#80c082"
|
|
13728
14330
|
}
|
|
13729
14331
|
},
|
|
13730
14332
|
{
|
|
13731
14333
|
cssVar: "--tree-color-status-warning-hover",
|
|
13732
14334
|
path: "color.status.warning-hover",
|
|
13733
|
-
value: "#
|
|
14335
|
+
value: "#795100",
|
|
13734
14336
|
category: "color",
|
|
13735
14337
|
derived: true,
|
|
13736
14338
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13737
14339
|
themeValues: {
|
|
13738
|
-
light: "#
|
|
13739
|
-
dark: "#
|
|
14340
|
+
light: "#795100",
|
|
14341
|
+
dark: "#d3a64e"
|
|
13740
14342
|
}
|
|
13741
14343
|
},
|
|
13742
14344
|
{
|
|
13743
14345
|
cssVar: "--tree-color-status-warning-press",
|
|
13744
14346
|
path: "color.status.warning-press",
|
|
13745
|
-
value: "#
|
|
14347
|
+
value: "#654300",
|
|
13746
14348
|
category: "color",
|
|
13747
14349
|
derived: true,
|
|
13748
14350
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13749
14351
|
themeValues: {
|
|
13750
|
-
light: "#
|
|
13751
|
-
dark: "#
|
|
14352
|
+
light: "#654300",
|
|
14353
|
+
dark: "#dab56c"
|
|
13752
14354
|
}
|
|
13753
14355
|
},
|
|
13754
14356
|
{
|
|
@@ -13778,13 +14380,13 @@ var treeui_catalog_default = {
|
|
|
13778
14380
|
{
|
|
13779
14381
|
cssVar: "--tree-color-status-warning-border",
|
|
13780
14382
|
path: "color.status.warning-border",
|
|
13781
|
-
value: "#
|
|
14383
|
+
value: "#a67e2c",
|
|
13782
14384
|
category: "color",
|
|
13783
14385
|
derived: true,
|
|
13784
14386
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13785
14387
|
themeValues: {
|
|
13786
|
-
light: "#
|
|
13787
|
-
dark: "#
|
|
14388
|
+
light: "#a67e2c",
|
|
14389
|
+
dark: "#a57b29"
|
|
13788
14390
|
}
|
|
13789
14391
|
},
|
|
13790
14392
|
{
|
|
@@ -13802,25 +14404,25 @@ var treeui_catalog_default = {
|
|
|
13802
14404
|
{
|
|
13803
14405
|
cssVar: "--tree-color-status-warning-on-soft",
|
|
13804
14406
|
path: "color.status.warning-on-soft",
|
|
13805
|
-
value: "#
|
|
14407
|
+
value: "#8d5e00",
|
|
13806
14408
|
category: "color",
|
|
13807
14409
|
derived: true,
|
|
13808
14410
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13809
14411
|
themeValues: {
|
|
13810
|
-
light: "#
|
|
13811
|
-
dark: "#
|
|
14412
|
+
light: "#8d5e00",
|
|
14413
|
+
dark: "#cc9732"
|
|
13812
14414
|
}
|
|
13813
14415
|
},
|
|
13814
14416
|
{
|
|
13815
14417
|
cssVar: "--tree-color-status-warning-on-soft-hover",
|
|
13816
14418
|
path: "color.status.warning-on-soft-hover",
|
|
13817
|
-
value: "#
|
|
14419
|
+
value: "#7f5500",
|
|
13818
14420
|
category: "color",
|
|
13819
14421
|
derived: true,
|
|
13820
14422
|
description: "Themed semantic color, resolved per [data-tree-theme]. Derived by the library from the semantic layer \u2014 read it, do not override it.",
|
|
13821
14423
|
themeValues: {
|
|
13822
|
-
light: "#
|
|
13823
|
-
dark: "#
|
|
14424
|
+
light: "#7f5500",
|
|
14425
|
+
dark: "#d5ab58"
|
|
13824
14426
|
}
|
|
13825
14427
|
},
|
|
13826
14428
|
{
|