@recursica/mui-adapter 0.5.0 → 0.7.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.
Files changed (212) hide show
  1. package/ARCHITECTURE.md +15 -0
  2. package/CHANGELOG.md +15 -0
  3. package/SETUP.md +77 -0
  4. package/USAGE.md +55 -0
  5. package/dist/mui-adapter.cjs +74 -1
  6. package/dist/mui-adapter.cjs.map +1 -1
  7. package/dist/mui-adapter.css +1 -1
  8. package/dist/mui-adapter.js +6863 -205
  9. package/dist/mui-adapter.js.map +1 -1
  10. package/dist/src/components/Accordion/Accordion.d.ts +43 -2
  11. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +6 -2
  12. package/dist/src/components/Autocomplete/Autocomplete.d.ts +12 -2
  13. package/dist/src/components/Avatar/Avatar.d.ts +10 -3
  14. package/dist/src/components/Badge/Badge.d.ts +10 -3
  15. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +9 -3
  16. package/dist/src/components/Button/Button.d.ts +2 -17
  17. package/dist/src/components/Card/Card.d.ts +38 -3
  18. package/dist/src/components/Checkbox/Checkbox.d.ts +13 -2
  19. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +18 -0
  20. package/dist/src/components/Checkbox/index.d.ts +5 -1
  21. package/dist/src/components/Chip/Chip.d.ts +9 -2
  22. package/dist/src/components/Container/Container.d.ts +1 -5
  23. package/dist/src/components/DatePicker/DatePicker.d.ts +2 -1
  24. package/dist/src/components/Dropdown/Dropdown.d.ts +12 -2
  25. package/dist/src/components/Flex/Flex.d.ts +2 -22
  26. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +5 -2
  27. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +9 -2
  28. package/dist/src/components/Group/Group.d.ts +2 -7
  29. package/dist/src/components/HoverCard/HoverCard.d.ts +28 -2
  30. package/dist/src/components/Label/Label.d.ts +6 -2
  31. package/dist/src/components/Link/Link.d.ts +2 -6
  32. package/dist/src/components/Loader/Loader.d.ts +2 -7
  33. package/dist/src/components/Menu/Menu.d.ts +25 -3
  34. package/dist/src/components/Modal/Modal.d.ts +37 -2
  35. package/dist/src/components/NumberInput/NumberInput.d.ts +12 -2
  36. package/dist/src/components/Pagination/Pagination.d.ts +12 -3
  37. package/dist/src/components/Pagination/Pagination.icons.d.ts +8 -0
  38. package/dist/src/components/Panel/Panel.d.ts +52 -3
  39. package/dist/src/components/Radio/Radio.d.ts +13 -3
  40. package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
  41. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  42. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +4 -2
  43. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  44. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  45. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
  46. package/dist/src/components/ReadOnlyField/index.d.ts +1 -0
  47. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +21 -3
  48. package/dist/src/components/Slider/Slider.d.ts +18 -2
  49. package/dist/src/components/Stack/Stack.d.ts +2 -5
  50. package/dist/src/components/Stepper/Stepper.d.ts +41 -2
  51. package/dist/src/components/Switch/Switch.d.ts +10 -3
  52. package/dist/src/components/Switch/SwitchGroup.d.ts +13 -0
  53. package/dist/src/components/Table/Table.d.ts +2 -1
  54. package/dist/src/components/Tabs/Tabs.d.ts +20 -3
  55. package/dist/src/components/Text/Text.d.ts +2 -16
  56. package/dist/src/components/TextArea/TextArea.d.ts +12 -2
  57. package/dist/src/components/TextField/TextField.d.ts +12 -2
  58. package/dist/src/components/TimePicker/TimePicker.d.ts +2 -1
  59. package/dist/src/components/Timeline/Timeline.d.ts +15 -2
  60. package/dist/src/components/Timeline/TimelineItem.d.ts +18 -0
  61. package/dist/src/components/Title/Title.d.ts +2 -15
  62. package/dist/src/components/Toast/Toast.d.ts +20 -2
  63. package/dist/src/components/Tooltip/Tooltip.d.ts +28 -3
  64. package/dist/src/components/TransferList/TransferList.d.ts +2 -1
  65. package/dist/src/components/Typography/Typography.d.ts +1 -1
  66. package/dist/src/utils/RequireAccessibleLabel.d.ts +1 -18
  67. package/dist/src/utils/filterStylingProps.d.ts +1 -11
  68. package/llms.txt +16 -0
  69. package/package.json +14 -3
  70. package/src/components/Accordion/Accordion.module.css +294 -56
  71. package/src/components/Accordion/Accordion.stories.tsx +131 -21
  72. package/src/components/Accordion/Accordion.tsx +260 -5
  73. package/src/components/AssistiveElement/AssistiveElement.module.css +114 -20
  74. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +60 -20
  75. package/src/components/AssistiveElement/AssistiveElement.tsx +81 -5
  76. package/src/components/Autocomplete/Autocomplete.module.css +319 -42
  77. package/src/components/Autocomplete/Autocomplete.stories.tsx +175 -23
  78. package/src/components/Autocomplete/Autocomplete.tsx +181 -6
  79. package/src/components/Avatar/Avatar.module.css +343 -73
  80. package/src/components/Avatar/Avatar.stories.tsx +94 -22
  81. package/src/components/Avatar/Avatar.tsx +99 -6
  82. package/src/components/Badge/Badge.module.css +127 -29
  83. package/src/components/Badge/Badge.stories.tsx +65 -22
  84. package/src/components/Badge/Badge.tsx +67 -6
  85. package/src/components/Breadcrumb/Breadcrumb.module.css +25 -5
  86. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +57 -22
  87. package/src/components/Breadcrumb/Breadcrumb.tsx +59 -6
  88. package/src/components/Button/Button.module.css +19 -61
  89. package/src/components/Button/Button.stories.tsx +24 -23
  90. package/src/components/Button/Button.tsx +7 -18
  91. package/src/components/Card/Card.module.css +154 -38
  92. package/src/components/Card/Card.stories.tsx +117 -19
  93. package/src/components/Card/Card.tsx +181 -5
  94. package/src/components/Checkbox/Checkbox.module.css +249 -39
  95. package/src/components/Checkbox/Checkbox.stories.tsx +81 -19
  96. package/src/components/Checkbox/Checkbox.tsx +246 -5
  97. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  98. package/src/components/Checkbox/CheckboxGroup.tsx +137 -0
  99. package/src/components/Checkbox/index.ts +6 -1
  100. package/src/components/Chip/Chip.module.css +246 -43
  101. package/src/components/Chip/Chip.stories.tsx +101 -21
  102. package/src/components/Chip/Chip.tsx +136 -6
  103. package/src/components/Container/Container.stories.tsx +103 -20
  104. package/src/components/Container/Container.tsx +1 -13
  105. package/src/components/DatePicker/DatePicker.stories.tsx +125 -19
  106. package/src/components/DatePicker/DatePicker.tsx +3 -1
  107. package/src/components/Dropdown/Dropdown.module.css +291 -41
  108. package/src/components/Dropdown/Dropdown.stories.tsx +80 -21
  109. package/src/components/Dropdown/Dropdown.tsx +180 -6
  110. package/src/components/FileInput/FileInput.stories.tsx +2 -19
  111. package/src/components/FileUpload/FileUpload.stories.tsx +2 -19
  112. package/src/components/Flex/Flex.stories.tsx +113 -20
  113. package/src/components/Flex/Flex.tsx +16 -26
  114. package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
  115. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +67 -20
  116. package/src/components/FormControlLayout/FormControlLayout.tsx +69 -4
  117. package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
  118. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +116 -22
  119. package/src/components/FormControlWrapper/FormControlWrapper.tsx +126 -6
  120. package/src/components/Group/Group.stories.tsx +6 -30
  121. package/src/components/Group/Group.tsx +14 -9
  122. package/src/components/HoverCard/HoverCard.module.css +90 -22
  123. package/src/components/HoverCard/HoverCard.stories.tsx +158 -21
  124. package/src/components/HoverCard/HoverCard.tsx +147 -5
  125. package/src/components/Label/Label.module.css +140 -35
  126. package/src/components/Label/Label.stories.tsx +108 -21
  127. package/src/components/Label/Label.tsx +82 -5
  128. package/src/components/Link/Link.module.css +4 -3
  129. package/src/components/Link/Link.stories.tsx +2 -8
  130. package/src/components/Link/Link.tsx +1 -5
  131. package/src/components/Loader/Loader.module.css +1 -2
  132. package/src/components/Loader/Loader.tsx +1 -7
  133. package/src/components/Menu/IMPLEMENTATION_NOTES.md +4 -0
  134. package/src/components/Menu/Menu.module.css +285 -51
  135. package/src/components/Menu/Menu.stories.tsx +229 -25
  136. package/src/components/Menu/Menu.tsx +73 -6
  137. package/src/components/Modal/Modal.module.css +171 -35
  138. package/src/components/Modal/Modal.stories.tsx +66 -22
  139. package/src/components/Modal/Modal.tsx +215 -5
  140. package/src/components/NumberInput/NumberInput.module.css +276 -42
  141. package/src/components/NumberInput/NumberInput.stories.tsx +83 -20
  142. package/src/components/NumberInput/NumberInput.tsx +136 -6
  143. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +3 -0
  144. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  145. package/src/components/Pagination/Pagination.module.css +234 -20
  146. package/src/components/Pagination/Pagination.stories.tsx +34 -21
  147. package/src/components/Pagination/Pagination.tsx +74 -6
  148. package/src/components/Panel/Panel.module.css +206 -38
  149. package/src/components/Panel/Panel.stories.tsx +214 -22
  150. package/src/components/Panel/Panel.tsx +130 -5
  151. package/src/components/Radio/Radio.module.css +235 -37
  152. package/src/components/Radio/Radio.stories.tsx +77 -19
  153. package/src/components/Radio/Radio.tsx +210 -5
  154. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  155. package/src/components/Radio/RadioGroup.tsx +125 -0
  156. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  157. package/src/components/ReadOnlyField/ReadOnlyField.module.css +53 -15
  158. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +147 -19
  159. package/src/components/ReadOnlyField/ReadOnlyField.tsx +105 -5
  160. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  161. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  162. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  163. package/src/components/ReadOnlyField/index.ts +1 -0
  164. package/src/components/SegmentedControl/SegmentedControl.module.css +179 -47
  165. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +102 -20
  166. package/src/components/SegmentedControl/SegmentedControl.tsx +140 -6
  167. package/src/components/Slider/Slider.module.css +539 -86
  168. package/src/components/Slider/Slider.stories.tsx +157 -19
  169. package/src/components/Slider/Slider.tsx +283 -5
  170. package/src/components/Stack/Stack.stories.tsx +4 -25
  171. package/src/components/Stack/Stack.tsx +1 -5
  172. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +4 -0
  173. package/src/components/Stepper/Stepper.module.css +410 -71
  174. package/src/components/Stepper/Stepper.stories.tsx +146 -20
  175. package/src/components/Stepper/Stepper.tsx +147 -6
  176. package/src/components/Switch/Switch.module.css +259 -39
  177. package/src/components/Switch/Switch.stories.tsx +98 -19
  178. package/src/components/Switch/Switch.tsx +200 -6
  179. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  180. package/src/components/Switch/SwitchGroup.tsx +120 -0
  181. package/src/components/Table/Table.stories.tsx +1 -19
  182. package/src/components/Table/Table.tsx +3 -1
  183. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +4 -0
  184. package/src/components/Tabs/Tabs.module.css +422 -79
  185. package/src/components/Tabs/Tabs.stories.tsx +156 -20
  186. package/src/components/Tabs/Tabs.tsx +86 -6
  187. package/src/components/Text/Text.stories.tsx +5 -17
  188. package/src/components/Text/Text.tsx +1 -15
  189. package/src/components/TextArea/TextArea.module.css +155 -32
  190. package/src/components/TextArea/TextArea.stories.tsx +80 -21
  191. package/src/components/TextArea/TextArea.tsx +146 -6
  192. package/src/components/TextField/TextField.module.css +261 -42
  193. package/src/components/TextField/TextField.stories.tsx +147 -20
  194. package/src/components/TextField/TextField.tsx +169 -6
  195. package/src/components/TimePicker/TimePicker.stories.tsx +2 -19
  196. package/src/components/TimePicker/TimePicker.tsx +3 -1
  197. package/src/components/Timeline/Timeline.module.css +365 -76
  198. package/src/components/Timeline/Timeline.stories.tsx +114 -21
  199. package/src/components/Timeline/Timeline.tsx +83 -5
  200. package/src/components/Timeline/TimelineItem.tsx +90 -0
  201. package/src/components/Title/Title.stories.tsx +0 -18
  202. package/src/components/Title/Title.tsx +1 -7
  203. package/src/components/Toast/Toast.module.css +166 -28
  204. package/src/components/Toast/Toast.stories.tsx +54 -22
  205. package/src/components/Toast/Toast.tsx +124 -5
  206. package/src/components/Tooltip/Tooltip.module.css +89 -24
  207. package/src/components/Tooltip/Tooltip.stories.tsx +152 -22
  208. package/src/components/Tooltip/Tooltip.tsx +88 -5
  209. package/src/components/TransferList/TransferList.stories.tsx +1 -19
  210. package/src/components/TransferList/TransferList.tsx +3 -1
  211. package/src/utils/RequireAccessibleLabel.ts +1 -12
  212. package/src/utils/filterStylingProps.ts +7 -20
