@ttoss/fsl-ui 0.2.4 → 0.2.6

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.
Files changed (134) hide show
  1. package/README.md +1 -1
  2. package/dist/components/AppShell/AppShell.cjs +124 -0
  3. package/dist/components/AppShell/AppShell.d.cts +74 -0
  4. package/dist/components/AppShell/AppShell.d.mts +74 -0
  5. package/dist/components/AppShell/AppShell.mjs +123 -0
  6. package/dist/components/Badge/Badge.cjs +61 -0
  7. package/dist/components/Badge/Badge.d.cts +56 -0
  8. package/dist/components/Badge/Badge.d.mts +56 -0
  9. package/dist/components/Badge/Badge.mjs +60 -0
  10. package/dist/components/Box/Box.cjs +114 -0
  11. package/dist/components/Box/Box.d.cts +115 -0
  12. package/dist/components/Box/Box.d.mts +115 -0
  13. package/dist/components/Box/Box.mjs +113 -0
  14. package/dist/components/Breadcrumbs/Breadcrumbs.cjs +1 -1
  15. package/dist/components/Breadcrumbs/Breadcrumbs.mjs +1 -1
  16. package/dist/components/Button/Button.cjs +2 -2
  17. package/dist/components/Button/Button.d.cts +2 -1
  18. package/dist/components/Button/Button.d.mts +2 -1
  19. package/dist/components/Button/Button.mjs +2 -2
  20. package/dist/components/Checkbox/Checkbox.cjs +2 -2
  21. package/dist/components/Checkbox/Checkbox.mjs +2 -2
  22. package/dist/components/CheckboxGroup/CheckboxGroup.cjs +1 -1
  23. package/dist/components/CheckboxGroup/CheckboxGroup.mjs +1 -1
  24. package/dist/components/Code/Code.cjs +69 -0
  25. package/dist/components/Code/Code.d.cts +53 -0
  26. package/dist/components/Code/Code.d.mts +53 -0
  27. package/dist/components/Code/Code.mjs +68 -0
  28. package/dist/components/Container/Container.cjs +65 -0
  29. package/dist/components/Container/Container.d.cts +61 -0
  30. package/dist/components/Container/Container.d.mts +61 -0
  31. package/dist/components/Container/Container.mjs +64 -0
  32. package/dist/components/FileTrigger/FileTrigger.cjs +1 -1
  33. package/dist/components/FileTrigger/FileTrigger.mjs +1 -1
  34. package/dist/components/Grid/Grid.cjs +88 -0
  35. package/dist/components/Grid/Grid.d.cts +87 -0
  36. package/dist/components/Grid/Grid.d.mts +87 -0
  37. package/dist/components/Grid/Grid.mjs +87 -0
  38. package/dist/components/GridList/GridList.cjs +2 -2
  39. package/dist/components/GridList/GridList.mjs +2 -2
  40. package/dist/components/Group/Group.cjs +1 -1
  41. package/dist/components/Group/Group.mjs +1 -1
  42. package/dist/components/Heading/Heading.cjs +78 -0
  43. package/dist/components/Heading/Heading.d.cts +63 -0
  44. package/dist/components/Heading/Heading.d.mts +63 -0
  45. package/dist/components/Heading/Heading.mjs +77 -0
  46. package/dist/components/Icon/Icon.cjs +2 -1
  47. package/dist/components/Icon/Icon.d.cts +59 -0
  48. package/dist/components/Icon/Icon.d.mts +59 -0
  49. package/dist/components/Icon/Icon.mjs +1 -1
  50. package/dist/components/Icon/glyphs.cjs +37 -10
  51. package/dist/components/Icon/glyphs.mjs +34 -10
  52. package/dist/components/Icon/intents.cjs +32 -0
  53. package/dist/components/Icon/intents.d.cts +33 -0
  54. package/dist/components/Icon/intents.d.mts +33 -0
  55. package/dist/components/Icon/intents.mjs +32 -0
  56. package/dist/components/Link/Link.cjs +1 -1
  57. package/dist/components/Link/Link.mjs +1 -1
  58. package/dist/components/ListBox/ListBox.cjs +1 -1
  59. package/dist/components/ListBox/ListBox.mjs +1 -1
  60. package/dist/components/Meter/Meter.cjs +11 -1
  61. package/dist/components/Meter/Meter.mjs +11 -1
  62. package/dist/components/NumberField/NumberField.cjs +2 -2
  63. package/dist/components/NumberField/NumberField.mjs +2 -2
  64. package/dist/components/ProgressBar/ProgressBar.cjs +1 -1
  65. package/dist/components/ProgressBar/ProgressBar.mjs +1 -1
  66. package/dist/components/RadioGroup/RadioGroup.cjs +2 -2
  67. package/dist/components/RadioGroup/RadioGroup.mjs +2 -2
  68. package/dist/components/Select/Select.cjs +2 -2
  69. package/dist/components/Select/Select.mjs +2 -2
  70. package/dist/components/Separator/Separator.cjs +1 -1
  71. package/dist/components/Separator/Separator.mjs +1 -1
  72. package/dist/components/Slider/Slider.cjs +1 -1
  73. package/dist/components/Slider/Slider.mjs +1 -1
  74. package/dist/components/Stack/Stack.cjs +89 -0
  75. package/dist/components/Stack/Stack.d.cts +75 -0
  76. package/dist/components/Stack/Stack.d.mts +75 -0
  77. package/dist/components/Stack/Stack.mjs +88 -0
  78. package/dist/components/Surface/Surface.cjs +84 -0
  79. package/dist/components/Surface/Surface.d.cts +72 -0
  80. package/dist/components/Surface/Surface.d.mts +72 -0
  81. package/dist/components/Surface/Surface.mjs +83 -0
  82. package/dist/components/Switch/Switch.cjs +3 -3
  83. package/dist/components/Switch/Switch.d.cts +1 -1
  84. package/dist/components/Switch/Switch.d.mts +1 -1
  85. package/dist/components/Switch/Switch.mjs +3 -3
  86. package/dist/components/Table/Table.cjs +248 -0
  87. package/dist/components/Table/Table.d.cts +128 -0
  88. package/dist/components/Table/Table.d.mts +128 -0
  89. package/dist/components/Table/Table.mjs +239 -0
  90. package/dist/components/Tabs/Tabs.cjs +71 -28
  91. package/dist/components/Tabs/Tabs.d.cts +0 -17
  92. package/dist/components/Tabs/Tabs.d.mts +0 -17
  93. package/dist/components/Tabs/Tabs.mjs +69 -28
  94. package/dist/components/Text/Text.cjs +70 -0
  95. package/dist/components/Text/Text.d.cts +89 -0
  96. package/dist/components/Text/Text.d.mts +89 -0
  97. package/dist/components/Text/Text.mjs +69 -0
  98. package/dist/components/Toast/Toast.cjs +1 -1
  99. package/dist/components/Toast/Toast.mjs +1 -1
  100. package/dist/components/ToggleButton/ToggleButton.cjs +2 -2
  101. package/dist/components/ToggleButton/ToggleButton.mjs +2 -2
  102. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.cjs +1 -1
  103. package/dist/components/ToggleButtonGroup/ToggleButtonGroup.mjs +1 -1
  104. package/dist/components/Toolbar/Toolbar.cjs +1 -1
  105. package/dist/components/Toolbar/Toolbar.mjs +1 -1
  106. package/dist/composites/Accordion/Accordion.cjs +14 -9
  107. package/dist/composites/Accordion/Accordion.mjs +14 -9
  108. package/dist/composites/Dialog/Dialog.cjs +1 -1
  109. package/dist/composites/Dialog/Dialog.mjs +1 -1
  110. package/dist/composites/Disclosure/Disclosure.cjs +14 -9
  111. package/dist/composites/Disclosure/Disclosure.mjs +14 -9
  112. package/dist/composites/Form/Form.cjs +1 -1
  113. package/dist/composites/Form/Form.mjs +1 -1
  114. package/dist/composites/Menu/Menu.cjs +2 -2
  115. package/dist/composites/Menu/Menu.mjs +2 -2
  116. package/dist/composites/Popover/Popover.cjs +1 -1
  117. package/dist/composites/Popover/Popover.mjs +1 -1
  118. package/dist/composites/SearchField/SearchField.cjs +2 -2
  119. package/dist/composites/SearchField/SearchField.mjs +2 -2
  120. package/dist/composites/TagGroup/TagGroup.cjs +2 -2
  121. package/dist/composites/TagGroup/TagGroup.mjs +2 -2
  122. package/dist/composites/TextArea/TextArea.cjs +2 -2
  123. package/dist/composites/TextArea/TextArea.mjs +2 -2
  124. package/dist/composites/TextField/TextField.cjs +2 -2
  125. package/dist/composites/TextField/TextField.mjs +2 -2
  126. package/dist/composites/Tooltip/Tooltip.cjs +1 -1
  127. package/dist/composites/Tooltip/Tooltip.mjs +1 -1
  128. package/dist/index.cjs +46 -0
  129. package/dist/index.d.cts +14 -1
  130. package/dist/index.d.mts +14 -1
  131. package/dist/index.mjs +14 -1
  132. package/llms.txt +51 -8
  133. package/package.json +4 -4
  134. package/src/tokens/CONTRACT.md +28 -10
