@recursica/mui-adapter 0.16.0 → 0.17.0

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.
@@ -1,4 +1,4 @@
1
- import { TableProps as MuiTableProps, TableBody as MuiTableBody, TableCell as MuiTableCell, TableContainer as MuiTableContainer, TableHead as MuiTableHead, TableRow as MuiTableRow, TableFooter as MuiTableFooter, TableSortLabel as MuiTableSortLabel } from '@mui/material';
1
+ import { TableProps as MuiTableProps, TableBodyProps as MuiTableBodyProps, TableCellProps as MuiTableCellProps, TableContainerProps as MuiTableContainerProps, TableHeadProps as MuiTableHeadProps, TableRowProps as MuiTableRowProps, TableFooterProps as MuiTableFooterProps, TableSortLabelProps as MuiTableSortLabelProps } from '@mui/material';
2
2
  import { RecursicaOverStyled } from '../../utils/filterStylingProps';
3
3
  import { RecursicaTableProps } from '@recursica/adapter-common';
4
4
  export type TableProps = RecursicaOverStyled<MuiTableProps & RecursicaTableProps>;
@@ -22,14 +22,133 @@ declare const TableBase: import('react').ForwardRefExoticComponent<(Omit<Omit<im
22
22
  } & {
23
23
  overStyled: true;
24
24
  }, "ref">) & import('react').RefAttributes<HTMLTableElement>>;
25
+ export type TableBodyPropsRecursica = RecursicaOverStyled<MuiTableBodyProps>;
26
+ export declare const TableBodyComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableBodyProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
27
+ overStyled?: false | undefined;
28
+ }, "ref"> | Omit<Omit<MuiTableBodyProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
29
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
30
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
31
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
32
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
33
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
34
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
35
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
36
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
37
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
38
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
39
+ } & {
40
+ overStyled: true;
41
+ }, "ref">) & import('react').RefAttributes<HTMLTableSectionElement>>;
42
+ export type TableCellPropsRecursica = RecursicaOverStyled<MuiTableCellProps>;
43
+ export declare const TableCellComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableCellProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
44
+ overStyled?: false | undefined;
45
+ }, "ref"> | Omit<Omit<MuiTableCellProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
46
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
47
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
48
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
49
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
50
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
51
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
52
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
53
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
54
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
55
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
56
+ } & {
57
+ overStyled: true;
58
+ }, "ref">) & import('react').RefAttributes<HTMLTableCellElement>>;
59
+ export type TableContainerPropsRecursica = RecursicaOverStyled<MuiTableContainerProps>;
60
+ export declare const TableContainerComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableContainerProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
61
+ overStyled?: false | undefined;
62
+ }, "ref"> | Omit<Omit<MuiTableContainerProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
63
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
64
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
65
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
66
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
67
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
68
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
69
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
70
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
71
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
72
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
73
+ } & {
74
+ overStyled: true;
75
+ }, "ref">) & import('react').RefAttributes<HTMLDivElement>>;
76
+ export type TableHeadPropsRecursica = RecursicaOverStyled<MuiTableHeadProps>;
77
+ export declare const TableHeadComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableHeadProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
78
+ overStyled?: false | undefined;
79
+ }, "ref"> | Omit<Omit<MuiTableHeadProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
80
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
81
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
82
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
83
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
84
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
85
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
86
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
87
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
88
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
89
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
90
+ } & {
91
+ overStyled: true;
92
+ }, "ref">) & import('react').RefAttributes<HTMLTableSectionElement>>;
93
+ export type TableRowPropsRecursica = RecursicaOverStyled<MuiTableRowProps>;
94
+ export declare const TableRowComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableRowProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
95
+ overStyled?: false | undefined;
96
+ }, "ref"> | Omit<Omit<MuiTableRowProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
97
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
98
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
99
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
100
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
101
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
102
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
103
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
104
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
105
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
106
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
107
+ } & {
108
+ overStyled: true;
109
+ }, "ref">) & import('react').RefAttributes<HTMLTableRowElement>>;
110
+ export type TableFooterPropsRecursica = RecursicaOverStyled<MuiTableFooterProps>;
111
+ export declare const TableFooterComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableFooterProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
112
+ overStyled?: false | undefined;
113
+ }, "ref"> | Omit<Omit<MuiTableFooterProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
114
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
115
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
116
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
117
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
118
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
119
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
120
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
121
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
122
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
123
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
124
+ } & {
125
+ overStyled: true;
126
+ }, "ref">) & import('react').RefAttributes<HTMLTableSectionElement>>;
127
+ export type TableSortLabelPropsRecursica = RecursicaOverStyled<MuiTableSortLabelProps>;
128
+ export declare const TableSortLabelComponent: import('react').ForwardRefExoticComponent<(Omit<Omit<import('@recursica/adapter-common').WithRecursicaSpacing<MuiTableSortLabelProps>, import('@recursica/adapter-common').BlockedStylingKeys> & import('@recursica/adapter-common').ForbiddenStyles & {
129
+ overStyled?: false | undefined;
130
+ }, "ref"> | Omit<Omit<MuiTableSortLabelProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap"> & {
131
+ m?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
132
+ mx?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
133
+ my?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
134
+ mt?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
135
+ mb?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
136
+ ml?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
137
+ mr?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
138
+ gap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
139
+ rowGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
140
+ columnGap?: string | number | import('@recursica/adapter-common').RecursicaSpacing;
141
+ } & {
142
+ overStyled: true;
143
+ }, "ref">) & import('react').RefAttributes<HTMLSpanElement>>;
25
144
  type TableComponent = typeof TableBase & {
26
- Body: typeof MuiTableBody;
27
- Cell: typeof MuiTableCell;
28
- Container: typeof MuiTableContainer;
29
- Head: typeof MuiTableHead;
30
- Row: typeof MuiTableRow;
31
- Footer: typeof MuiTableFooter;
32
- SortLabel: typeof MuiTableSortLabel;
145
+ Body: typeof TableBodyComponent;
146
+ Cell: typeof TableCellComponent;
147
+ Container: typeof TableContainerComponent;
148
+ Head: typeof TableHeadComponent;
149
+ Row: typeof TableRowComponent;
150
+ Footer: typeof TableFooterComponent;
151
+ SortLabel: typeof TableSortLabelComponent;
33
152
  };