@@ -1,8 +1,138 @@
1
- import React from "react";
2
- import "./NumberInput.module.css";
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ TextField as MuiNumberInput,
4
+ type TextFieldProps as MuiNumberInputProps,
5
+ } from "@mui/material";
6
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
7
+ import {
8
+ filterStylingProps,
9
+ type RecursicaOverStyled,
10
+ } from "../../utils/filterStylingProps";
11
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
12
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
13
+ import styles from "./NumberInput.module.css";
3
14
 
4
- export type NumberInputProps = React.HTMLAttributes<HTMLDivElement>;
15
+ import { type RecursicaNumberInputProps as BaseRecursicaNumberInputProps } from "@recursica/adapter-common";
5
16
 
6
- export const NumberInput: React.FC<NumberInputProps> = (props) => {
7
- return <div {...props}>NumberInput</div>;
8
- };
17
+ export interface RecursicaNumberInputProps
18
+ extends Omit<
19
+ MuiNumberInputProps,
20
+ "size" | "variant" | "radius" | "wrapperProps" | "classNames" | "styles"
21
+ >,
22
+ Pick<
23
+ RecursicaFormControlWrapperProps,
24
+ | "assistiveText"
25
+ | "assistiveWithIcon"
26
+ | "formLayout"
27
+ | "labelSize"
28
+ | "labelAlignment"
29
+ | "labelOptionalText"
30
+ | "labelWithEditIcon"
31
+ | "onLabelEditClick"
32
+ >,
33
+ ReadOnlyControlProps,
34
+ BaseRecursicaNumberInputProps {}
35
+
36
+ export type NumberInputProps = RecursicaOverStyled<RecursicaNumberInputProps>;
37
+
38
+ export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>(
39
+ function NumberInput(props, ref) {
40
+ const {
41
+ overStyled = false,
42
+ formLayout = "stacked",
43
+
44
+ // Label & Wrapper Maps
45
+ labelSize,
46
+ labelAlignment,
47
+ labelOptionalText,
48
+ labelWithEditIcon,
49
+ onLabelEditClick,
50
+
51
+ label,
52
+ assistiveText,
53
+ assistiveWithIcon,
54
+ error,
55
+ required,
56
+ // removed withAsterisk
57
+ id,
58
+ className,
59
+ style,
60
+ disabled,
61
+ readOnly,
62
+ readOnlyComponent,
63
+ emptyValueComponent,
64
+ value,
65
+ defaultValue,
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ hideControls = false,
68
+ ...rest
69
+ } = props;
70
+
71
+ const sanitizedProps = filterStylingProps(rest, overStyled);
72
+ const restRecord = sanitizedProps as Record<string, unknown>;
73
+
74
+ // Delete prohibited sizing hooks from bypassing variables natively
75
+ delete restRecord["size"];
76
+ delete restRecord["variant"];
77
+ delete restRecord["radius"];
78
+
79
+ // Securely map core native blocks down ensuring nested CSS modules map precisely
80
+ const mergedClassNames: Partial<Record<string, string>> = {
81
+ wrapper: styles.root, // The nested Input internal relative wrapper bounding box
82
+ input: styles.input,
83
+ section: styles.section,
84
+ controls: styles.controls,
85
+ control: styles.control,
86
+ };
87
+
88
+ const wrapperClass = className
89
+ ? `${styles.layoutOverride} ${className}`
90
+ : styles.layoutOverride;
91
+
92
+ return (
93
+ <WithReadOnlyWrapper
94
+ className={wrapperClass}
95
+ style={style as React.CSSProperties}
96
+ controlMaxWidth="var(--recursica_ui-kit_components_number-input_properties_max-width)"
97
+ controlMinWidth="var(--recursica_ui-kit_components_number-input_properties_min-width)"
98
+ overStyled={overStyled as true}
99
+ formLayout={formLayout}
100
+ labelSize={labelSize}
101
+ labelAlignment={labelAlignment}
102
+ labelOptionalText={labelOptionalText}
103
+ labelWithEditIcon={labelWithEditIcon}
104
+ onLabelEditClick={onLabelEditClick}
105
+ label={label}
106
+ assistiveText={assistiveText}
107
+ assistiveWithIcon={assistiveWithIcon}
108
+ error={error}
109
+ required={required}
110
+ id={id}
111
+ readOnly={readOnly}
112
+ readOnlyComponent={readOnlyComponent}
113
+ emptyValueComponent={emptyValueComponent}
114
+ readOnlyType="text"
115
+ readOnlyValue={
116
+ value !== undefined ? value?.toString() : defaultValue?.toString()
117
+ }
118
+ readOnlyNativeProps={props}
119
+ activeComponent={
120
+ /* Naked Input execution safely decoupled from Mui's macro Input.Wrapper DOM hooks */
121
+ <MuiNumberInput
122
+ ref={ref}
123
+ classes={mergedClassNames}
124
+ disabled={disabled}
125
+ value={value}
126
+ defaultValue={defaultValue}
127
+ label={undefined}
128
+ error={undefined}
129
+ required={undefined}
130
+ {...(sanitizedProps as unknown as MuiNumberInputProps)}
131
+ />
132
+ }
133
+ />
134
+ );
135
+ },
136
+ );
137
+
138
+ NumberInput.displayName = "NumberInput";
@@ -0,0 +1,3 @@
1
+ # Pagination Implementation Notes
2
+
3
+ - **Compositional API Dropped:** Mantine's original `Pagination` component relies heavily on dot-notation sub-components (`Pagination.Root`, `Pagination.Items`, `Pagination.Control`, etc.). MUI's `<Pagination>` is fundamentally monolithic. Following architectural review, we have decided to drop the dot-notation wrappers for `mui-adapter` and rely strictly on MUI's monolithic API. Storybook and visual regression tests have been updated to reflect this divergence while retaining core property mapping compatibility.
@@ -0,0 +1,66 @@
1
+ import styles from "./Pagination.module.css";
2
+
3
+ const NextPath =
4
+ "M8.781 8l-3.3-3.3.943-.943L10.667 8l-4.243 4.243-.943-.943 3.3-3.3z";
5
+ const PrevPath =
6
+ "M7.219 8l3.3 3.3-.943.943L5.333 8l4.243-4.243.943.943-3.3 3.3z";
7
+ const FirstPath =
8
+ "M6.85355 3.85355C7.04882 3.65829 7.04882 3.34171 6.85355 3.14645C6.65829 2.95118 6.34171 2.95118 6.14645 3.14645L2.14645 7.14645C1.95118 7.34171 1.95118 7.65829 2.14645 7.85355L6.14645 11.8536C6.34171 12.0488 6.65829 12.0488 6.85355 11.8536C7.04882 11.6583 7.04882 11.3417 6.85355 11.1464L3.20711 7.5L6.85355 3.85355ZM12.8536 3.85355C13.0488 3.65829 13.0488 3.34171 12.8536 3.14645C12.6583 2.95118 12.3417 2.95118 12.1464 3.14645L8.14645 7.14645C7.95118 7.34171 7.95118 7.65829 8.14645 7.85355L12.1464 11.8536C12.3417 12.0488 12.6583 12.0488 12.8536 11.8536C13.0488 11.6583 13.0488 11.3417 12.8536 11.1464L9.20711 7.5L12.8536 3.85355Z";
9
+ const LastPath =
10
+ "M2.14645 11.1464C1.95118 11.3417 1.95118 11.6583 2.14645 11.8536C2.34171 12.0488 2.65829 12.0488 2.85355 11.8536L6.85355 7.85355C7.04882 7.65829 7.04882 7.34171 6.85355 7.14645L2.85355 3.14645C2.65829 2.95118 2.34171 2.95118 2.14645 3.14645C1.95118 3.34171 1.95118 3.65829 2.14645 3.85355L5.79289 7.5L2.14645 11.1464ZM8.14645 11.1464C7.95118 11.3417 7.95118 11.6583 8.14645 11.8536C8.34171 12.0488 8.65829 12.0488 8.85355 11.8536L12.8536 7.85355C13.0488 7.65829 13.0488 7.34171 12.8536 7.14645L8.85355 3.14645C8.65829 2.95118 8.34171 2.95118 8.14645 3.14645C7.95118 3.34171 7.95118 3.65829 8.14645 3.85355L11.7929 7.5L8.14645 11.1464Z";
11
+
12
+ export type PaginationIconType = "next" | "prev" | "first" | "last";
13
+
14
+ const paths: Record<PaginationIconType, string> = {
15
+ next: NextPath,
16
+ prev: PrevPath,
17
+ first: FirstPath,
18
+ last: LastPath,
19
+ };
20
+
21
+ export const PaginationIcon = ({
22
+ type,
23
+ className,
24
+ ...props
25
+ }: React.ComponentProps<"svg"> & { type: PaginationIconType }) => (
26
+ <svg
27
+ viewBox="0 0 16 16"
28
+ xmlns="http://www.w3.org/2000/svg"
29
+ className={`${styles.baseIcon} ${className || ""}`.trim()}
30
+ {...props}
31
+ >
32
+ <path d={paths[type as PaginationIconType]} fill="currentColor" />
33
+ </svg>
34
+ );
35
+
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ export const NextWithLabel = (props: any) => (
38
+ <div className={styles.iconWithLabel}>
39
+ <span>Next</span>
40
+ <PaginationIcon type="next" {...props} />
41
+ </div>
42
+ );
43
+
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ export const PrevWithLabel = (props: any) => (
46
+ <div className={styles.iconWithLabel}>
47
+ <PaginationIcon type="prev" {...props} />
48
+ <span>Prev</span>
49
+ </div>
50
+ );
51
+
52
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
+ export const FirstWithLabel = (props: any) => (
54
+ <div className={styles.iconWithLabel}>
55
+ <PaginationIcon type="first" {...props} />
56
+ <span>First</span>
57
+ </div>
58
+ );
59
+
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ export const LastWithLabel = (props: any) => (
62
+ <div className={styles.iconWithLabel}>
63
+ <span>Last</span>
64
+ <PaginationIcon type="last" {...props} />
65
+ </div>
66
+ );
@@ -1,13 +1,9 @@
1
1
  /* EXEMPTIONS:
2
- This component is a placeholder stub. Once fully implemented, its specific
3
- tokens will be fully wired up to direct styles. */
4
-
2
+ - All pagination subcomponent properties (active-pages, inactive-pages, navigation-controls) are ignored
3
+ because we are not implementing custom subcomponent styling for pagination. Instead, pagination items
4
+ directly inherit the unified, standard brand button components for complete UI/UX consistency, rendering
5
+ these generated subcomponent tokens redundant. */
5
6
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_border-size */
6
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_background */
7
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_border-color */
8
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_icon-color */
9
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_text */
10
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_text-hover */
11
7
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_disabled-opacity */
12
8
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_elevation */
13
9
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_height */
@@ -27,13 +23,12 @@
27
23
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_text_line-height */
28
24
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_text_text-decoration */
29
25
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_text_text-transform */
30
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_colors_dots-color */
26
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_background */
27
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_border-color */
28
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_icon-color */
29
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_text */
30
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_active-pages_subcomponent_colors_text-hover */
31
31
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_border-size */
32
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_background */
33
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_border-color */
34
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_icon-color */
35
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_text */
36
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_text-hover */
37
32
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_disabled-opacity */
38
33
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_elevation */
39
34
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_height */
@@ -53,13 +48,12 @@
53
48
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_text_line-height */
54
49
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_text_text-decoration */
55
50
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_text_text-transform */
56
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_item-gap */
51
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_background */
52
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_border-color */
53
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_icon-color */
54
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_text */
55
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_inactive-pages_subcomponent_colors_text-hover */
57
56
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_border-size */
58
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_background */
59
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_border-color */
60
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_icon-color */
61
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_text */
62
- /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_text-hover */
63
57
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_disabled-opacity */
64
58
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_elevation */
65
59
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_height */
@@ -79,3 +73,223 @@
79
73
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_text_line-height */
80
74
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_text_text-decoration */
81
75
  /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_text_text-transform */