@@ -0,0 +1,239 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ import { focusRingOutline } from "../../tokens/focusRing.mjs";
3
+ import { resolveInteractiveStyle } from "../../tokens/resolveInteractiveStyle.mjs";
4
+ import { Icon } from "../Icon/Icon.mjs";
5
+ import { vars } from "@ttoss/fsl-theme/vars";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Cell, Column, Row, Table, TableBody, TableHeader } from "react-aria-components";
8
+
9
+ //#region src/components/Table/Table.tsx
10
+ /** Formal semantic identity — Table root (Collection entity, surface). */
11
+ var tableMeta = {
12
+ displayName: "Table",
13
+ entity: "Collection",
14
+ structure: "root"
15
+ };
16
+ /** Formal semantic identity — TableColumn header (Collection `title` role). */
17
+ var tableColumnMeta = {
18
+ displayName: "TableColumn",
19
+ entity: "Collection",
20
+ structure: "title"
21
+ };
22
+ /** Formal semantic identity — TableRow (Selection entity, selectable row). */
23
+ var tableRowMeta = {
24
+ displayName: "TableRow",
25
+ entity: "Selection",
26
+ structure: "item",
27
+ composition: "selection"
28
+ };
29
+ /** Formal semantic identity — TableCell (Collection `content` role). */
30
+ var tableCellMeta = {
31
+ displayName: "TableCell",
32
+ entity: "Collection",
33
+ structure: "content"
34
+ };
35
+ /**
36
+ * A semantic data table built on React Aria's `Table` — column headers,
37
+ * keyboard grid navigation, sorting, and row selection.
38
+ *
39
+ * Per ADR-007 the CONTAINER is Entity = Collection (an `informational`
40
+ * surface) and each `TableRow` is Entity = Selection (`input` chrome, the
41
+ * `selected` State). Compose `TableHeader` + `TableColumn` for the header
42
+ * and `TableBody` + `TableRow` + `TableCell` for the data. Sorting is
43
+ * controlled via `sortDescriptor`/`onSortChange` with `allowsSorting` on the
44
+ * sortable columns. Row selection uses React Aria's `selectionMode`;
45
+ * clicking a row toggles it (there is no checkbox column yet — it ships
46
+ * when a consumer demands bulk actions).
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * <Table aria-label="Team" sortDescriptor={sort} onSortChange={setSort}>
51
+ * <TableHeader>
52
+ * <TableColumn id="name" isRowHeader allowsSorting>Name</TableColumn>
53
+ * <TableColumn id="role">Role</TableColumn>
54
+ * </TableHeader>
55
+ * <TableBody>
56
+ * <TableRow id="ada">
57
+ * <TableCell>Ada Lovelace</TableCell>
58
+ * <TableCell>Admin</TableCell>
59
+ * </TableRow>
60
+ * </TableBody>
61
+ * </Table>
62
+ * ```
63
+ */
64
+ var Table$1 = props => {
65
+ const surface = vars.colors.informational.primary;
66
+ return /* @__PURE__ */jsx(Table, {
67
+ ...props,
68
+ "data-scope": "table",
69
+ "data-part": "root",
70
+ style: {
71
+ boxSizing: "border-box",
72
+ inlineSize: "100%",
73
+ borderCollapse: "separate",
74
+ borderSpacing: 0,
75
+ borderRadius: vars.radii.surface,
76
+ borderWidth: vars.border.outline.surface.width,
77
+ borderStyle: vars.border.outline.surface.style,
78
+ borderColor: surface?.border?.default ?? "transparent",
79
+ backgroundColor: surface?.background?.default,
80
+ color: surface?.text?.default
81
+ }
82
+ });
83
+ };
84
+ Table$1.displayName = tableMeta.displayName;
85
+ /**
86
+ * The header row group. An internal frame part — place `TableColumn`s
87
+ * inside it.
88
+ */
89
+ var TableHeader$1 = props => {
90
+ return /* @__PURE__ */jsx(TableHeader, {
91
+ ...props,
92
+ "data-scope": "table",
93
+ "data-part": "header"
94
+ });
95
+ };
96
+ TableHeader$1.displayName = "TableHeader";
97
+ /**
98
+ * A column header (Collection `title` role). With `allowsSorting`, React
99
+ * Aria makes it a keyboard-operable sort control (`aria-sort` included) and
100
+ * the current direction renders as an arrow Icon
101
+ * (`action.sortAscending` / `action.sortDescending`).
102
+ *
103
+ * Set `isRowHeader` on the column whose cells name the row for assistive
104
+ * technology.
105
+ */
106
+ var TableColumn = ({
107
+ children,
108
+ ...props
109
+ }) => {
110
+ const colors = vars.colors.informational.muted;
111
+ return /* @__PURE__ */jsx(Column, {
112
+ ...props,
113
+ "data-scope": "table",
114
+ "data-part": "title",
115
+ style: ({
116
+ allowsSorting,
117
+ isHovered,
118
+ isFocusVisible
119
+ }) => {
120
+ return {
121
+ boxSizing: "border-box",
122
+ textAlign: "start",
123
+ paddingBlock: vars.spacing.inset.control.sm,
124
+ paddingInline: vars.spacing.inset.control.md,
125
+ ...vars.text.label.sm,
126
+ cursor: allowsSorting ? "pointer" : void 0,
127
+ transitionProperty: "color",
128
+ transitionDuration: vars.motion.feedback.duration,
129
+ transitionTimingFunction: vars.motion.feedback.easing,
130
+ color: allowsSorting ? resolveInteractiveStyle(colors?.text, {
131
+ isHovered
132
+ }) : colors?.text?.default,
133
+ borderBlockEndWidth: vars.border.divider.width,
134
+ borderBlockEndStyle: vars.border.divider.style,
135
+ borderBlockEndColor: colors?.border?.default ?? "transparent",
136
+ outline: focusRingOutline(isFocusVisible),
137
+ outlineOffset: "-2px"
138
+ };
139
+ },
140
+ children: ({
141
+ allowsSorting,
142
+ sortDirection
143
+ }) => {
144
+ return /* @__PURE__ */jsxs("span", {
145
+ style: {
146
+ display: "inline-flex",
147
+ alignItems: "center",
148
+ gap: vars.spacing.gap.inline.sm
149
+ },
150
+ children: [children, allowsSorting && sortDirection && /* @__PURE__ */jsx(Icon, {
151
+ intent: sortDirection === "ascending" ? "action.sortAscending" : "action.sortDescending",
152
+ size: "sm"
153
+ })]
154
+ });
155
+ }
156
+ });
157
+ };
158
+ TableColumn.displayName = tableColumnMeta.displayName;
159
+ /** The data row group. An internal frame part — place `TableRow`s inside. */
160
+ var TableBody$1 = props => {
161
+ return /* @__PURE__ */jsx(TableBody, {
162
+ ...props,
163
+ "data-scope": "table",
164
+ "data-part": "body"
165
+ });
166
+ };
167
+ TableBody$1.displayName = "TableBody";
168
+ /**
169
+ * A single data row. Entity = Selection → reads `vars.colors.input.*` and
170
+ * surfaces the `selected` State when the parent Table has a `selectionMode`.
171
+ */
172
+ var TableRow = props => {
173
+ const c = vars.colors.input.primary;
174
+ return /* @__PURE__ */jsx(Row, {
175
+ ...props,
176
+ "data-scope": "table",
177
+ "data-part": "item",
178
+ style: ({
179
+ isSelected,
180
+ isHovered,
181
+ isFocusVisible,
182
+ isDisabled,
183
+ selectionMode
184
+ }) => {
185
+ return {
186
+ boxSizing: "border-box",
187
+ blockSize: vars.sizing.hit,
188
+ cursor: selectionMode === "none" ? void 0 : isDisabled ? "not-allowed" : "pointer",
189
+ opacity: isDisabled ? vars.opacity.disabled : void 0,
190
+ transitionProperty: "background-color, color",
191
+ transitionDuration: vars.motion.feedback.duration,
192
+ transitionTimingFunction: vars.motion.feedback.easing,
193
+ backgroundColor: resolveInteractiveStyle(c?.background, {
194
+ isDisabled,
195
+ isSelected,
196
+ isHovered: isHovered && selectionMode !== "none"
197
+ }),
198
+ color: resolveInteractiveStyle(c?.text, {
199
+ isDisabled,
200
+ isSelected
201
+ }),
202
+ outline: focusRingOutline(isFocusVisible),
203
+ outlineOffset: "-2px"
204
+ };
205
+ }
206
+ });
207
+ };
208
+ TableRow.displayName = tableRowMeta.displayName;
209
+ /**
210
+ * A data cell (Collection `content` role). Focusable during keyboard grid
211
+ * navigation; typography and color inherit from the row.
212
+ */
213
+ var TableCell = props => {
214
+ const colors = vars.colors.informational.muted;
215
+ return /* @__PURE__ */jsx(Cell, {
216
+ ...props,
217
+ "data-scope": "table",
218
+ "data-part": "content",
219
+ style: ({
220
+ isFocusVisible
221
+ }) => {
222
+ return {
223
+ boxSizing: "border-box",
224
+ paddingBlock: vars.spacing.inset.control.sm,
225
+ paddingInline: vars.spacing.inset.control.md,
226
+ ...vars.text.body.sm,
227
+ borderBlockEndWidth: vars.border.divider.width,
228
+ borderBlockEndStyle: vars.border.divider.style,
229
+ borderBlockEndColor: colors?.border?.default ?? "transparent",
230
+ outline: focusRingOutline(isFocusVisible),
231
+ outlineOffset: "-2px"
232
+ };
233
+ }
234
+ });
235
+ };
236
+ TableCell.displayName = tableCellMeta.displayName;
237
+
238
+ //#endregion
239
+ export { Table$1 as Table, TableBody$1 as TableBody, TableCell, TableColumn, TableHeader$1 as TableHeader, TableRow, tableCellMeta, tableColumnMeta, tableMeta, tableRowMeta };
@@ -1,9 +1,12 @@
1
1
  /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