34
153
  export declare const Table: TableComponent;
35
154
  export {};
package/llms.txt CHANGED
@@ -9,8 +9,64 @@ This adapter converts Recursica design tokens into MUI-specific themes and compo
9
9
  - Relies on `@mui/material`, `@emotion/react`, and `@emotion/styled` peer dependencies.
10
10
  - When building UI in consumer applications, prioritize using components exported by this package to adhere to the Recursica design system.
11
11
 
12
- ## Documentation
12
+ ## Reference Documentation
13
13
 
14
- - [USAGE](USAGE.md): Detailed usage instructions.
14
+ - [USAGE](USAGE.md): Detailed usage instructions, import rules, and layout/token conventions.
15
+ - [OVERSTYLING](OVERSTYLING.md): The `overStyled` escape hatch — when it's appropriate, what's permitted by default, and how to visually audit its usage.
16
+ - [SETUP](SETUP.md): Installation and integration steps.
15
17
  - [ARCHITECTURE](ARCHITECTURE.md): Package architecture and dependencies.
16
18
  - [README](README.md)
19
+
20
+ ## Components
21
+
22
+ Each component has its own `USAGE.md` documenting its props, adapter-specific behaviors, layout constraints, and accessibility requirements.
23
+
24
+ - [Accordion](src/components/Accordion/USAGE.md)
25
+ - [AssistiveElement](src/components/AssistiveElement/USAGE.md)
26
+ - [Autocomplete](src/components/Autocomplete/USAGE.md)
27
+ - [Avatar](src/components/Avatar/USAGE.md)
28
+ - [Badge](src/components/Badge/USAGE.md)
29
+ - [Box](src/components/Box/USAGE.md)
30
+ - [Breadcrumb](src/components/Breadcrumb/USAGE.md)
31
+ - [Button](src/components/Button/USAGE.md)
32
+ - [Card](src/components/Card/USAGE.md)
33
+ - [Checkbox](src/components/Checkbox/USAGE.md)
34
+ - [Chip](src/components/Chip/USAGE.md)
35
+ - [Container](src/components/Container/USAGE.md)
36
+ - [DatePicker](src/components/DatePicker/USAGE.md)
37
+ - [Dropdown](src/components/Dropdown/USAGE.md)
38
+ - [FileInput](src/components/FileInput/USAGE.md)
39
+ - [FileUpload](src/components/FileUpload/USAGE.md)
40
+ - [Flex](src/components/Flex/USAGE.md)
41
+ - [FormControlLayout](src/components/FormControlLayout/USAGE.md)
42
+ - [FormControlWrapper](src/components/FormControlWrapper/USAGE.md)
43
+ - [Group](src/components/Group/USAGE.md)
44
+ - [HoverCard](src/components/HoverCard/USAGE.md)
45
+ - [Label](src/components/Label/USAGE.md)
46
+ - [Link](src/components/Link/USAGE.md)
47
+ - [Loader](src/components/Loader/USAGE.md)
48
+ - [Menu](src/components/Menu/USAGE.md)
49
+ - [Modal](src/components/Modal/USAGE.md)
50
+ - [NumberInput](src/components/NumberInput/USAGE.md)
51
+ - [Pagination](src/components/Pagination/USAGE.md)
52
+ - [Panel](src/components/Panel/USAGE.md)
53
+ - [Radio](src/components/Radio/USAGE.md)
54
+ - [ReadOnlyField](src/components/ReadOnlyField/USAGE.md)
55
+ - [SegmentedControl](src/components/SegmentedControl/USAGE.md)
56
+ - [Slider](src/components/Slider/USAGE.md)
57
+ - [Stack](src/components/Stack/USAGE.md)
58
+ - [Stepper](src/components/Stepper/USAGE.md)
59
+ - [Switch](src/components/Switch/USAGE.md)
60
+ - [Table](src/components/Table/USAGE.md)
61
+ - [Tabs](src/components/Tabs/USAGE.md)
62
+ - [Text](src/components/Text/USAGE.md)
63
+ - [TextArea](src/components/TextArea/USAGE.md)
64
+ - [TextField](src/components/TextField/USAGE.md)
65
+ - [TimePicker](src/components/TimePicker/USAGE.md)
66
+ - [Timeline](src/components/Timeline/USAGE.md)
67
+ - [Title](src/components/Title/USAGE.md)
68
+ - [Toast](src/components/Toast/USAGE.md)
69
+ - [Tooltip](src/components/Tooltip/USAGE.md)
70
+ - [TransferList](src/components/TransferList/USAGE.md)
71
+ - [Tree](src/components/Tree/USAGE.md)
72
+ - [Typography](src/components/Typography/USAGE.md)
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "url": "git+https://github.com/borderux/recursica.git",
14
14
  "directory": "packages/mui-adapter"