76
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_background */
77
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_border-color */
78
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_icon-color */
79
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_text */
80
+ /* recursica-ignore: --recursica_ui-kit_components_pagination_properties_navigation-controls_subcomponent_colors_text-hover */
81
+
82
+ .root {
83
+ display: flex;
84
+ align-items: center;
85
+ gap: var(--recursica_ui-kit_components_pagination_properties_item-gap);
86
+ }
87
+
88
+ .control {
89
+ box-sizing: border-box;
90
+ margin: 0;
91
+ border-style: solid;
92
+ position: relative;
93
+ transition: all 0.2s ease;
94
+ overflow: hidden;
95
+ display: inline-flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+
99
+ /* Typography */
100
+ font-family: var(
101
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-family
102
+ );
103
+ font-size: var(
104
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-size
105
+ );
106
+ font-style: var(
107
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-style
108
+ );
109
+ font-weight: var(
110
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-weight
111
+ );
112
+ letter-spacing: var(
113
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_letter-spacing
114
+ );
115
+ line-height: var(
116
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_line-height
117
+ );
118
+ text-decoration: var(
119
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-decoration
120
+ );
121
+ text-transform: var(
122
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-transform
123
+ );
124
+
125
+ /* Dimensions */
126
+ border-radius: var(
127
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_border-radius
128
+ );
129
+ height: var(
130
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_height
131
+ );
132
+ min-width: var(
133
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
134
+ );
135
+ padding: 0
136
+ var(
137
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_horizontal-padding
138
+ );
139
+
140
+ /* Base Inactive Style: Outline */
141
+ border-width: var(
142
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_border-size
143
+ );
144
+ box-shadow: var(
145
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_elevation
146
+ );
147
+ background-color: var(
148
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_background
149
+ );
150
+ border-color: var(
151
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_border-color
152
+ );
153
+ color: var(
154
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text
155
+ );
156
+ }
157
+
158
+ .control:disabled {
159
+ opacity: var(--recursica_brand_states_disabled);
160
+ cursor: not-allowed;
161
+ }
162
+
163
+ .control:hover:not(:disabled) {
164
+ color: var(
165
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text-hover
166
+ );
167
+ }
168
+
169
+ /* Hover Overlay */
170
+ .control::after {
171
+ content: "";
172
+ position: absolute;
173
+ inset: 0;
174
+ border-radius: inherit;
175
+ z-index: 0;
176
+ pointer-events: none;
177
+ transition: opacity 150ms ease;
178
+ opacity: 0;
179
+ background-color: var(
180
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-color
181
+ );
182
+ }
183
+
184
+ .control:hover:not(:disabled)::after {
185
+ opacity: var(
186
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-opacity
187
+ );
188
+ }
189
+
190
+ /* Active Style: Solid */
191
+ .control[data-active] {
192
+ border-width: var(
193
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_border-size
194
+ );
195
+ box-shadow: var(
196
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_elevation
197
+ );
198
+ background-color: var(
199
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_background
200
+ );
201
+ border-color: var(
202
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_border-color
203
+ );
204
+ color: var(
205
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text
206
+ );
207
+ }
208
+
209
+ .control[data-active]:hover:not(:disabled) {
210
+ color: var(
211
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text-hover
212
+ );
213
+ }
214
+
215
+ /* Navigation Style: Text */
216
+ .control[data-variant="text"] {
217
+ border-width: var(
218
+ --recursica_ui-kit_components_button_variants_styles_text_properties_border-size
219
+ );
220
+ box-shadow: var(
221
+ --recursica_ui-kit_components_button_variants_styles_text_properties_elevation
222
+ );
223
+ background-color: var(
224
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_background
225
+ );
226
+ border-color: var(
227
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_border-color
228
+ );
229
+ color: var(
230
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text
231
+ );
232
+
233
+ /* Also explicitly inherit navigation sizes incase they differ from pages */
234
+ border-radius: var(
235
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_border-radius
236
+ );
237
+ height: var(
238
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_height
239
+ );
240
+ min-width: var(
241
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
242
+ );
243
+ padding: 0
244
+ var(
245
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_horizontal-padding
246
+ );
247
+ }
248
+
249
+ .control[data-variant="text"]:hover:not(:disabled) {
250
+ color: var(
251
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text-hover
252
+ );
253
+ }
254
+
255
+ /* Hover Overlay for Navigation */
256
+ .control[data-variant="text"]::after {
257
+ background-color: var(
258
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-color
259
+ );
260
+ }
261
+ .control[data-variant="text"]:hover:not(:disabled)::after {
262
+ opacity: var(
263
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_hover-opacity
264
+ );
265
+ }
266
+
267
+ /* Dots */
268
+ .dots {
269
+ display: inline-flex;
270
+ align-items: center;
271
+ justify-content: center;
272
+ height: var(
273
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_height
274
+ );
275
+ min-width: var(
276
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_min-width
277
+ );
278
+ color: var(
279
+ --recursica_ui-kit_components_pagination_properties_colors_dots-color
280
+ );
281
+ }
282
+
283
+ /* Icon Styles */
284
+ .iconWithLabel {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: var(
288
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
289
+ );
290
+ }
291
+
292
+ .baseIcon {
293
+ width: calc(var(--pagination-control-size) / 1.8);
294
+ height: calc(var(--pagination-control-size) / 1.8);
295
+ }
@@ -1,35 +1,48 @@
1
1
  import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Pagination } from "./Pagination";