2
3
  const require_focusRing = require('../../tokens/focusRing.cjs');
3
4
  const require_resolveInteractiveStyle = require('../../tokens/resolveInteractiveStyle.cjs');
4
5
  let _ttoss_fsl_theme_vars = require("@ttoss/fsl-theme/vars");
5
- let react_aria_components = require("react-aria-components");
6
6
  let react_jsx_runtime = require("react/jsx-runtime");
7
+ let react_aria_components = require("react-aria-components");
8
+ let react = require("react");
9
+ react = require_runtime.__toESM(react);
7
10
 
8
11
  //#region src/components/Tabs/Tabs.tsx
9
12
  /** Formal semantic identity — Tabs root (Navigation entity). */
@@ -47,21 +50,30 @@ var tabPanelMeta = {
47
50
  * </Tabs>
48
51
  * ```
49
52
  */
53
+ /**
54
+ * Orientation reaches `Tab` through this context — RAC exposes it in
55
+ * `TabList`'s render props but not in `Tab`'s, and the selected-tab
56
+ * indicator must switch edges with the orientation (friction F-003).
57
+ */
58
+ var TabsOrientationContext = react.createContext("horizontal");
50
59
  var Tabs = ({
51
60
  orientation = "horizontal",
52
61
  ...props
53
62
  }) => {
54
- return /* @__PURE__ */(0, react_jsx_runtime.jsx)(react_aria_components.Tabs, {
55
- ...props,
56
- orientation,
57
- "data-scope": "tabs",
58
- "data-part": "root",
59
- style: {
60
- boxSizing: "border-box",
61
- display: "flex",
62
- flexDirection: orientation === "vertical" ? "row" : "column",
63
- gap: _ttoss_fsl_theme_vars.vars.spacing.gap.stack.sm
64
- }
63
+ return /* @__PURE__ */(0, react_jsx_runtime.jsx)(TabsOrientationContext.Provider, {
64
+ value: orientation,
65
+ children: /* @__PURE__ */(0, react_jsx_runtime.jsx)(react_aria_components.Tabs, {
66
+ ...props,
67
+ orientation,
68
+ "data-scope": "tabs",
69
+ "data-part": "root",
70
+ style: {
71
+ boxSizing: "border-box",
72
+ display: "flex",
73
+ flexDirection: orientation === "vertical" ? "row" : "column",
74
+ gap: _ttoss_fsl_theme_vars.vars.spacing.gap.stack.sm
75
+ }
76
+ })
65
77
  });
66
78
  };
67
79
  Tabs.displayName = tabsMeta.displayName;
@@ -74,23 +86,62 @@ var TabList = props => {
74
86
  ...props,
75
87
  "data-scope": "tabs",
76
88
  "data-part": "control",
77
- style: {
78
- boxSizing: "border-box",
79
- display: "flex",
80
- gap: _ttoss_fsl_theme_vars.vars.spacing.gap.inline.sm,
81
- borderBlockEndWidth: _ttoss_fsl_theme_vars.vars.border.divider.width,
82
- borderBlockEndStyle: _ttoss_fsl_theme_vars.vars.border.divider.style,
83
- borderBlockEndColor: _ttoss_fsl_theme_vars.vars.colors.navigation.muted?.border?.default ?? "transparent"
89
+ style: ({
90
+ orientation
91
+ }) => {
92
+ const isVertical = orientation === "vertical";
93
+ return {
94
+ boxSizing: "border-box",
95
+ display: "flex",
96
+ flexDirection: isVertical ? "column" : "row",
97
+ gap: isVertical ? _ttoss_fsl_theme_vars.vars.spacing.gap.stack.sm : _ttoss_fsl_theme_vars.vars.spacing.gap.inline.sm,
98
+ ...(isVertical ? {
99
+ borderInlineEndWidth: _ttoss_fsl_theme_vars.vars.border.divider.width,
100
+ borderInlineEndStyle: _ttoss_fsl_theme_vars.vars.border.divider.style,
101
+ borderInlineEndColor: _ttoss_fsl_theme_vars.vars.colors.navigation.muted?.border?.default ?? "transparent"
102
+ } : {
103
+ borderBlockEndWidth: _ttoss_fsl_theme_vars.vars.border.divider.width,
104
+ borderBlockEndStyle: _ttoss_fsl_theme_vars.vars.border.divider.style,
105
+ borderBlockEndColor: _ttoss_fsl_theme_vars.vars.colors.navigation.muted?.border?.default ?? "transparent"
106
+ })
107
+ };
84
108
  }
85
109
  });
86
110
  };
87
111
  TabList.displayName = tabListMeta.displayName;
88
112
  /**
113
+ * Style for the decorative active-tab indicator line — block-end underline
114
+ * when horizontal, inline-start bar when vertical (F-003).
115
+ */
116
+ var tabIndicatorStyle = orientation => {
117
+ const color = _ttoss_fsl_theme_vars.vars.colors.navigation.primary?.border?.current ?? _ttoss_fsl_theme_vars.vars.colors.navigation.primary?.border?.default;
118
+ const style = _ttoss_fsl_theme_vars.vars.border.outline.control.style;
119
+ if (orientation === "vertical") return {
120
+ position: "absolute",
121
+ insetBlockStart: 0,
122
+ insetBlockEnd: 0,
123
+ insetInlineStart: 0,
124
+ borderInlineStartWidth: _ttoss_fsl_theme_vars.vars.border.outline.selected.width,
125
+ borderInlineStartStyle: style,
126
+ borderInlineStartColor: color
127
+ };
128
+ return {
129
+ position: "absolute",
130
+ insetInlineStart: 0,
131
+ insetInlineEnd: 0,
132
+ insetBlockEnd: 0,
133
+ borderBlockEndWidth: _ttoss_fsl_theme_vars.vars.border.outline.selected.width,
134
+ borderBlockEndStyle: style,
135
+ borderBlockEndColor: color
136
+ };
137
+ };
138
+ /**
89
139
  * A single selectable tab. The selected tab reads the navigation `current`
90
140
  * color and shows an underline indicator; others use hover/default.
91
141
  */
92
142
  var Tab = props => {
93
143
  const colors = _ttoss_fsl_theme_vars.vars.colors.navigation.primary;
144
+ const orientation = react.useContext(TabsOrientationContext);
94
145
  return /* @__PURE__ */(0, react_jsx_runtime.jsx)(react_aria_components.Tab, {
95
146
  ...props,
96
147
  "data-scope": "tabs",
@@ -131,15 +182,7 @@ var Tab = props => {
131
182
  "data-scope": "tabs",
132
183
  "data-part": "indicator",
133
184
  "aria-hidden": true,
134
- style: {
135
- position: "absolute",
136
- insetInlineStart: 0,
137
- insetInlineEnd: 0,
138
- insetBlockEnd: 0,
139
- borderBlockEndWidth: _ttoss_fsl_theme_vars.vars.border.outline.selected.width,
140
- borderBlockEndStyle: _ttoss_fsl_theme_vars.vars.border.outline.control.style,
141
- borderBlockEndColor: _ttoss_fsl_theme_vars.vars.colors.navigation.primary?.border?.current ?? _ttoss_fsl_theme_vars.vars.colors.navigation.primary?.border?.default
142
- }
185
+ style: tabIndicatorStyle(orientation)
143
186
  })]
144
187
  });
145
188
  }
@@ -28,23 +28,6 @@ declare const tabPanelMeta: {
28
28
  };
29
29
  /** Props for the Tabs root. */
30
30
  type TabsProps$1 = Omit<TabsProps, 'style'>;
31
- /**
32
- * A tabbed navigation widget (Navigation entity). Compose with `TabList` +
33
- * `Tab` for the switcher and `TabPanel` for each view. React Aria manages
34
- * selection, arrow-key navigation, and panel association.
35
- *
36
- * @example
37
- * ```tsx
38
- * <Tabs>
39
- * <TabList aria-label="Sections">
40
- * <Tab id="a">Overview</Tab>
41
- * <Tab id="b">Details</Tab>
42
- * </TabList>
43
- * <TabPanel id="a">Overview content</TabPanel>
44
- * <TabPanel id="b">Details content</TabPanel>
45
- * </Tabs>
46
- * ```
47
- */
48
31
  declare const Tabs: {
49
32
  ({
50
33
  orientation,
@@ -28,23 +28,6 @@ declare const tabPanelMeta: {
28
28
  };
29
29
  /** Props for the Tabs root. */
30
30
  type TabsProps$1 = Omit<TabsProps, 'style'>;
31
- /**
32
- * A tabbed navigation widget (Navigation entity). Compose with `TabList` +
33
- * `Tab` for the switcher and `TabPanel` for each view. React Aria manages
34
- * selection, arrow-key navigation, and panel association.
35
- *
36
- * @example
37
- * ```tsx
38
- * <Tabs>
39
- * <TabList aria-label="Sections">
40
- * <Tab id="a">Overview</Tab>
41
- * <Tab id="b">Details</Tab>
42
- * </TabList>
43
- * <TabPanel id="a">Overview content</TabPanel>
44
- * <TabPanel id="b">Details content</TabPanel>
45
- * </Tabs>
46
- * ```
47
- */
48
31
  declare const Tabs$1: {
49
32
  ({
50
33
  orientation,
@@ -2,8 +2,9 @@
2
2
  import { focusRingOutline } from "../../tokens/focusRing.mjs";
3
3
  import { resolveInteractiveStyle } from "../../tokens/resolveInteractiveStyle.mjs";
4
4
  import { vars } from "@ttoss/fsl-theme/vars";
5
- import { Tab, TabList, TabPanel, Tabs } from "react-aria-components";
6
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { Tab, TabList, TabPanel, Tabs } from "react-aria-components";
7
+ import * as React from "react";
7
8
 
8
9
  //#region src/components/Tabs/Tabs.tsx
9
10
  /** Formal semantic identity — Tabs root (Navigation entity). */
@@ -47,21 +48,30 @@ var tabPanelMeta = {
47
48
  * </Tabs>
48
49
  * ```
49
50
  */
51
+ /**
52
+ * Orientation reaches `Tab` through this context — RAC exposes it in
53
+ * `TabList`'s render props but not in `Tab`'s, and the selected-tab
54
+ * indicator must switch edges with the orientation (friction F-003).
55
+ */
56
+ var TabsOrientationContext = React.createContext("horizontal");
50
57
  var Tabs$1 = ({
51
58
  orientation = "horizontal",
52
59
  ...props
53
60
  }) => {
54
- return /* @__PURE__ */jsx(Tabs, {
55
- ...props,
56
- orientation,
57
- "data-scope": "tabs",
58
- "data-part": "root",
59
- style: {
60
- boxSizing: "border-box",
61
- display: "flex",
62
- flexDirection: orientation === "vertical" ? "row" : "column",
63
- gap: vars.spacing.gap.stack.sm
64
- }
61
+ return /* @__PURE__ */jsx(TabsOrientationContext.Provider, {
62
+ value: orientation,
63
+ children: /* @__PURE__ */jsx(Tabs, {
64
+ ...props,
65
+ orientation,
66
+ "data-scope": "tabs",
67
+ "data-part": "root",
68
+ style: {
69
+ boxSizing: "border-box",
70
+ display: "flex",
71
+ flexDirection: orientation === "vertical" ? "row" : "column",
72
+ gap: vars.spacing.gap.stack.sm
73
+ }
74
+ })
65
75
  });
66
76
  };
67
77
  Tabs$1.displayName = tabsMeta.displayName;
@@ -74,23 +84,62 @@ var TabList$1 = props => {
74
84
  ...props,
75
85
  "data-scope": "tabs",
76
86
  "data-part": "control",
77
- style: {
78
- boxSizing: "border-box",
79
- display: "flex",
80
- gap: vars.spacing.gap.inline.sm,
81
- borderBlockEndWidth: vars.border.divider.width,
82
- borderBlockEndStyle: vars.border.divider.style,
83
- borderBlockEndColor: vars.colors.navigation.muted?.border?.default ?? "transparent"
87
+ style: ({
88
+ orientation
89
+ }) => {
90
+ const isVertical = orientation === "vertical";
91
+ return {
92
+ boxSizing: "border-box",
93
+ display: "flex",
94
+ flexDirection: isVertical ? "column" : "row",
95
+ gap: isVertical ? vars.spacing.gap.stack.sm : vars.spacing.gap.inline.sm,
96
+ ...(isVertical ? {
97
+ borderInlineEndWidth: vars.border.divider.width,
98
+ borderInlineEndStyle: vars.border.divider.style,
99
+ borderInlineEndColor: vars.colors.navigation.muted?.border?.default ?? "transparent"
100
+ } : {
101
+ borderBlockEndWidth: vars.border.divider.width,
102
+ borderBlockEndStyle: vars.border.divider.style,
103
+ borderBlockEndColor: vars.colors.navigation.muted?.border?.default ?? "transparent"
104
+ })
105
+ };
84
106
  }
85
107
  });
86
108
  };
87
109
  TabList$1.displayName = tabListMeta.displayName;
88
110
  /**
111
+ * Style for the decorative active-tab indicator line — block-end underline
112
+ * when horizontal, inline-start bar when vertical (F-003).
113
+ */
114
+ var tabIndicatorStyle = orientation => {
115
+ const color = vars.colors.navigation.primary?.border?.current ?? vars.colors.navigation.primary?.border?.default;
116
+ const style = vars.border.outline.control.style;
117
+ if (orientation === "vertical") return {
118
+ position: "absolute",
119
+ insetBlockStart: 0,
120
+ insetBlockEnd: 0,
121
+ insetInlineStart: 0,
122
+ borderInlineStartWidth: vars.border.outline.selected.width,
123
+ borderInlineStartStyle: style,
124
+ borderInlineStartColor: color
125
+ };
126
+ return {
127
+ position: "absolute",
128
+ insetInlineStart: 0,
129
+ insetInlineEnd: 0,
130
+ insetBlockEnd: 0,
131
+ borderBlockEndWidth: vars.border.outline.selected.width,
132
+ borderBlockEndStyle: style,
133
+ borderBlockEndColor: color
134
+ };
135
+ };
136
+ /**
89
137
  * A single selectable tab. The selected tab reads the navigation `current`
90
138
  * color and shows an underline indicator; others use hover/default.
91
139
  */
92
140
  var Tab$1 = props => {
93
141
  const colors = vars.colors.navigation.primary;
142
+ const orientation = React.useContext(TabsOrientationContext);
94
143
  return /* @__PURE__ */jsx(Tab, {
95
144
  ...props,
96
145
  "data-scope": "tabs",
@@ -131,15 +180,7 @@ var Tab$1 = props => {
131
180
  "data-scope": "tabs",
132
181
  "data-part": "indicator",
133
182
  "aria-hidden": true,
134
- style: {
135
- position: "absolute",
136
- insetInlineStart: 0,
137
- insetInlineEnd: 0,
138
- insetBlockEnd: 0,
139
- borderBlockEndWidth: vars.border.outline.selected.width,
140
- borderBlockEndStyle: vars.border.outline.control.style,
141
- borderBlockEndColor: vars.colors.navigation.primary?.border?.current ?? vars.colors.navigation.primary?.border?.default
142
- }
183
+ style: tabIndicatorStyle(orientation)
143
184
  })]
144
185
  });
145
186
  }