15
15
  },
16
- "version": "0.16.0",
16
+ "version": "0.17.0",
17
17
  "publishConfig": {
18
18
  "access": "public"
19
19
  },
@@ -37,7 +37,8 @@
37
37
  "llms.txt",
38
38
  "USAGE.md",
39
39
  "ARCHITECTURE.md",
40
- "SETUP.md"
40
+ "SETUP.md",
41
+ "OVERSTYLING.md"
41
42
  ],
42
43
  "keywords": [
43
44
  "react",
@@ -1,3 +1,4 @@
1
+ import ReactMarkdown from "react-markdown";
1
2
  import { Paper, Divider } from "@mui/material";
2
3
  import {
3
4
  Container,
@@ -13,6 +14,7 @@ import {
13
14
  toggleGlobalOverStyled,
14
15
  wrapComponent,
15
16
  } from "@recursica/adapter-common";
17
+ import overStylingDoc from "../OVERSTYLING.md?raw";
16
18
 
17
19
  const Button = wrapComponent(RawButton);
18
20
  const Text = wrapComponent(RawText);
@@ -23,198 +25,16 @@ export const OverStylingInfo = () => {
23
25
  return (
24
26
  <Container size="md" style={{ padding: "32px 0" }}>
25
27
  <Paper variant="outlined" sx={{ p: 4, borderRadius: 2 }}>
26
- <Title order={4} mb={2}>
27
- Over Styling (<code>overStyled</code>)
28
- </Title>
29
- <Text mb={2}>
30
- By default, all Recursica components are strictly sandboxed. This
31
- means they are protected against arbitrary styling configurations
32
- (like passing generic React <code>style</code> objects, custom{" "}
33
- <code>className</code> injections, or using deep MUI layout props like{" "}
34
- <code>sx</code>). This strict compile-time and run-time enforcement
35
- guarantees that your design system tokens remain true across your
36
- application.
37
- </Text>
38
- <Text mb={2}>
39
- However, there may be edge cases where a developer absolutely must
40
- modify a component beyond what the design tokens natively allow. For
41
- this, we provide the <strong>escape hatch</strong> property:{" "}
42
- <code>overStyled={`{true}`}</code>.
43
- </Text>
44
-
45
- <Title order={6} mb={1} mt={4}>
46
- The Core Philosophy
47
- </Title>
48
- <Text mb={1}>
49
- **You should not over-style components.** Using{" "}
50
- <code>overStyled</code> explicitly signifies that you are breaking
51
- design system rules.
52
- </Text>
53
- <Box component="ol" sx={{ pl: 4, mb: 4 }}>
54
- <li>
55
- <Text>
56
- <strong>Technical Debt:</strong> If over-styling is required, it
57
- should be treated as a short-term workaround. Ideally, the
58
- component will be refactored once the required layouts or variants
59
- are officially integrated into the core Recursica component
60
- library.
61
- </Text>
62
- </li>
63
- <li>
64
- <Text>
65
- <strong>Auditing & Searching:</strong> Because this pattern
66
- creates technical debt, we enforce the explicit{" "}
67
- <code>overStyled</code> boolean. This provides a highly auditable,
68
- easily searchable string. Product managers and engineers can
69
- quickly grep the codebase for <code>overStyled</code> (or the{" "}
70
- <code>RecursicaOverStyled</code> typings) to hunt down components
71
- that don't match standard patterns.
72
- </Text>
73
- </li>
74
- <li>
75
- <Text>
76
- <strong>Highly Custom Components:</strong> If your application
77
- genuinely requires massive custom layouts that the UI kit cannot
78
- support, <strong>do not hack the Recursica component</strong>.
79
- Instead, it is highly encouraged that you import the underlying
80
- primitive component directly from <code>@mui/material</code> and
81
- construct your independent feature there. While you can utilize
82
- raw Recursica CSS variables on these custom components, note that
83
- they are not guaranteed to be accurately maintained as Recursica
84
- evolves. Keep strict components strict!
85
- </Text>
86
- </li>
87
- </Box>
88
-
89
- <Divider sx={{ mb: 4 }} />
90
-
91
- <Title order={6} mb={1}>
92
- Permitted Layout Properties
93
- </Title>
94
- <Text mb={1}>
95
- Unlike deep styling bounds (colors, typography, padding, dimensions),
96
- external <strong>layout spacing properties</strong> like Margins (
97
- <code>m</code>, <code>mt</code>, <code>mb</code>, <code>mx</code>) are
98
- safely <strong>permitted by default</strong>. This allows integrators
99
- to structurally compose components alongside siblings without
100
- breaching internal token boundaries.
101
- </Text>
102
- <Text mb={3}>
103
- When using layout properties, you have the flexibility to use either
104
- ecosystem seamlessly:
105
- </Text>
106
- <Box component="ol" sx={{ pl: 4, mb: 2 }}>
107
- <li>
108
- <Text>
109
- <strong>MUI Core Values:</strong> Passing standard MUI sizes (like{" "}
110
- <code>mt={"{2}"}</code>) passes straight through to MUI natively,
111
- allowing you to interface completely normally with a parent
112
- application's existing MUI Theme setup that might fall outside
113
- Recursica's scope.
114
- </Text>
115
- </li>
116
- <li>
117
- <Text>
118
- <strong>Recursica Strict Tokens:</strong> Passing our custom
119
- prefixed tokens (like <code>mt="rec-md"</code>) signals our
120
- internal layout interceptor to securely translate the value
121
- directly to our native <code>--recursica_brand_dimensions_*</code>{" "}
122
- CSS variables. This ensures strict design token measurements while
123
- sharing the exact same prop interface!
124
- </Text>
125
- </li>
126
- </Box>
127
- <Text mb={1} overStyled sx={{ fontWeight: 500 }}>
128
- Available Recursica Layout Tokens:
129
- </Text>
130
- <Box component="ul" sx={{ pl: 4, mb: 4 }}>
131
- <li>
132
- <Text>
133
- <code>rec-none</code> (0px limit)
134
- </Text>
135
- </li>
136
- <li>
137
- <Text>
138
- <code>rec-sm</code> (0.5x scaling)
139
- </Text>
140
- </li>
141
- <li>
142
- <Text>
143
- <code>rec-default</code> (1.0x scaling)
144
- </Text>
145
- </li>
146
- <li>
147
- <Text>
148
- <code>rec-md</code> (1.5x scaling)
149
- </Text>
150
- </li>
151
- <li>
152
- <Text>
153
- <code>rec-lg</code> (2.0x scaling)
154
- </Text>
155
- </li>
156
- <li>
157
- <Text>
158
- <code>rec-xl</code> (3.0x scaling)
159
- </Text>
160
- </li>
161
- <li>
162
- <Text>
163
- <code>rec-2xl</code> (4.0x scaling)
164
- </Text>
165
- </li>
28
+ <Box className="markdown-body">
29
+ <ReactMarkdown>{overStylingDoc}</ReactMarkdown>
166
30
  </Box>
167
31
 
168
- <Divider sx={{ mb: 4 }} />
32
+ <Divider sx={{ my: 4 }} />
169
33
 
170
- <Title order={6} mb={1}>
171
- Primitive Layout Components Exemption
34
+ <Title order={6} mb={2}>
35
+ Try It Yourself
172
36
  </Title>
173
- <Text mb={1}>
174
- Unlike complex UI components (Buttons, Tabs, Inputs) which are
175
- strictly protected, <strong>Primitive Layout Components</strong> (
176
- <code>Flex</code>,<code>Stack</code>, <code>Group</code>,{" "}
177
- <code>Container</code>) are entirely exempt from the{" "}
178
- <code>RecursicaOverStyled</code> gatekeeper.
179
- </Text>
180
- <Text mb={4}>
181
- Because the entire functional purpose of these components is
182
- structural layout composition, developers are free to pass any
183
- standard MUI width, height, padding, margin, gap, and alignment
184
- property directly to them without needing to flag{" "}
185
- <code>overStyled={`{true}`}</code>. The internal custom token mapper
186
- (such as converting <code>gap="rec-md"</code>) is still active
187
- natively on these wrappers.
188
- </Text>
189
37
 
190
- <Divider sx={{ mb: 4 }} />
191
-
192
- <Title order={6} mb={1}>
193
- Visual Auditing & Highlights (Development Only)
194
- </Title>
195
- <Text mb={2}>
196
- To make it easy to spot technical debt and design system violations,
197
- Recursica automatically tracks any component that uses the{" "}
198
- <code>overStyled={`{true}`}</code> prop.
199
- </Text>
200
- <Text mb={2}>
201
- In <strong>development builds</strong>, you can highlight all
202
- over-styled components on the page. Open your browser's developer
203
- console and run:
204
- </Text>
205
- <Box
206
- component="pre"
207
- sx={{
208
- p: 1.5,
209
- bgcolor: "grey.100",
210
- borderRadius: 1,
211
- fontSize: 13,
212
- mt: 1,
213
- mb: 2,
214
- }}
215
- >
216
- <code>recursica.toggleOverStyled()</code>
217
- </Box>
218
38
  <Stack direction="row" alignItems="center" gap="rec-sm" mb="rec-md">
219
39
  <Switch
220
40
  label="Highlight Over-Styled Components"
@@ -222,20 +42,7 @@ export const OverStylingInfo = () => {
222
42
  onChange={() => toggleGlobalOverStyled()}
223
43
  />
224
44
  </Stack>
225
- <Text mb={4}>
226
- This toggles a <strong>cyan 2px box shadow</strong> outline around the
227
- children of all over-styled components. The wrapping elements use{" "}
228
- <code>display: contents</code> under the hood to ensure they occupy
229
- zero DOM space and do not affect flex, grid, or absolute positioning
230
- flow. In production builds, this debugging helper is completely
231
- disabled and stripped with zero performance overhead.
232
- </Text>
233
-
234
- <Divider sx={{ mb: 4 }} />
235
45
 
236
- <Title order={6} mb={2}>
237
- Live Example
238
- </Title>
239
46
  <Text mb={4}>
240
47
  Below is a side-by-side comparison. The first is a standard Recursica
241
48
  Button protected by the design tokens mapping. The second flagrantly
@@ -3,12 +3,19 @@ import {
3
3
  Table as MuiTable,
4
4
  type TableProps as MuiTableProps,
5
5
  TableBody as MuiTableBody,
6
+ type TableBodyProps as MuiTableBodyProps,
6
7
  TableCell as MuiTableCell,
8
+ type TableCellProps as MuiTableCellProps,
7
9
  TableContainer as MuiTableContainer,
10
+ type TableContainerProps as MuiTableContainerProps,
8
11
  TableHead as MuiTableHead,
12
+ type TableHeadProps as MuiTableHeadProps,
9
13
  TableRow as MuiTableRow,
14
+ type TableRowProps as MuiTableRowProps,
10
15
  TableFooter as MuiTableFooter,
16
+ type TableFooterProps as MuiTableFooterProps,
11
17
  TableSortLabel as MuiTableSortLabel,
18
+ type TableSortLabelProps as MuiTableSortLabelProps,
12
19
  } from "@mui/material";
13
20
  import {
14
21
  filterStylingProps,
@@ -45,21 +52,142 @@ const TableBase = forwardRef<HTMLTableElement, TableProps>(function Table(
45
52
 
46
53
  TableBase.displayName = "Table";
47
54
 
55
+ // ==== EXPLICIT DOT-NOTATION SUB-COMPONENTS ====
56
+ // Each sub-component is wrapped independently so it goes through
57
+ // filterStylingProps/overStyled the same way the root Table does.
58
+
59
+ export type TableBodyPropsRecursica = RecursicaOverStyled<MuiTableBodyProps>;
60
+
61
+ export const TableBodyComponent = forwardRef<
62
+ HTMLTableSectionElement,
63
+ TableBodyPropsRecursica
64
+ >(function TableBody({ overStyled = false, ...rest }, ref) {
65
+ const sanitizedProps = filterStylingProps(rest, overStyled);
66
+ return (
67
+ <MuiTableBody
68
+ ref={ref}
69
+ {...(sanitizedProps as unknown as MuiTableBodyProps)}
70
+ />
71
+ );
72
+ });
73
+ TableBodyComponent.displayName = "TableBody";
74
+
75
+ export type TableCellPropsRecursica = RecursicaOverStyled<MuiTableCellProps>;
76
+
77
+ export const TableCellComponent = forwardRef<
78
+ HTMLTableCellElement,
79
+ TableCellPropsRecursica
80
+ >(function TableCell({ overStyled = false, ...rest }, ref) {
81
+ const sanitizedProps = filterStylingProps(rest, overStyled);
82
+ return (
83
+ <MuiTableCell
84
+ ref={ref}
85
+ {...(sanitizedProps as unknown as MuiTableCellProps)}
86
+ />
87
+ );
88
+ });
89
+ TableCellComponent.displayName = "TableCell";
90
+
91
+ export type TableContainerPropsRecursica =
92
+ RecursicaOverStyled<MuiTableContainerProps>;
93
+
94
+ export const TableContainerComponent = forwardRef<
95
+ HTMLDivElement,
96
+ TableContainerPropsRecursica
97
+ >(function TableContainer({ overStyled = false, ...rest }, ref) {
98
+ const sanitizedProps = filterStylingProps(rest, overStyled);
99
+ return (
100
+ <MuiTableContainer
101
+ ref={ref}
102
+ {...(sanitizedProps as unknown as MuiTableContainerProps)}
103
+ />
104
+ );
105
+ });
106
+ TableContainerComponent.displayName = "TableContainer";
107
+
108
+ export type TableHeadPropsRecursica = RecursicaOverStyled<MuiTableHeadProps>;
109
+
110
+ export const TableHeadComponent = forwardRef<
111
+ HTMLTableSectionElement,
112
+ TableHeadPropsRecursica
113
+ >(function TableHead({ overStyled = false, ...rest }, ref) {
114
+ const sanitizedProps = filterStylingProps(rest, overStyled);
115
+ return (
116
+ <MuiTableHead
117
+ ref={ref}
118
+ {...(sanitizedProps as unknown as MuiTableHeadProps)}
119
+ />
120
+ );
121
+ });
122
+ TableHeadComponent.displayName = "TableHead";
123
+
124
+ export type TableRowPropsRecursica = RecursicaOverStyled<MuiTableRowProps>;
125
+
126
+ export const TableRowComponent = forwardRef<
127
+ HTMLTableRowElement,
128
+ TableRowPropsRecursica
129
+ >(function TableRow({ overStyled = false, ...rest }, ref) {
130
+ const sanitizedProps = filterStylingProps(rest, overStyled);
131
+ return (
132
+ <MuiTableRow
133
+ ref={ref}
134
+ {...(sanitizedProps as unknown as MuiTableRowProps)}
135
+ />
136
+ );
137
+ });
138
+ TableRowComponent.displayName = "TableRow";
139
+
140
+ export type TableFooterPropsRecursica =
141
+ RecursicaOverStyled<MuiTableFooterProps>;
142
+
143
+ export const TableFooterComponent = forwardRef<
144
+ HTMLTableSectionElement,
145
+ TableFooterPropsRecursica
146
+ >(function TableFooter({ overStyled = false, ...rest }, ref) {
147
+ const sanitizedProps = filterStylingProps(rest, overStyled);
148
+ return (
149
+ <MuiTableFooter
150
+ ref={ref}
151
+ {...(sanitizedProps as unknown as MuiTableFooterProps)}
152
+ />
153
+ );
154
+ });
155
+ TableFooterComponent.displayName = "TableFooter";
156
+
157
+ export type TableSortLabelPropsRecursica =
158
+ RecursicaOverStyled<MuiTableSortLabelProps>;
159
+
160
+ export const TableSortLabelComponent = forwardRef<
161
+ HTMLSpanElement,
162
+ TableSortLabelPropsRecursica
163
+ >(function TableSortLabel({ overStyled = false, ...rest }, ref) {
164
+ const sanitizedProps = filterStylingProps(rest, overStyled);
165
+ return (
166
+ <MuiTableSortLabel
167
+ ref={ref}
168
+ {...(sanitizedProps as unknown as MuiTableSortLabelProps)}
169
+ />
170
+ );
171
+ });
172
+ TableSortLabelComponent.displayName = "TableSortLabel";
173
+
174
+ // ==== DOT NOTATION EXPORT ====
175
+
48
176
  type TableComponent = typeof TableBase & {
49
- Body: typeof MuiTableBody;
50
- Cell: typeof MuiTableCell;
51
- Container: typeof MuiTableContainer;
52
- Head: typeof MuiTableHead;
53
- Row: typeof MuiTableRow;
54
- Footer: typeof MuiTableFooter;
55
- SortLabel: typeof MuiTableSortLabel;
177
+ Body: typeof TableBodyComponent;
178
+ Cell: typeof TableCellComponent;
179
+ Container: typeof TableContainerComponent;
180
+ Head: typeof TableHeadComponent;
181
+ Row: typeof TableRowComponent;
182
+ Footer: typeof TableFooterComponent;
183
+ SortLabel: typeof TableSortLabelComponent;
56
184
  };
57
185
 
58
186
  export const Table = TableBase as TableComponent;
59
- Table.Body = MuiTableBody;
60
- Table.Cell = MuiTableCell;
61
- Table.Container = MuiTableContainer;
62
- Table.Head = MuiTableHead;
63
- Table.Row = MuiTableRow;
64
- Table.Footer = MuiTableFooter;
65
- Table.SortLabel = MuiTableSortLabel;
187
+ Table.Body = TableBodyComponent;
188
+ Table.Cell = TableCellComponent;
189
+ Table.Container = TableContainerComponent;
190
+ Table.Head = TableHeadComponent;
191
+ Table.Row = TableRowComponent;
192
+ Table.Footer = TableFooterComponent;
193
+ Table.SortLabel = TableSortLabelComponent;