3
- import { ComingSoon } from "@recursica/storybook-template";
4
3
 
5
4
  const meta: Meta<typeof Pagination> = {
6
- title: "UI-Kit/🚧 Pagination",
5
+ title: "UI-Kit/Pagination",
7
6
  component: Pagination,
8
7
  tags: ["autodocs"],
9
- parameters: {
10
- controls: {
11
- include: [
12
- "layer",
13
- "withLayer",
14
- "children",
15
- "component",
16
- "variant",
17
- "size",
18
- "icon",
19
- "disabled",
20
- "href",
21
- "onClick",
22
- "onChange",
23
- "value",
24
- "checked",
25
- ],
8
+ argTypes: {
9
+ total: { control: "number" },
10
+ withEdges: { control: "boolean" },
11
+ withControls: { control: "boolean" },
12
+ disabled: { control: "boolean" },
13
+ withLabels: {
14
+ control: "boolean",
15
+ description: "Toggle text labels alongside icons",
26
16
  },
17
+ defaultChecked: { table: { disable: true } },
18
+ },
19
+ args: {
20
+ total: 10,
21
+ withEdges: false,
22
+ withControls: true,
23
+ withLabels: false,
24
+ },
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
26
+ render: ({ withLayer, layer, ...args }: any) => {
27
+ return <Pagination {...args} />;
27
28
  },
28
29
  };
29
30
 
30
31
  export default meta;
32
+
31
33
  type Story = StoryObj<typeof Pagination>;
32
34
 
33
- export const Default: Story = {
34
- render: () => <ComingSoon componentName="Pagination" />,
35
+ export const Default: Story = {};
36
+
37
+ export const WithEdges: Story = {
38
+ args: {
39
+ withEdges: true,
40
+ },
41
+ };
42
+
43
+ export const WithTextLabels: Story = {
44
+ args: {
45
+ withEdges: true,
46
+ withLabels: true,
47
+ },
35
48
  };
@@ -1,8 +1,76 @@
1
- import React from "react";
2
- import "./Pagination.module.css";
1
+ import { forwardRef } from "react";
2
+ import {
3
+ Pagination as MuiPagination,
4
+ type PaginationProps as MuiPaginationProps,
5
+ } from "@mui/material";
6
+ import {
7
+ filterStylingProps,
8
+ type RecursicaOverStyled,
9
+ } from "../../utils/filterStylingProps";
10
+ import styles from "./Pagination.module.css";
3
11
 
4
- export type PaginationProps = React.HTMLAttributes<HTMLDivElement>;
12
+ import { type RecursicaPaginationProps } from "@recursica/adapter-common";
5
13
 
6
- export const Pagination: React.FC<PaginationProps> = (props) => {
7
- return <div {...props}>Pagination</div>;
8
- };
14
+ export type PaginationProps = RecursicaOverStyled<
15
+ MuiPaginationProps & RecursicaPaginationProps
16
+ >;
17
+
18
+ function usePaginationClassNames(restRecord: Record<string, unknown>): {
19
+ className: string;
20
+ classNames: Partial<Record<string, string>>;
21
+ } {
22
+ const mergedClassNames: Partial<Record<string, string>> = {
23
+ root: styles.root,
24
+ ul: styles.ul,
25
+ };
26
+
27
+ const classNamesProp = restRecord.classNames;
28
+ if (
29
+ classNamesProp &&
30
+ typeof classNamesProp === "object" &&
31
+ !Array.isArray(classNamesProp)
32
+ ) {
33
+ const o = classNamesProp as Partial<Record<string, string>>;
34
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
35
+ mergedClassNames.ul = o.ul ? `${styles.ul} ${o.ul}` : styles.ul;
36
+ }
37
+
38
+ const classNameProp = restRecord.className as string | undefined;
39
+ const finalClass = classNameProp
40
+ ? `${styles.root} ${classNameProp}`
41
+ : styles.root;
42
+
43
+ return { className: finalClass, classNames: mergedClassNames };
44
+ }
45
+
46
+ const _Pagination = forwardRef<HTMLDivElement, PaginationProps>(
47
+ function Pagination(
48
+ {
49
+ overStyled = false,
50
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
51
+ withLabels,
52
+ ...rest
53
+ },
54
+ ref,
55
+ ) {
56
+ const sanitizedProps = filterStylingProps(rest, overStyled);
57
+ const stylingParams = usePaginationClassNames(
58
+ sanitizedProps as Record<string, unknown>,
59
+ );
60
+
61
+ return (
62
+ <div ref={ref} className={stylingParams.className}>
63
+ <MuiPagination
64
+ classes={stylingParams.classNames}
65
+ {...(sanitizedProps as MuiPaginationProps)}
66
+ />
67
+ </div>
68
+ );
69
+ },
70
+ );
71
+ _Pagination.displayName = "Pagination";
72
+
73
+ /**
74
+ * Recursica Pagination component wrapping Mui's Pagination.
75
+ */
76
+ export const Pagination = _Pagination;