@@ -0,0 +1,70 @@
1
+ /** Powered by @ttoss/config. https://ttoss.dev/docs/modules/packages/config/ */
2
+ let _ttoss_fsl_theme_vars = require("@ttoss/fsl-theme/vars");
3
+ let react_jsx_runtime = require("react/jsx-runtime");
4
+
5
+ //#region src/components/Text/Text.tsx
6
+ /** Formal semantic identity — Text root (Structure entity, body/label text). */
7
+ var textMeta = {
8
+ displayName: "Text",
9
+ entity: "Structure",
10
+ structure: "root"
11
+ };
12
+ /** Typography token per variant — the scale reaches the DOM only here. */
13
+ var TYPE_BY_VARIANT = {
14
+ "display-sm": _ttoss_fsl_theme_vars.vars.text.display.sm,
15
+ "body-lg": _ttoss_fsl_theme_vars.vars.text.body.lg,
16
+ "body-md": _ttoss_fsl_theme_vars.vars.text.body.md,
17
+ "body-sm": _ttoss_fsl_theme_vars.vars.text.body.sm,
18
+ "label-lg": _ttoss_fsl_theme_vars.vars.text.label.lg,
19
+ "label-md": _ttoss_fsl_theme_vars.vars.text.label.md,
20
+ "label-sm": _ttoss_fsl_theme_vars.vars.text.label.sm
21
+ };
22
+ /** Muted text colour; `default` tone inherits (no colour set). */
23
+ var colorForTone = tone => {
24
+ return tone === "muted" ? _ttoss_fsl_theme_vars.vars.colors.informational.muted.text?.default : "inherit";
25
+ };
26
+ /**
27
+ * Running copy and labels bound to the FSL type scale.
28
+ *
29
+ * Entity = Structure. `variant` picks the step of the body/label scale — there
30
+ * is no raw font-size vocabulary, which is how the theme's typography reaches
31
+ * the screen consistently. `tone="muted"` is the sanctioned way to build text
32
+ * hierarchy (secondary copy recedes); otherwise colour is inherited from the
33
+ * surface.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * <Text>Your changes are saved automatically.</Text>
38
+ * <Text variant="label-md" tone="muted">Last updated 2 minutes ago</Text>
39
+ * ```
40
+ */
41
+ var Text = ({
42
+ variant = "body-md",
43
+ tone = "default",
44
+ align = "start",
45
+ numeric = "normal",
46
+ as = "p",
47
+ children,
48
+ ...props
49
+ }) => {
50
+ return /* @__PURE__ */(0, react_jsx_runtime.jsx)(as, {
51
+ ...props,
52
+ "data-scope": "text",
53
+ "data-part": "root",
54
+ "data-variant": variant,
55
+ "data-tone": tone,
56
+ style: {
57
+ margin: 0,
58
+ color: colorForTone(tone),
59
+ textAlign: align,
60
+ fontVariantNumeric: numeric === "tabular" ? "tabular-nums" : void 0,
61
+ ...TYPE_BY_VARIANT[variant]
62
+ },
63
+ children
64
+ });
65
+ };
66
+ Text.displayName = textMeta.displayName;
67
+
68
+ //#endregion
69
+ exports.Text = Text;
70
+ exports.textMeta = textMeta;