@recursica/adapter-mui-v7 1.1.0 → 1.3.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.
- package/CHANGELOG.md +17 -0
- package/OVERSTYLING.md +1 -1
- package/SETUP.md +26 -3
- package/dist/adapter-mui-v7.cjs +69 -69
- package/dist/adapter-mui-v7.cjs.map +1 -1
- package/dist/adapter-mui-v7.css +1 -1
- package/dist/adapter-mui-v7.js +5955 -5739
- package/dist/adapter-mui-v7.js.map +1 -1
- package/dist/index.d.ts +69 -51
- package/llms.txt +1 -1
- package/package.json +4 -4
- package/recursica_brand.json +2 -2
- package/recursica_tokens.json +2 -2
- package/recursica_ui-kit.json +2 -2
- package/recursica_variables_scoped.css +7 -3
- package/src/components/Checkbox/Checkbox.module.css +1 -3
- package/src/components/Container/USAGE.md +0 -1
- package/src/components/FileInput/FileInput.module.css +8 -0
- package/src/components/FileUpload/FileUpload.module.css +1 -0
- package/src/components/FileUpload/FileUpload.tsx +1 -0
- package/src/components/Flex/USAGE.md +2 -1
- package/src/components/Group/USAGE.md +2 -1
- package/src/components/LayoutGrid/LAYOUT_GRID_IMPLEMENTATION_NOTES.md +82 -0
- package/src/components/LayoutGrid/LayoutGrid.columns.dom.test.tsx +78 -0
- package/src/components/{Grid/Grid.module.css → LayoutGrid/LayoutGrid.module.css} +11 -10
- package/src/components/LayoutGrid/LayoutGrid.stories.tsx +61 -0
- package/src/components/LayoutGrid/LayoutGrid.test.tsx +1 -0
- package/src/components/LayoutGrid/LayoutGrid.tsx +181 -0
- package/src/components/LayoutGrid/USAGE.md +79 -0
- package/src/components/LayoutGrid/index.ts +1 -0
- package/src/components/Menu/Menu.stories.tsx +0 -3
- package/src/components/Pagination/IMPLEMENTATION_NOTES.md +42 -38
- package/src/components/Pagination/Pagination.icons.tsx +0 -32
- package/src/components/Pagination/Pagination.manifest.dom.test.tsx +105 -0
- package/src/components/Pagination/Pagination.module.css +25 -164
- package/src/components/Pagination/Pagination.tsx +221 -97
- package/src/components/Pagination/USAGE.md +8 -1
- package/src/components/Panel/Panel.module.css +24 -1
- package/src/components/Panel/Panel.stories.tsx +4 -4
- package/src/components/Panel/Panel.tsx +10 -1
- package/src/components/Radio/Radio.module.css +2 -2
- package/src/components/SegmentedControl/SegmentedControl.module.css +18 -0
- package/src/components/Stack/USAGE.md +2 -1
- package/src/components/Stepper/Stepper.module.css +0 -21
- package/src/components/index.ts +1 -1
- package/src/index.ts +1 -0
- package/src/utils/breakpointsFromRecManifest.test.ts +40 -0
- package/src/utils/breakpointsFromRecManifest.ts +72 -0
- package/src/utils/index.ts +1 -0
- package/src/components/Grid/Grid.stories.tsx +0 -151
- package/src/components/Grid/Grid.test.tsx +0 -1
- package/src/components/Grid/Grid.tsx +0 -189
- package/src/components/Grid/IMPLEMENTATION_NOTES.md +0 -99
- package/src/components/Grid/USAGE.md +0 -57
- package/src/components/Grid/index.ts +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { CardProps as CardProps_2 } from '@mui/material';
|
|
|
13
13
|
import { CheckboxProps as CheckboxProps_2 } from '@mui/material';
|
|
14
14
|
import { ChipProps as ChipProps_2 } from '@mui/material';
|
|
15
15
|
import { CommonProps } from '@mui/material/OverridableComponent';
|
|
16
|
+
import { ComponentPropsWithoutRef } from 'react';
|
|
16
17
|
import { ContainerProps as ContainerProps_2 } from '@mui/material';
|
|
17
18
|
import { CSSProperties } from 'react';
|
|
18
19
|
import { DatePickerProps as DatePickerProps_2 } from '@mui/x-date-pickers/DatePicker';
|
|
@@ -31,7 +32,7 @@ import { FormControlProps } from '@mui/material';
|
|
|
31
32
|
import { FormGroupProps } from '@mui/material';
|
|
32
33
|
import { FormHelperTextProps } from '@mui/material';
|
|
33
34
|
import { ForwardRefExoticComponent } from 'react';
|
|
34
|
-
import { GridProps
|
|
35
|
+
import { GridProps } from '@mui/material';
|
|
35
36
|
import { HTMLAttributes } from 'react';
|
|
36
37
|
import { InputBaseProps } from '@mui/material';
|
|
37
38
|
import { InputLabelProps } from '@mui/material';
|
|
@@ -39,7 +40,6 @@ import { JSX } from 'react';
|
|
|
39
40
|
import { LinkProps as LinkProps_2 } from '@mui/material';
|
|
40
41
|
import { MenuItemProps as MenuItemProps_2 } from '@mui/material';
|
|
41
42
|
import { MenuProps as MenuProps_2 } from '@mui/material';
|
|
42
|
-
import { PaginationProps as PaginationProps_2 } from '@mui/material';
|
|
43
43
|
import { RadioGroupProps as RadioGroupProps_2 } from '@mui/material';
|
|
44
44
|
import { RadioProps as RadioProps_2 } from '@mui/material';
|
|
45
45
|
import { ReactNode } from 'react';
|
|
@@ -68,11 +68,11 @@ import { RecursicaFileUploadItem } from '@recursica/adapter-common';
|
|
|
68
68
|
import { RecursicaFileUploadProps as RecursicaFileUploadProps_2 } from '@recursica/adapter-common';
|
|
69
69
|
import { RecursicaFormControlLayoutProps } from '@recursica/adapter-common';
|
|
70
70
|
import { RecursicaFormControlWrapperProps as RecursicaFormControlWrapperProps_2 } from '@recursica/adapter-common';
|
|
71
|
-
import { RecursicaGridColProps } from '@recursica/adapter-common';
|
|
72
|
-
import { RecursicaGridProps } from '@recursica/adapter-common';
|
|
73
71
|
import { RecursicaHeadingProps } from '@recursica/adapter-common';
|
|
74
72
|
import { RecursicaHoverCardProps } from '@recursica/adapter-common';
|
|
75
73
|
import { RecursicaLabelProps } from '@recursica/adapter-common';
|
|
74
|
+
import { RecursicaLayoutGridColProps } from '@recursica/adapter-common';
|
|
75
|
+
import { RecursicaLayoutGridProps } from '@recursica/adapter-common';
|
|
76
76
|
import { RecursicaLinkProps } from '@recursica/adapter-common';
|
|
77
77
|
import { RecursicaLoaderProps } from '@recursica/adapter-common';
|
|
78
78
|
import { RecursicaMenuProps } from '@recursica/adapter-common';
|
|
@@ -139,6 +139,7 @@ import { TimePickerProps as TimePickerProps_2 } from '@mui/x-date-pickers/TimePi
|
|
|
139
139
|
import { ToggleButtonGroupProps } from '@mui/material';
|
|
140
140
|
import { TooltipProps as TooltipProps_2 } from '@mui/material';
|
|
141
141
|
import { TypographyProps as TypographyProps_2 } from '@mui/material';
|
|
142
|
+
import { UsePaginationProps } from '@mui/material/usePagination';
|
|
142
143
|
import { WithRecursicaSpacing } from '@recursica/adapter-common';
|
|
143
144
|
|
|
144
145
|
export declare const Accordion: AccordionComponent;
|
|
@@ -352,6 +353,23 @@ export declare type BreadcrumbProps = RecursicaOverStyled<Omit<BreadcrumbsProps,
|
|
|
352
353
|
|
|
353
354
|
declare type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl";
|
|
354
355
|
|
|
356
|
+
/**
|
|
357
|
+
* Builds a `{ name: <start px> }` breakpoint values object from the manifest's layout grids, to
|
|
358
|
+
* merge into MUI's `createTheme({ breakpoints: { values } })`. Opt-in: nothing in the adapter
|
|
359
|
+
* calls this for you, and the result is a plain object you can edit.
|
|
360
|
+
*
|
|
361
|
+
* MUI breakpoints are mobile-first start widths, so each non-default grid maps to its
|
|
362
|
+
* `min-width`; a grid with only a `max-width` (e.g. `mobile`, up to 480px) starts at `0`. The
|
|
363
|
+
* `default` grid has no width of its own: when other grids exist it is included, named `default`,
|
|
364
|
+
* starting one pixel past the widest `max-width`. A manifest with only the `default` grid (the
|
|
365
|
+
* stock Forge export) returns `{}`. MUI's `values` replaces its defaults rather than merging, so
|
|
366
|
+
* spread MUI's own defaults first: `values: { ...createTheme().breakpoints.values, ...result }`.
|
|
367
|
+
*
|
|
368
|
+
* Throws for a non-default grid with neither width, for non-numeric widths, and when no other grid
|
|
369
|
+
* has a `max-width` for `default` to start after.
|
|
370
|
+
*/
|
|
371
|
+
export declare function breakpointsFromRecManifest(manifest: ManifestWithLayoutGrids): Record<string, number>;
|
|
372
|
+
|
|
355
373
|
/**
|
|
356
374
|
* Recursica Button component wrapping MUI's Button.
|
|
357
375
|
*
|
|
@@ -620,32 +638,6 @@ export declare const FormControlWrapper: default_2.ForwardRefExoticComponent<Omi
|
|
|
620
638
|
|
|
621
639
|
export declare type FormControlWrapperProps = RecursicaFormControlWrapperProps;
|
|
622
640
|
|
|
623
|
-
export declare const Grid: GridComponent;
|
|
624
|
-
|
|
625
|
-
declare const GridBase: ForwardRefExoticComponent<Omit<GridProps, "ref"> & RefAttributes<HTMLDivElement>>;
|
|
626
|
-
|
|
627
|
-
export declare const GridCol: ForwardRefExoticComponent<Omit<GridColProps, "ref"> & RefAttributes<HTMLDivElement>>;
|
|
628
|
-
|
|
629
|
-
export declare type GridColProps = WithRecursicaSpacing<OmitSx<Omit<GridProps_2, "container" | "order">>> & RecursicaGridColProps & {
|
|
630
|
-
/** Sets the CSS `order` property. Applied via inline style — see notes above. */
|
|
631
|
-
order?: number;
|
|
632
|
-
/** Hides the column below the given breakpoint. MUI has no native equivalent. */
|
|
633
|
-
visibleFrom?: Breakpoint;
|
|
634
|
-
/** Hides the column above the given breakpoint. MUI has no native equivalent. */
|
|
635
|
-
hiddenFrom?: Breakpoint;
|
|
636
|
-
};
|
|
637
|
-
|
|
638
|
-
declare type GridComponent = typeof GridBase & {
|
|
639
|
-
Col: typeof GridCol;
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
export declare type GridProps = WithRecursicaSpacing<OmitSx<Omit<GridProps_2, "container" | "justifyContent" | "alignItems" | "spacing" | "columnSpacing" | "rowSpacing" | "columns">>> & RecursicaGridProps & {
|
|
643
|
-
/** Sets `justify-content` on the container. Applied via inline style — see notes above. */
|
|
644
|
-
justifyContent?: CSSProperties["justifyContent"];
|
|
645
|
-
/** Sets `align-items` on the container. Applied via inline style — see notes above. */
|
|
646
|
-
alignItems?: CSSProperties["alignItems"];
|
|
647
|
-
};
|
|
648
|
-
|
|
649
641
|
export declare const Group: ForwardRefExoticComponent<Omit<GroupProps, "ref"> & RefAttributes<HTMLDivElement>>;
|
|
650
642
|
|
|
651
643
|
declare interface GroupOwnProps {
|
|
@@ -724,6 +716,32 @@ export declare interface LabelProps extends InputLabelProps, RecursicaLabelProps
|
|
|
724
716
|
overStyled?: boolean;
|
|
725
717
|
}
|
|
726
718
|
|
|
719
|
+
export declare const LayoutGrid: LayoutGridComponent;
|
|
720
|
+
|
|
721
|
+
declare const LayoutGridBase: ForwardRefExoticComponent<Omit<LayoutGridProps, "ref"> & RefAttributes<HTMLDivElement>>;
|
|
722
|
+
|
|
723
|
+
export declare const LayoutGridCol: ForwardRefExoticComponent<Omit<LayoutGridColProps, "ref"> & RefAttributes<HTMLDivElement>>;
|
|
724
|
+
|
|
725
|
+
export declare type LayoutGridColProps = WithRecursicaSpacing<OmitSx<Omit<GridProps, "container" | "order">>> & RecursicaLayoutGridColProps & {
|
|
726
|
+
/** Sets the CSS `order` property. Applied via inline style. */
|
|
727
|
+
order?: number;
|
|
728
|
+
/** Hides the column below the given breakpoint. MUI has no native equivalent. */
|
|
729
|
+
visibleFrom?: Breakpoint;
|
|
730
|
+
/** Hides the column above the given breakpoint. MUI has no native equivalent. */
|
|
731
|
+
hiddenFrom?: Breakpoint;
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
declare type LayoutGridComponent = typeof LayoutGridBase & {
|
|
735
|
+
Col: typeof LayoutGridCol;
|
|
736
|
+
};
|
|
737
|
+
|
|
738
|
+
export declare type LayoutGridProps = WithRecursicaSpacing<OmitSx<Omit<GridProps, "container" | "justifyContent" | "alignItems" | "spacing" | "columnSpacing" | "rowSpacing" | "columns">>> & RecursicaLayoutGridProps & {
|
|
739
|
+
/** Sets `justify-content` on the container. Applied via inline style. */
|
|
740
|
+
justifyContent?: CSSProperties["justifyContent"];
|
|
741
|
+
/** Sets `align-items` on the container. Applied via inline style. */
|
|
742
|
+
alignItems?: CSSProperties["alignItems"];
|
|
743
|
+
};
|
|
744
|
+
|
|
727
745
|
export declare const Link: ForwardRefExoticComponent<(Omit<Omit<WithRecursicaSpacing<Omit<LinkProps_2, "underline"> & RecursicaLinkProps>, "className" | "classes" | "style" | "sx" | "color" | "bgcolor" | "backgroundColor" | "typography" | "fontFamily" | "fontSize" | "fontWeight" | "lineHeight" | "letterSpacing" | "textAlign" | "border" | "borderTop" | "borderBottom" | "borderLeft" | "borderRight" | "borderColor" | "borderRadius" | "boxShadow" | "display" | "position" | "zIndex" | "p" | "py" | "px" | "pt" | "pb" | "pl" | "pr" | "classNames" | "styles" | "vars" | "bg" | "c" | "opacity" | "ff" | "fz" | "fw" | "lts" | "ta" | "lh" | "fs" | "tt" | "td" | "bd" | "bdw" | "bds" | "bdc" | "bdr" | "shadow" | "w" | "miw" | "maw" | "h" | "mih" | "mah"> & Omit<ForbiddenStyles, never> & {
|
|
728
746
|
overStyled?: false | undefined;
|
|
729
747
|
}, "ref"> | Omit<Omit<Omit<LinkProps_2, "underline"> & RecursicaLinkProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap" | "gutter" | "spacing"> & {
|
|
@@ -749,6 +767,12 @@ export declare const Loader: default_2.ForwardRefExoticComponent<LoaderProps & d
|
|
|
749
767
|
|
|
750
768
|
export declare type LoaderProps = RecursicaOverStyled<default_2.HTMLAttributes<HTMLSpanElement> & RecursicaLoaderProps>;
|
|
751
769
|
|
|
770
|
+
declare interface ManifestWithLayoutGrids {
|
|
771
|
+
brand?: {
|
|
772
|
+
"layout-grids"?: Record<string, unknown>;
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
|
|
752
776
|
export declare const Menu: ForwardRefExoticComponent<(Omit<Omit<WithRecursicaSpacing<MenuProps_2 & RecursicaMenuProps>, "className" | "classes" | "style" | "sx" | "color" | "bgcolor" | "backgroundColor" | "typography" | "fontFamily" | "fontSize" | "fontWeight" | "lineHeight" | "letterSpacing" | "textAlign" | "border" | "borderTop" | "borderBottom" | "borderLeft" | "borderRight" | "borderColor" | "borderRadius" | "boxShadow" | "display" | "position" | "zIndex" | "p" | "py" | "px" | "pt" | "pb" | "pl" | "pr" | "classNames" | "styles" | "vars" | "bg" | "c" | "opacity" | "ff" | "fz" | "fw" | "lts" | "ta" | "lh" | "fs" | "tt" | "td" | "bd" | "bdw" | "bds" | "bdc" | "bdr" | "shadow" | "w" | "miw" | "maw" | "h" | "mih" | "mah"> & Omit<ForbiddenStyles, never> & {
|
|
753
777
|
overStyled?: false | undefined;
|
|
754
778
|
}, "ref"> | Omit<Omit<MenuProps_2 & RecursicaMenuProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap" | "gutter" | "spacing"> & {
|
|
@@ -902,6 +926,8 @@ declare const ModalTitle: default_2.ForwardRefExoticComponent<(Omit<Omit<WithRec
|
|
|
902
926
|
|
|
903
927
|
export declare type ModalTitleProps = RecursicaOverStyled<DialogTitleProps>;
|
|
904
928
|
|
|
929
|
+
declare type NavControl = "first" | "previous" | "next" | "last";
|
|
930
|
+
|
|
905
931
|
export declare const NumberInput: default_2.ForwardRefExoticComponent<(Omit<Omit<WithRecursicaSpacing<RecursicaNumberInputProps>, "className" | "classes" | "style" | "sx" | "color" | "bgcolor" | "backgroundColor" | "typography" | "fontFamily" | "fontSize" | "fontWeight" | "lineHeight" | "letterSpacing" | "textAlign" | "border" | "borderTop" | "borderBottom" | "borderLeft" | "borderRight" | "borderColor" | "borderRadius" | "boxShadow" | "display" | "position" | "zIndex" | "p" | "py" | "px" | "pt" | "pb" | "pl" | "pr" | "classNames" | "styles" | "vars" | "bg" | "c" | "opacity" | "ff" | "fz" | "fw" | "lts" | "ta" | "lh" | "fs" | "tt" | "td" | "bd" | "bdw" | "bds" | "bdc" | "bdr" | "shadow" | "w" | "miw" | "maw" | "h" | "mih" | "mah"> & Omit<ForbiddenStyles, never> & {
|
|
906
932
|
overStyled?: false | undefined;
|
|
907
933
|
}, "ref"> | Omit<Omit<RecursicaNumberInputProps, "m" | "my" | "mx" | "mt" | "mb" | "ml" | "mr" | "gap" | "rowGap" | "columnGap" | "gutter" | "spacing"> & {
|
|
@@ -926,28 +952,20 @@ export declare type NumberInputProps = RecursicaOverStyled<RecursicaNumberInputP
|
|
|
926
952
|
declare type OmitSx<T> = Omit<T, "sx">;
|
|
927
953
|
|
|
928
954
|
/**
|
|
929
|
-
* Recursica Pagination
|
|
955
|
+
* Recursica Pagination. Its page and navigation buttons are Recursica `Button`s whose style and
|
|
956
|
+
* size come from the manifest's `ui-kit.components.pagination` selected variants. Requires the
|
|
957
|
+
* `manifest` prop on `RecursicaThemeProvider`.
|
|
930
958
|
*/
|
|
931
|
-
export declare const Pagination: ForwardRefExoticComponent<
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
gap?: string | number | RecursicaSpacing;
|
|
942
|
-
rowGap?: string | number | RecursicaSpacing;
|
|
943
|
-
columnGap?: string | number | RecursicaSpacing;
|
|
944
|
-
gutter?: string | number | RecursicaSpacing;
|
|
945
|
-
spacing?: string | number | RecursicaSpacing;
|
|
946
|
-
} & {
|
|
947
|
-
overStyled: true;
|
|
948
|
-
}, "ref">) & RefAttributes<HTMLDivElement>>;
|
|
949
|
-
|
|
950
|
-
export declare type PaginationProps = RecursicaOverStyled<PaginationProps_2 & RecursicaPaginationProps>;
|
|
959
|
+
export declare const Pagination: ForwardRefExoticComponent<PaginationProps & RefAttributes<HTMLElement>>;
|
|
960
|
+
|
|
961
|
+
export declare type PaginationProps = RecursicaOverStyled<RecursicaPaginationProps & Pick<UsePaginationProps, "page" | "defaultPage" | "onChange" | "siblingCount" | "boundaryCount" | "disabled"> & {
|
|
962
|
+
/** Extra props for each page button */
|
|
963
|
+
getItemProps?: (page: number) => Record<string, unknown>;
|
|
964
|
+
/** Extra props for each first/previous/next/last button */
|
|
965
|
+
getControlProps?: (control: NavControl) => Record<string, unknown>;
|
|
966
|
+
/** Replaces the dots between page ranges */
|
|
967
|
+
dotsIcon?: ReactNode;
|
|
968
|
+
} & Omit<ComponentPropsWithoutRef<"nav">, "onChange" | "children">>;
|
|
951
969
|
|
|
952
970
|
export declare const Panel: PanelComponent;
|
|
953
971
|
|
package/llms.txt
CHANGED
|
@@ -40,11 +40,11 @@ Each component has its own `USAGE.md` documenting its props, adapter-specific be
|
|
|
40
40
|
- [Flex](src/components/Flex/USAGE.md)
|
|
41
41
|
- [FormControlLayout](src/components/FormControlLayout/USAGE.md)
|
|
42
42
|
- [FormControlWrapper](src/components/FormControlWrapper/USAGE.md)
|
|
43
|
-
- [Grid](src/components/Grid/USAGE.md)
|
|
44
43
|
- [Group](src/components/Group/USAGE.md)
|
|
45
44
|
- [HoverCard](src/components/HoverCard/USAGE.md)
|
|
46
45
|
- [Label](src/components/Label/USAGE.md)
|
|
47
46
|
- [Layer](src/components/Layer/USAGE.md)
|
|
47
|
+
- [LayoutGrid](src/components/LayoutGrid/USAGE.md)
|
|
48
48
|
- [Link](src/components/Link/USAGE.md)
|
|
49
49
|
- [Loader](src/components/Loader/USAGE.md)
|
|
50
50
|
- [Menu](src/components/Menu/USAGE.md)
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"type": "git",
|
|
13
13
|
"url": "git+https://github.com/borderux/recursica-adapter-mui-v7.git"
|
|
14
14
|
},
|
|
15
|
-
"version": "1.
|
|
15
|
+
"version": "1.3.0",
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
@@ -83,9 +83,9 @@
|
|
|
83
83
|
"@mui/x-date-pickers": "^9.11.0",
|
|
84
84
|
"@mui/x-tree-view": "^9.11.0",
|
|
85
85
|
"@playwright/test": "^1.62.1",
|
|
86
|
-
"@recursica/adapter-tester": "^5.
|
|
86
|
+
"@recursica/adapter-tester": "^5.3.1",
|
|
87
87
|
"@recursica/recursica-postcss-vars": "^1.5.0",
|
|
88
|
-
"@recursica/storybook-template": "^0.7.
|
|
88
|
+
"@recursica/storybook-template": "^0.7.15",
|
|
89
89
|
"@recursica/token-analyzer": "^1.8.0",
|
|
90
90
|
"@storybook/addon-a11y": "^10.3.3",
|
|
91
91
|
"@storybook/addon-docs": "^10.3.3",
|
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"vitest": "^3.2.4"
|
|
123
123
|
},
|
|
124
124
|
"dependencies": {
|
|
125
|
-
"@recursica/adapter-common": "^
|
|
125
|
+
"@recursica/adapter-common": "^1.1.1",
|
|
126
126
|
"@recursica/official-release": "^2.8.0",
|
|
127
127
|
"dayjs": "^1.11.21"
|
|
128
128
|
},
|
package/recursica_brand.json
CHANGED
package/recursica_tokens.json
CHANGED
package/recursica_ui-kit.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Recursica CSS Variables - Scoped
|
|
3
|
-
* Transform version: 1.
|
|
4
|
-
* Source JSON version: 0.
|
|
5
|
-
* Generated:
|
|
3
|
+
* Transform version: 1.4.0
|
|
4
|
+
* Source JSON version: 0.29.0
|
|
5
|
+
* Generated: Fri, 02 Oct 2026 22:19:36 GMT
|
|
6
6
|
*
|
|
7
7
|
* --- How to integrate this file ---
|
|
8
8
|
*
|
|
@@ -133,10 +133,14 @@
|
|
|
133
133
|
--recursica_brand_layer_1_elements_interactive_tone: var(--recursica_tokens_colors_scale-06_400);
|
|
134
134
|
--recursica_brand_layer_2_elements_interactive_tone: var(--recursica_tokens_colors_scale-06_400);
|
|
135
135
|
--recursica_brand_layer_3_elements_interactive_tone: var(--recursica_tokens_colors_scale-06_400);
|
|
136
|
+
--recursica_brand_layout-grids_column-gutter: var(--recursica_brand_layout-grids_default_column-gutter);
|
|
137
|
+
--recursica_brand_layout-grids_columns: var(--recursica_brand_layout-grids_default_columns);
|
|
136
138
|
--recursica_brand_layout-grids_default_column-gutter: var(--recursica_tokens_sizes_2x);
|
|
137
139
|
--recursica_brand_layout-grids_default_columns: 6;
|
|
138
140
|
--recursica_brand_layout-grids_default_margin: var(--recursica_tokens_sizes_3x);
|
|
139
141
|
--recursica_brand_layout-grids_default_row-gutter: var(--recursica_tokens_sizes_3x);
|
|
142
|
+
--recursica_brand_layout-grids_margin: var(--recursica_brand_layout-grids_default_margin);
|
|
143
|
+
--recursica_brand_layout-grids_row-gutter: var(--recursica_brand_layout-grids_default_row-gutter);
|
|
140
144
|
--recursica_brand_modes_dark_elevations_elevation-0: var(--recursica_brand_modes_dark_elevations_elevation-0_x) var(--recursica_brand_modes_dark_elevations_elevation-0_y) var(--recursica_brand_modes_dark_elevations_elevation-0_blur) var(--recursica_brand_modes_dark_elevations_elevation-0_spread) var(--recursica_brand_modes_dark_elevations_elevation-0_color);
|
|
141
145
|
--recursica_brand_modes_dark_elevations_elevation-0_blur: 0px;
|
|
142
146
|
--recursica_brand_modes_dark_elevations_elevation-0_color: var(--recursica_brand_modes_dark_palettes_neutral_500_color_tone);
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
/* SideBySide Variant */
|
|
22
22
|
.groupRoot[data-layout="side-by-side"] {
|
|
23
23
|
flex-direction: column;
|
|
24
|
-
flex-wrap:
|
|
24
|
+
flex-wrap: nowrap;
|
|
25
25
|
padding-top: var(
|
|
26
26
|
--recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_vertical-padding
|
|
27
27
|
);
|
|
@@ -278,8 +278,6 @@
|
|
|
278
278
|
);
|
|
279
279
|
}
|
|
280
280
|
.groupRoot[data-layout="side-by-side"] {
|
|
281
|
-
flex-direction: row;
|
|
282
|
-
flex-wrap: wrap;
|
|
283
281
|
gap: var(
|
|
284
282
|
--recursica_ui-kit_components_checkbox-group_variants_layouts_side-by-side_properties_gutter
|
|
285
283
|
);
|
|
@@ -35,7 +35,6 @@ All Recursica components in the `@recursica/adapter-mui-v7` package adhere stric
|
|
|
35
35
|
|
|
36
36
|
> [!IMPORTANT]
|
|
37
37
|
>
|
|
38
|
-
> - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
39
38
|
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
40
39
|
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
41
40
|
|
|
@@ -52,6 +52,14 @@
|
|
|
52
52
|
min-height: var(
|
|
53
53
|
--recursica_ui-kit_components_file-input_properties_min-height
|
|
54
54
|
);
|
|
55
|
+
/* Fixed height (icon + padding + border) so the nested clear Button overflows the row instead of growing the control. */
|
|
56
|
+
height: calc(
|
|
57
|
+
var(--recursica_ui-kit_components_file-input_properties_icon-size) + 2 *
|
|
58
|
+
var(
|
|
59
|
+
--recursica_ui-kit_components_file-input_properties_vertical-padding
|
|
60
|
+
) +
|
|
61
|
+
2 * var(--recursica_ui-kit_components_file-input_properties_border-size)
|
|
62
|
+
);
|
|
55
63
|
gap: var(--recursica_ui-kit_components_file-input_properties_icon-text-gap);
|
|
56
64
|
padding-top: var(
|
|
57
65
|
--recursica_ui-kit_components_file-input_properties_vertical-padding
|
|
@@ -36,6 +36,7 @@ All Recursica components in the `@recursica/adapter-mui-v7` package adhere stric
|
|
|
36
36
|
|
|
37
37
|
> [!IMPORTANT]
|
|
38
38
|
>
|
|
39
|
-
> - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
40
39
|
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
41
40
|
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
41
|
+
|
|
42
|
+
> [!NOTE] > **Responsive props use your MUI theme's breakpoints, not Forge's.** Keys such as `{ xs, sm, md }` come from `theme.breakpoints`; Forge's layout grids switch via plain CSS `@media` and never edit the MUI theme. Build your theme with `breakpointsFromRecManifest` so the two agree (see [LayoutGrid](../LayoutGrid/USAGE.md)).
|
|
@@ -36,6 +36,7 @@ All Recursica components in the `@recursica/adapter-mui-v7` package adhere stric
|
|
|
36
36
|
|
|
37
37
|
> [!IMPORTANT]
|
|
38
38
|
>
|
|
39
|
-
> - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
|
|
40
39
|
> - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
|
|
41
40
|
> - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
|
|
41
|
+
|
|
42
|
+
> [!NOTE] > **Responsive props use your MUI theme's breakpoints, not Forge's.** Keys such as `{ xs, sm, md }` come from `theme.breakpoints`; Forge's layout grids switch via plain CSS `@media` and never edit the MUI theme. Build your theme with `breakpointsFromRecManifest` so the two agree (see [LayoutGrid](../LayoutGrid/USAGE.md)).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# LayoutGrid Implementation Notes
|
|
2
|
+
|
|
3
|
+
`LayoutGrid` is the Recursica layout grid. MUI has no native Grid/Grid.Col split: its `Grid`
|
|
4
|
+
merges "container" and "item" behavior into one component (toggled by `container` and a `size`
|
|
5
|
+
prop). `LayoutGrid` always renders `<MuiGrid container>` and `LayoutGrid.Col` renders `<MuiGrid>`
|
|
6
|
+
in item mode, to keep the same dot-notation shape as the Mantine adapter. It was named `Grid`
|
|
7
|
+
before 2026-10-05.
|
|
8
|
+
|
|
9
|
+
Unlike the other primitive layout components (`Flex`, `Stack`, `Group`, `Container`), it has a
|
|
10
|
+
formal Recursica prop contract (`RecursicaLayoutGridProps` in `adapter-common`) and wires the
|
|
11
|
+
design system's `layout-grids` tokens. Its other props are MUI's own vocabulary, not a shared
|
|
12
|
+
contract:
|
|
13
|
+
|
|
14
|
+
- **`size`** (not Mantine's `span`): a column count, `"auto"`, `"grow"`, or a responsive object keyed by
|
|
15
|
+
MUI's breakpoints (`xs`/`sm`/`md`/`lg`/`xl`, no `"base"`). It renames to `span` when
|
|
16
|
+
`RecursicaLayoutGridColProps` picks `span` up (queued in `adapter-common`).
|
|
17
|
+
- **`offset`**: MUI's own prop, used as is.
|
|
18
|
+
- **`grow` (container)**: not implemented; use `size="grow"` per column.
|
|
19
|
+
- **`order`, `justifyContent`, `alignItems`**: typed by MUI but never read by its Grid generator
|
|
20
|
+
(`@mui/system` `gridGenerator`), so they're applied via inline `style`.
|
|
21
|
+
- **`visibleFrom` / `hiddenFrom`**: no MUI mechanism, so `LayoutGrid.module.css` has media-query
|
|
22
|
+
classes hardcoded to MUI's default breakpoints (0/600/900/1200/1536). They do not follow a
|
|
23
|
+
customized `theme.breakpoints`.
|
|
24
|
+
|
|
25
|
+
## Forge contract
|
|
26
|
+
|
|
27
|
+
Forge always emits a default grid with columns (default 6, editable), column-gutter, row-gutter and
|
|
28
|
+
side margin, in the CSS and in `recursica_manifest.json`. Additional breakpoints are overrides, so
|
|
29
|
+
nothing here has a fallback value.
|
|
30
|
+
|
|
31
|
+
## No integrator-facing layout props
|
|
32
|
+
|
|
33
|
+
Columns, column-gutter, row-gutter and margin are design-system-managed, not per-instance settings.
|
|
34
|
+
`columns`, `spacing`, `columnSpacing` and `rowSpacing` were removed from the public type and are
|
|
35
|
+
deleted at runtime so they can't shadow the token-driven values. For an arbitrary N-column grid,
|
|
36
|
+
use MUI's `Grid` directly.
|
|
37
|
+
|
|
38
|
+
## How each token is applied
|
|
39
|
+
|
|
40
|
+
Forge emits a responsive alias per grid var (`--recursica_brand_layout-grids_{columns,row-gutter,column-gutter,margin}`),
|
|
41
|
+
set from `_default_*` at `:root` and redefined inside Forge's `@media` blocks per non-default grid.
|
|
42
|
+
`LayoutGrid` reads only the alias, so tokens follow breakpoints with no JS. Overlapping ranges are
|
|
43
|
+
not guarded by Forge; the later `@media` block wins.
|
|
44
|
+
|
|
45
|
+
- **Columns**: MUI's Grid computes widths in CSS from `--Grid-parent-columns`, so unlike Mantine no
|
|
46
|
+
per-column style rule is needed. `LayoutGrid` passes the alias as `columns`
|
|
47
|
+
(`var(--recursica_brand_layout-grids_columns)`); MUI types it as a number but writes it
|
|
48
|
+
verbatim into the custom property, which the width `calc()` then reads. Verified in
|
|
49
|
+
`@mui/system`'s `gridGenerator`.
|
|
50
|
+
- **Column gutter / row gutter**: passed to MUI's own `columnSpacing`/`rowSpacing` as the
|
|
51
|
+
responsive aliases. MUI applies each independently (strings are not multiplied by `theme.spacing`).
|
|
52
|
+
- **Margin**: no MUI Grid prop equivalent; `.root` in `LayoutGrid.module.css` reads it directly.
|
|
53
|
+
- **Clamping**: MUI's width calc does not clamp, so `size={6}` at 3 columns would overflow.
|
|
54
|
+
`.col { max-width: 100% }` makes it fill the row instead, matching Mantine's `min(span, columns)`.
|
|
55
|
+
|
|
56
|
+
## Breakpoints
|
|
57
|
+
|
|
58
|
+
Responsive `size`/`offset` switch at the MUI theme's breakpoints, which Forge never edits.
|
|
59
|
+
Integrators should merge `breakpointsFromRecManifest(manifest)` into `theme.breakpoints.values`
|
|
60
|
+
so both switch at the same widths (MUI's `values` replaces its defaults, so spread them first;
|
|
61
|
+
see SETUP.md). `RecursicaThemeProvider` is UI-kit agnostic and does not compare the manifest
|
|
62
|
+
against the theme. The helper returns numbers (MUI's unit), not the `"Npx"` strings the Mantine
|
|
63
|
+
one returns.
|
|
64
|
+
|
|
65
|
+
## `LayoutGrid.Col` contract is scaffolded
|
|
66
|
+
|
|
67
|
+
`RecursicaLayoutGridColProps` currently only contributes `children`; `span`, `order`,
|
|
68
|
+
`visibleFrom` and `hiddenFrom` are drafted and commented out in `adapter-common`. No runtime
|
|
69
|
+
effect here.
|
|
70
|
+
|
|
71
|
+
## Brand-layer exemption
|
|
72
|
+
|
|
73
|
+
`layout-grids` tokens have no `ui-kit` layer in Forge's model, so `LayoutGrid.module.css` reads
|
|
74
|
+
`brand_layout-grids_margin` directly with a `recursica-allow-brand:` header. The other three are
|
|
75
|
+
read in `LayoutGrid.tsx` (a TSX prop value), which the analyzer does not scan.
|
|
76
|
+
|
|
77
|
+
## Stories
|
|
78
|
+
|
|
79
|
+
A single `Default` story reads `brand.layout-grids.default.columns` from the manifest (via
|
|
80
|
+
`useRecursicaManifest()`) and fills two rows of that many single-column cells. Same story id as the
|
|
81
|
+
Mantine adapter's, so it diffs against its golden. Only `size` is used, so the story stays valid
|
|
82
|
+
for every adapter.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import { flushSync } from "react-dom";
|
|
4
|
+
import { StyledEngineProvider } from "@mui/material/styles";
|
|
5
|
+
import { LayoutGrid } from "./LayoutGrid";
|
|
6
|
+
|
|
7
|
+
function mount(node: React.ReactElement) {
|
|
8
|
+
const container = document.createElement("div");
|
|
9
|
+
document.body.appendChild(container);
|
|
10
|
+
const root = createRoot(container);
|
|
11
|
+
// injectFirst, as RecursicaThemeProvider does, so the component CSS beats MUI's.
|
|
12
|
+
flushSync(() =>
|
|
13
|
+
root.render(
|
|
14
|
+
<StyledEngineProvider injectFirst>{node}</StyledEngineProvider>,
|
|
15
|
+
),
|
|
16
|
+
);
|
|
17
|
+
return {
|
|
18
|
+
container,
|
|
19
|
+
done: () => {
|
|
20
|
+
root.unmount();
|
|
21
|
+
container.remove();
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
describe("LayoutGrid tokens", () => {
|
|
27
|
+
it("takes columns and gutters from the responsive Forge variables", () => {
|
|
28
|
+
document.documentElement.style.setProperty(
|
|
29
|
+
"--recursica_brand_layout-grids_columns",
|
|
30
|
+
"3",
|
|
31
|
+
);
|
|
32
|
+
document.documentElement.style.setProperty(
|
|
33
|
+
"--recursica_brand_layout-grids_column-gutter",
|
|
34
|
+
"10px",
|
|
35
|
+
);
|
|
36
|
+
document.documentElement.style.setProperty(
|
|
37
|
+
"--recursica_brand_layout-grids_row-gutter",
|
|
38
|
+
"20px",
|
|
39
|
+
);
|
|
40
|
+
const { container, done } = mount(
|
|
41
|
+
<LayoutGrid>
|
|
42
|
+
<LayoutGrid.Col size={1}>a</LayoutGrid.Col>
|
|
43
|
+
</LayoutGrid>,
|
|
44
|
+
);
|
|
45
|
+
const grid = container.querySelector(".MuiGrid-container") as HTMLElement;
|
|
46
|
+
const style = getComputedStyle(grid);
|
|
47
|
+
expect(style.getPropertyValue("--Grid-columns").trim()).toBe("3");
|
|
48
|
+
expect(style.getPropertyValue("--Grid-columnSpacing").trim()).toBe("10px");
|
|
49
|
+
expect(style.getPropertyValue("--Grid-rowSpacing").trim()).toBe("20px");
|
|
50
|
+
done();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("drops columns and spacing props passed at runtime", () => {
|
|
54
|
+
const { container, done } = mount(
|
|
55
|
+
<LayoutGrid {...({ columns: 12, spacing: 8 } as Record<string, unknown>)}>
|
|
56
|
+
<LayoutGrid.Col size={1}>a</LayoutGrid.Col>
|
|
57
|
+
</LayoutGrid>,
|
|
58
|
+
);
|
|
59
|
+
const grid = container.querySelector(".MuiGrid-container") as HTMLElement;
|
|
60
|
+
expect(
|
|
61
|
+
getComputedStyle(grid).getPropertyValue("--Grid-columns").trim(),
|
|
62
|
+
).toBe("3");
|
|
63
|
+
done();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("clamps a column wider than the grid to the row", () => {
|
|
67
|
+
const { container, done } = mount(
|
|
68
|
+
<LayoutGrid>
|
|
69
|
+
<LayoutGrid.Col size={6}>a</LayoutGrid.Col>
|
|
70
|
+
</LayoutGrid>,
|
|
71
|
+
);
|
|
72
|
+
const col = container.querySelector(
|
|
73
|
+
".MuiGrid-container > div",
|
|
74
|
+
) as HTMLElement;
|
|
75
|
+
expect(getComputedStyle(col).maxWidth).toBe("100%");
|
|
76
|
+
done();
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -3,25 +3,26 @@
|
|
|
3
3
|
* - Breakpoint pixel thresholds below (600/900/1200/1536) match MUI's own default
|
|
4
4
|
* theme.breakpoints (xs/sm/md/lg/xl). They drive `visibleFrom`/`hiddenFrom`, which
|
|
5
5
|
* have no native MUI Grid equivalent to hook into. If the consuming app customizes
|
|
6
|
-
* its MUI theme breakpoints, these thresholds will not follow that change
|
|
6
|
+
* its MUI theme breakpoints, these thresholds will not follow that change:
|
|
7
7
|
* structural layout mechanics, not a design token.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
/* Brand-layer exemption (recursica-allow-brand)
|
|
10
|
+
/* Brand-layer exemption (recursica-allow-brand): layout-grid tokens have no ui-kit-layer
|
|
11
11
|
* representation in Forge's model (a grid is a page-layout primitive, not a "component"), so
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* recursica-allow-brand: --recursica_brand_layout-grids_default_margin
|
|
12
|
+
* LayoutGrid reads the responsive brand_layout-grids_* alias directly (Forge redefines it per
|
|
13
|
+
* breakpoint inside @media). Columns, column-gutter and row-gutter are applied in
|
|
14
|
+
* LayoutGrid.tsx through MUI's own props; `margin` has no MUI Grid prop equivalent, so it's
|
|
15
|
+
* applied here. See LAYOUT_GRID_IMPLEMENTATION_NOTES.md.
|
|
16
|
+
* recursica-allow-brand: --recursica_brand_layout-grids_margin
|
|
18
17
|
*/
|
|
19
18
|
|
|
20
|
-
.root
|
|
21
|
-
margin: var(--recursica_brand_layout-
|
|
19
|
+
.root {
|
|
20
|
+
margin: var(--recursica_brand_layout-grids_margin);
|
|
22
21
|
}
|
|
23
22
|
|
|
23
|
+
/* A numeric size larger than the current column count fills the row instead of overflowing. */
|
|
24
24
|
.col {
|
|
25
|
+
max-width: 100%;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
.hiddenFromXs {
|