rsuite 6.0.0-canary-20250620 → 6.0.0-canary-20250622

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 (193) hide show
  1. package/Accordion/styles/index.css +0 -78
  2. package/AutoComplete/styles/index.css +1 -79
  3. package/Avatar/styles/index.css +0 -78
  4. package/AvatarGroup/styles/index.css +0 -78
  5. package/Badge/styles/index.css +0 -78
  6. package/Box/styles/index.css +0 -78
  7. package/Breadcrumb/styles/index.css +0 -78
  8. package/Button/styles/index.css +0 -78
  9. package/ButtonGroup/styles/index.css +0 -78
  10. package/ButtonToolbar/styles/index.css +0 -82
  11. package/Calendar/styles/index.css +0 -78
  12. package/Card/styles/index.css +0 -78
  13. package/CardGroup/styles/index.css +0 -78
  14. package/Carousel/styles/index.css +0 -78
  15. package/CascadeTree/styles/index.css +0 -78
  16. package/Cascader/styles/index.css +1 -79
  17. package/Center/styles/index.css +0 -78
  18. package/CheckPicker/styles/index.css +1 -79
  19. package/CheckTree/styles/index.css +1 -79
  20. package/CheckTreePicker/styles/index.css +1 -79
  21. package/Checkbox/styles/index.css +0 -78
  22. package/CheckboxGroup/styles/index.css +0 -78
  23. package/Container/styles/index.css +0 -78
  24. package/Content/styles/index.css +0 -78
  25. package/DateInput/styles/index.css +0 -78
  26. package/DatePicker/styles/index.css +1 -79
  27. package/DateRangeInput/styles/index.css +0 -78
  28. package/DateRangePicker/styles/index.css +1 -79
  29. package/Divider/styles/index.css +0 -78
  30. package/Drawer/styles/index.css +0 -78
  31. package/Dropdown/styles/index.css +0 -78
  32. package/FlexboxGrid/styles/index.css +0 -78
  33. package/Footer/styles/index.css +0 -78
  34. package/Form/styles/index.css +0 -78
  35. package/FormControl/styles/index.css +0 -78
  36. package/FormControlLabel/styles/index.css +0 -78
  37. package/FormErrorMessage/styles/index.css +0 -78
  38. package/FormGroup/styles/index.css +0 -78
  39. package/FormHelpText/styles/index.css +0 -78
  40. package/FormStack/styles/index.css +0 -78
  41. package/Grid/styles/index.css +0 -78
  42. package/Header/styles/index.css +0 -78
  43. package/Heading/styles/index.css +0 -78
  44. package/HeadingGroup/styles/index.css +0 -78
  45. package/Highlight/styles/index.css +0 -78
  46. package/IconButton/styles/index.css +0 -78
  47. package/Image/styles/index.css +0 -78
  48. package/InlineEdit/styles/index.css +0 -78
  49. package/Input/styles/index.css +0 -78
  50. package/InputGroup/styles/index.css +1 -79
  51. package/InputNumber/styles/index.css +1 -79
  52. package/InputPicker/styles/index.css +1 -79
  53. package/Kbd/styles/index.css +0 -78
  54. package/Link/styles/index.css +0 -78
  55. package/List/styles/index.css +0 -78
  56. package/Loader/styles/index.css +0 -78
  57. package/Menu/styles/index.css +0 -78
  58. package/Message/styles/index.css +0 -78
  59. package/Modal/styles/index.css +0 -78
  60. package/MultiCascadeTree/styles/index.css +1 -79
  61. package/MultiCascader/styles/index.css +1 -79
  62. package/Nav/styles/index.css +0 -78
  63. package/Navbar/styles/index.css +0 -78
  64. package/Notification/styles/index.css +0 -78
  65. package/NumberInput/styles/index.css +1 -79
  66. package/Pagination/styles/index.css +1 -79
  67. package/Panel/styles/index.css +0 -78
  68. package/PanelGroup/styles/index.css +0 -78
  69. package/PasswordInput/styles/index.css +1 -79
  70. package/PasswordStrengthMeter/styles/index.css +0 -78
  71. package/PinInput/styles/index.css +0 -78
  72. package/Placeholder/styles/index.css +0 -78
  73. package/Popover/styles/index.css +0 -78
  74. package/Progress/styles/index.css +0 -78
  75. package/ProgressCircle/styles/index.css +0 -78
  76. package/Radio/styles/index.css +0 -78
  77. package/RadioGroup/styles/index.css +0 -78
  78. package/RadioTile/styles/index.css +0 -78
  79. package/RangeSlider/styles/index.css +0 -78
  80. package/Rate/styles/index.css +0 -78
  81. package/SegmentedControl/package.json +7 -0
  82. package/SegmentedControl/styles/index.css +159 -0
  83. package/SelectPicker/styles/index.css +1 -79
  84. package/Sidebar/styles/index.css +0 -78
  85. package/Sidenav/styles/index.css +0 -78
  86. package/Slider/styles/index.css +0 -78
  87. package/Stack/styles/index.css +0 -78
  88. package/Stat/styles/index.css +0 -78
  89. package/StatGroup/styles/index.css +0 -78
  90. package/Steps/styles/index.css +0 -78
  91. package/Table/styles/index.css +0 -78
  92. package/Tabs/styles/index.css +0 -78
  93. package/Tag/styles/index.css +0 -78
  94. package/TagGroup/styles/index.css +0 -78
  95. package/TagInput/styles/index.css +1 -79
  96. package/TagPicker/styles/index.css +1 -79
  97. package/Text/styles/index.css +0 -78
  98. package/Textarea/styles/index.css +0 -78
  99. package/TimePicker/styles/index.css +1 -79
  100. package/TimeRangePicker/styles/index.css +1 -79
  101. package/Timeline/styles/index.css +0 -78
  102. package/Toggle/styles/index.css +0 -78
  103. package/Tooltip/styles/index.css +0 -78
  104. package/Tree/styles/index.css +1 -79
  105. package/TreePicker/styles/index.css +1 -79
  106. package/Uploader/styles/index.css +0 -78
  107. package/cjs/ButtonToolbar/ButtonToolbar.js +2 -0
  108. package/cjs/Grid/utils/styles.d.ts +1 -1
  109. package/cjs/InputPicker/utils.d.ts +1 -1
  110. package/cjs/Nav/Nav.d.ts +2 -3
  111. package/cjs/RadioGroup/RadioGroup.d.ts +4 -1
  112. package/cjs/SegmentedControl/Indicator.d.ts +10 -0
  113. package/cjs/SegmentedControl/Indicator.js +22 -0
  114. package/cjs/SegmentedControl/SegmentedControl.d.ts +27 -0
  115. package/cjs/SegmentedControl/SegmentedControl.js +87 -0
  116. package/cjs/SegmentedControl/SegmentedItem.d.ts +16 -0
  117. package/cjs/SegmentedControl/SegmentedItem.js +44 -0
  118. package/cjs/SegmentedControl/hooks/useIndicatorPosition.d.ts +17 -0
  119. package/cjs/SegmentedControl/hooks/useIndicatorPosition.js +55 -0
  120. package/cjs/SegmentedControl/index.d.ts +4 -0
  121. package/cjs/SegmentedControl/index.js +11 -0
  122. package/cjs/Slider/ProgressBar.js +1 -1
  123. package/cjs/Stack/Stack.js +20 -5
  124. package/cjs/Stack/utils.d.ts +9 -0
  125. package/cjs/Stack/utils.js +38 -0
  126. package/cjs/Tabs/Tabs.d.ts +4 -2
  127. package/cjs/index.d.ts +1 -0
  128. package/cjs/index.js +6 -0
  129. package/cjs/internals/Box/Box.d.ts +27 -27
  130. package/cjs/internals/Box/Box.js +13 -8
  131. package/cjs/internals/Box/utils.d.ts +4 -1
  132. package/cjs/internals/Box/utils.js +154 -13
  133. package/cjs/internals/Provider/types.d.ts +2 -0
  134. package/cjs/internals/constants/index.js +2 -2
  135. package/cjs/internals/hooks/useElementResize.d.ts +2 -1
  136. package/cjs/internals/hooks/useElementResize.js +50 -7
  137. package/cjs/internals/hooks/useStyled.d.ts +60 -0
  138. package/cjs/internals/hooks/useStyled.js +257 -0
  139. package/cjs/internals/utils/colours.js +1 -1
  140. package/cjs/internals/utils/style-sheet/css.d.ts +1 -1
  141. package/cjs/internals/utils/style-sheet/css.js +1 -1
  142. package/cjs/internals/utils/style-sheet/index.d.ts +1 -0
  143. package/cjs/internals/utils/style-sheet/index.js +6 -0
  144. package/cjs/internals/utils/style-sheet/style-manager.d.ts +50 -0
  145. package/cjs/internals/utils/style-sheet/style-manager.js +97 -0
  146. package/dist/rsuite-no-reset.css +200 -101
  147. package/dist/rsuite-no-reset.min.css +1 -1
  148. package/dist/rsuite.css +200 -101
  149. package/dist/rsuite.js +172 -14
  150. package/dist/rsuite.js.map +1 -1
  151. package/dist/rsuite.min.css +1 -1
  152. package/dist/rsuite.min.js +1 -1
  153. package/dist/rsuite.min.js.map +1 -1
  154. package/esm/ButtonToolbar/ButtonToolbar.js +2 -0
  155. package/esm/Grid/utils/styles.d.ts +1 -1
  156. package/esm/InputPicker/utils.d.ts +1 -1
  157. package/esm/Nav/Nav.d.ts +2 -3
  158. package/esm/RadioGroup/RadioGroup.d.ts +4 -1
  159. package/esm/SegmentedControl/Indicator.d.ts +10 -0
  160. package/esm/SegmentedControl/Indicator.js +17 -0
  161. package/esm/SegmentedControl/SegmentedControl.d.ts +27 -0
  162. package/esm/SegmentedControl/SegmentedControl.js +81 -0
  163. package/esm/SegmentedControl/SegmentedItem.d.ts +16 -0
  164. package/esm/SegmentedControl/SegmentedItem.js +39 -0
  165. package/esm/SegmentedControl/hooks/useIndicatorPosition.d.ts +17 -0
  166. package/esm/SegmentedControl/hooks/useIndicatorPosition.js +50 -0
  167. package/esm/SegmentedControl/index.d.ts +4 -0
  168. package/esm/SegmentedControl/index.js +8 -0
  169. package/esm/Slider/ProgressBar.js +1 -1
  170. package/esm/Stack/Stack.js +21 -6
  171. package/esm/Stack/utils.d.ts +9 -0
  172. package/esm/Stack/utils.js +35 -0
  173. package/esm/Tabs/Tabs.d.ts +4 -2
  174. package/esm/index.d.ts +1 -0
  175. package/esm/index.js +1 -0
  176. package/esm/internals/Box/Box.d.ts +27 -27
  177. package/esm/internals/Box/Box.js +9 -4
  178. package/esm/internals/Box/utils.d.ts +4 -1
  179. package/esm/internals/Box/utils.js +153 -13
  180. package/esm/internals/Provider/types.d.ts +2 -0
  181. package/esm/internals/constants/index.js +2 -2
  182. package/esm/internals/hooks/useElementResize.d.ts +2 -1
  183. package/esm/internals/hooks/useElementResize.js +50 -7
  184. package/esm/internals/hooks/useStyled.d.ts +60 -0
  185. package/esm/internals/hooks/useStyled.js +251 -0
  186. package/esm/internals/utils/colours.js +1 -1
  187. package/esm/internals/utils/style-sheet/css.d.ts +1 -1
  188. package/esm/internals/utils/style-sheet/css.js +1 -1
  189. package/esm/internals/utils/style-sheet/index.d.ts +1 -0
  190. package/esm/internals/utils/style-sheet/index.js +2 -1
  191. package/esm/internals/utils/style-sheet/style-manager.d.ts +50 -0
  192. package/esm/internals/utils/style-sheet/style-manager.js +93 -0
  193. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
  import { getCssValue, getSizeStyle, getColorVar } from "../utils/index.js";
3
-
3
+ import { BREAKPOINTS } from "../constants/index.js";
4
4
  // Mapping for padding properties to their CSS style equivalents
5
5
  const paddingStyleMap = {
6
6
  p: 'padding',
@@ -70,6 +70,45 @@ export const omitBoxProps = props => {
70
70
  return filteredProps;
71
71
  };
72
72
 
73
+ /**
74
+ * Checks if a value is a responsive value object
75
+ * @param value - Value to check
76
+ * @returns True if the value is a responsive value object
77
+ */
78
+ function isResponsiveValue(value) {
79
+ return value !== null && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).some(key => BREAKPOINTS.includes(key));
80
+ }
81
+
82
+ /**
83
+ * Process a value that might be a responsive value
84
+ * @param value - Value to process
85
+ * @param processor - Function to process non-responsive values
86
+ * @returns Processed value or responsive object with processed values
87
+ */
88
+ function processResponsiveValue(value, processor) {
89
+ if (value === undefined) {
90
+ return undefined;
91
+ }
92
+ if (isResponsiveValue(value)) {
93
+ const result = {};
94
+ Object.entries(value).forEach(([breakpoint, val]) => {
95
+ if (val !== undefined) {
96
+ const processed = processor(val);
97
+ if (processed !== undefined) {
98
+ result[breakpoint] = processed;
99
+ }
100
+ }
101
+ });
102
+ return Object.keys(result).length > 0 ? result : undefined;
103
+ }
104
+ return processor(value);
105
+ }
106
+
107
+ // Type for CSS variable values that can be string, number, or responsive values
108
+
109
+ // Silence ESLint warnings for unused parameters in forEach callbacks
110
+ /* eslint-disable @typescript-eslint/no-unused-vars */
111
+
73
112
  /**
74
113
  * Converts layout properties to CSS variables with abbreviated names
75
114
  * @param props Object containing layout properties
@@ -77,42 +116,143 @@ export const omitBoxProps = props => {
77
116
  */
78
117
  export const getBoxCSSVariables = props => {
79
118
  const cssVars = {};
119
+ const prefix = `--rs-box-`;
80
120
 
81
121
  // Process padding properties
82
122
  Object.keys(paddingStyleMap).forEach(propKey => {
83
123
  if (props[propKey] !== undefined) {
84
- cssVars[`--rs-box-${propKey}`] = getCssValue(props[propKey]);
124
+ cssVars[`${prefix}${propKey}`] = processResponsiveValue(props[propKey], val => getCssValue(val));
85
125
  }
86
126
  });
87
127
 
88
128
  // Process margin properties
89
129
  Object.keys(marginStyleMap).forEach(propKey => {
90
130
  if (props[propKey] !== undefined) {
91
- cssVars[`--rs-box-${propKey}`] = getCssValue(props[propKey]);
131
+ cssVars[`${prefix}${propKey}`] = processResponsiveValue(props[propKey], val => getCssValue(val));
92
132
  }
93
133
  });
94
134
 
95
135
  // Process size properties
96
136
  Object.keys(sizeStyleMap).forEach(propKey => {
97
137
  if (props[propKey] !== undefined) {
98
- cssVars[`--rs-box-${propKey}`] = getCssValue(props[propKey]);
138
+ cssVars[`${prefix}${propKey}`] = processResponsiveValue(props[propKey], val => getCssValue(val));
99
139
  }
100
140
  });
101
141
  if (props.bd !== undefined) {
102
- cssVars['--rs-box-bd'] = getCssValue(props.bd);
142
+ cssVars[`${prefix}bd`] = processResponsiveValue(props.bd, val => getCssValue(val));
103
143
  }
104
144
  if (props.display !== undefined) {
105
- cssVars['--rs-box-display'] = props.display;
145
+ cssVars[`${prefix}display`] = processResponsiveValue(props.display, val => val);
106
146
  }
107
147
  if (props.c !== undefined) {
108
- cssVars['--rs-box-c'] = getColorVar(props.c);
148
+ cssVars[`${prefix}c`] = processResponsiveValue(props.c, val => getColorVar(val));
109
149
  }
110
150
  if (props.bg !== undefined) {
111
- cssVars['--rs-box-bg'] = getColorVar(props.bg);
151
+ cssVars[`${prefix}bg`] = processResponsiveValue(props.bg, val => getColorVar(val));
152
+ }
153
+
154
+ // Handle special cases for rounded and shadow
155
+ if (props.rounded !== undefined) {
156
+ const processRounded = val => {
157
+ const result = getSizeStyle(val, 'box', 'rounded');
158
+ return result ? result : undefined;
159
+ };
160
+ if (isResponsiveValue(props.rounded)) {
161
+ // Handle responsive rounded values
162
+ const responsiveRounded = {};
163
+ Object.entries(props.rounded).forEach(([breakpoint, val]) => {
164
+ if (val !== undefined) {
165
+ const styleObj = processRounded(val);
166
+ if (styleObj) {
167
+ responsiveRounded[breakpoint] = styleObj;
168
+ }
169
+ }
170
+ });
171
+
172
+ // For each CSS variable key in the rounded styles, create a responsive value
173
+ const processedKeys = new Set();
174
+ Object.entries(responsiveRounded).forEach(([_breakpoint, styleObj]) => {
175
+ if (styleObj) {
176
+ Object.entries(styleObj).forEach(([key, _value]) => {
177
+ processedKeys.add(key);
178
+ });
179
+ }
180
+ });
181
+ processedKeys.forEach(key => {
182
+ const responsiveValue = {};
183
+ Object.entries(responsiveRounded).forEach(([breakpoint, styleObj]) => {
184
+ if (styleObj && styleObj[key] !== undefined) {
185
+ // Ensure we're only using string values for CSS variables
186
+ const value = styleObj[key];
187
+ if (typeof value === 'string' || typeof value === 'number') {
188
+ responsiveValue[breakpoint] = value;
189
+ }
190
+ }
191
+ });
192
+ if (Object.keys(responsiveValue).length > 0) {
193
+ cssVars[key] = responsiveValue;
194
+ }
195
+ });
196
+ } else {
197
+ // Handle non-responsive rounded value
198
+ const styleObj = processRounded(props.rounded);
199
+ if (styleObj) {
200
+ Object.entries(styleObj).forEach(([key, value]) => {
201
+ cssVars[key] = value;
202
+ });
203
+ }
204
+ }
205
+ }
206
+ if (props.shadow !== undefined) {
207
+ const processShadow = val => {
208
+ const result = getSizeStyle(val, 'box', 'shadow');
209
+ return result ? result : undefined;
210
+ };
211
+ if (isResponsiveValue(props.shadow)) {
212
+ // Handle responsive shadow values
213
+ const responsiveShadow = {};
214
+ Object.entries(props.shadow).forEach(([breakpoint, val]) => {
215
+ if (val !== undefined) {
216
+ const styleObj = processShadow(val);
217
+ if (styleObj) {
218
+ responsiveShadow[breakpoint] = styleObj;
219
+ }
220
+ }
221
+ });
222
+
223
+ // For each CSS variable key in the shadow styles, create a responsive value
224
+ const processedKeys = new Set();
225
+ Object.entries(responsiveShadow).forEach(([_breakpoint, styleObj]) => {
226
+ if (styleObj) {
227
+ Object.entries(styleObj).forEach(([key, _value]) => {
228
+ processedKeys.add(key);
229
+ });
230
+ }
231
+ });
232
+ processedKeys.forEach(key => {
233
+ const responsiveValue = {};
234
+ Object.entries(responsiveShadow).forEach(([breakpoint, styleObj]) => {
235
+ if (styleObj && styleObj[key] !== undefined) {
236
+ // Ensure we're only using string values for CSS variables
237
+ const value = styleObj[key];
238
+ if (typeof value === 'string' || typeof value === 'number') {
239
+ responsiveValue[breakpoint] = value;
240
+ }
241
+ }
242
+ });
243
+ if (Object.keys(responsiveValue).length > 0) {
244
+ cssVars[key] = responsiveValue;
245
+ }
246
+ });
247
+ } else {
248
+ // Handle non-responsive shadow value
249
+ const styleObj = processShadow(props.shadow);
250
+ if (styleObj) {
251
+ Object.entries(styleObj).forEach(([key, value]) => {
252
+ cssVars[key] = value;
253
+ });
254
+ }
255
+ }
112
256
  }
113
- return {
114
- ...cssVars,
115
- ...getSizeStyle(props.rounded, 'box', 'rounded'),
116
- ...getSizeStyle(props.shadow, 'box', 'shadow')
117
- };
257
+ return cssVars;
118
258
  };
@@ -87,6 +87,7 @@ import type { RangeSliderProps } from '../../RangeSlider';
87
87
  import type { RateProps } from '../../Rate';
88
88
  import type { RowProps } from '../../Row';
89
89
  import type { SelectPickerProps } from '../../SelectPicker';
90
+ import type { SegmentedControlProps } from '../../SegmentedControl';
90
91
  import type { SidebarProps } from '../../Sidebar';
91
92
  import type { SidenavProps } from '../../Sidenav';
92
93
  import type { SliderProps } from '../../Slider';
@@ -209,6 +210,7 @@ export interface ReactSuiteComponents {
209
210
  Rate: ComponentProps<RateProps>;
210
211
  Row: ComponentProps<RowProps>;
211
212
  SelectPicker: ComponentProps<SelectPickerProps>;
213
+ SegmentedControl: ComponentProps<SegmentedControlProps>;
212
214
  Sidebar: ComponentProps<SidebarProps>;
213
215
  Sidenav: ComponentProps<SidenavProps>;
214
216
  Slider: ComponentProps<SliderProps>;
@@ -1,6 +1,6 @@
1
1
  'use client';
2
- export const SIZE = ['lg', 'md', 'sm', 'xs'];
3
- export const BREAKPOINTS = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
2
+ export const SIZE = ['xs', 'sm', 'md', 'lg'];
3
+ export const BREAKPOINTS = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
4
4
  export const STATUS = ['success', 'warning', 'error', 'info'];
5
5
  export const COLOR = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'violet'];
6
6
  export const PLACEMENT_4 = ['top', 'bottom', 'right', 'left'];
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  /**
2
3
  * Attach the event handler directly to the specified DOM element,
3
4
  * and it will be triggered when the size of the DOM element is changed.
@@ -5,5 +6,5 @@
5
6
  * @param eventTarget The target to listen for events on
6
7
  * @param listener An event handler
7
8
  */
8
- export declare function useElementResize(eventTarget: Element | null | (() => Element | null), listener: ResizeObserverCallback): void;
9
+ export declare function useElementResize(eventTarget: Element | null | (() => Element | null) | React.RefObject<Element | null>, listener: ResizeObserverCallback): void;
9
10
  export default useElementResize;
@@ -11,18 +11,61 @@ import { ResizeObserver } from '@juggle/resize-observer';
11
11
  */
12
12
  export function useElementResize(eventTarget, listener) {
13
13
  const resizeObserver = useRef(null);
14
+ const currentElement = useRef(null);
15
+
16
+ // Create the observer
14
17
  useEffect(() => {
15
- if (!resizeObserver.current) {
16
- const target = typeof eventTarget === 'function' ? eventTarget() : eventTarget;
17
- if (target) {
18
- resizeObserver.current = new ResizeObserver(listener);
19
- resizeObserver.current.observe(target);
18
+ // Get the target element
19
+ let target = null;
20
+ if (eventTarget) {
21
+ if (typeof eventTarget === 'function') {
22
+ target = eventTarget();
23
+ } else if ('current' in eventTarget) {
24
+ target = eventTarget.current;
25
+ } else {
26
+ target = eventTarget;
27
+ }
28
+ }
29
+
30
+ // If target changed, disconnect the previous observer
31
+ if (currentElement.current !== target) {
32
+ if (resizeObserver.current) {
33
+ resizeObserver.current.disconnect();
34
+ resizeObserver.current = null;
20
35
  }
36
+ currentElement.current = target;
37
+ }
38
+
39
+ // If we have a target and no observer, create one
40
+ if (target && !resizeObserver.current) {
41
+ const observer = new ResizeObserver(listener);
42
+ observer.observe(target);
43
+ resizeObserver.current = observer;
21
44
  }
45
+
46
+ // Cleanup function
22
47
  return () => {
23
- var _resizeObserver$curre;
24
- (_resizeObserver$curre = resizeObserver.current) === null || _resizeObserver$curre === void 0 || _resizeObserver$curre.disconnect();
48
+ if (resizeObserver.current) {
49
+ resizeObserver.current.disconnect();
50
+ resizeObserver.current = null;
51
+ }
52
+ currentElement.current = null;
25
53
  };
26
54
  }, [eventTarget, listener]);
55
+
56
+ // Update the current element reference if it changes
57
+ useEffect(() => {
58
+ if (eventTarget) {
59
+ if (typeof eventTarget === 'function') {
60
+ currentElement.current = eventTarget();
61
+ } else if ('current' in eventTarget) {
62
+ currentElement.current = eventTarget.current;
63
+ } else {
64
+ currentElement.current = eventTarget;
65
+ }
66
+ } else {
67
+ currentElement.current = null;
68
+ }
69
+ }, [eventTarget]);
27
70
  }
28
71
  export default useElementResize;
@@ -0,0 +1,60 @@
1
+ import { CSSProperties } from 'react';
2
+ import type { Breakpoints, ResponsiveValue } from '../types';
3
+ /**
4
+ * Options for the useStyled hook
5
+ */
6
+ interface UseStyledOptions {
7
+ /**
8
+ * CSS variables to apply
9
+ */
10
+ cssVars?: Record<string, string | number | undefined | ResponsiveValue<string | number>>;
11
+ /**
12
+ * Base class name to include
13
+ */
14
+ className?: string;
15
+ /**
16
+ * Base style to merge with
17
+ */
18
+ style?: CSSProperties;
19
+ /**
20
+ * Whether this element should be styled
21
+ * Can be a boolean or a breakpoint string
22
+ */
23
+ enabled?: boolean | Breakpoints;
24
+ /**
25
+ * Prefix for the generated class name
26
+ * @default 'rs'
27
+ */
28
+ prefix?: string;
29
+ }
30
+ /**
31
+ * Result of the useStyled hook
32
+ */
33
+ interface UseStyledResult {
34
+ /**
35
+ * Combined class name including the unique identifier
36
+ */
37
+ className: string | undefined;
38
+ /**
39
+ * Style object without CSS variables
40
+ */
41
+ style: CSSProperties | undefined;
42
+ /**
43
+ * Unique identifier for this styled element
44
+ */
45
+ id: string;
46
+ }
47
+ /**
48
+ * Custom hook for managing component styling with scoped CSS variables
49
+ *
50
+ * This hook handles:
51
+ * 1. Generating a unique class name for the component
52
+ * 2. Creating a scoped style rule to prevent CSS variable inheritance
53
+ * 3. Managing the lifecycle of style rules
54
+ * 4. Handling responsive values for different breakpoints
55
+ *
56
+ * @param options - Styling options
57
+ * @returns Styling properties to apply to the component
58
+ */
59
+ export declare function useStyled(options: UseStyledOptions): UseStyledResult;
60
+ export default useStyled;
@@ -0,0 +1,251 @@
1
+ 'use client';
2
+ import { useId, useLayoutEffect, useContext } from 'react';
3
+ import isEmpty from 'lodash/isEmpty';
4
+ import { StyleManager } from "../utils/style-sheet/style-manager.js";
5
+ import { BREAKPOINTS } from "../constants/index.js";
6
+ import { CustomContext } from "../Provider/CustomContext.js";
7
+ // CSS Property Map
8
+ const propertyMap = {
9
+ // Padding
10
+ p: 'padding',
11
+ pt: 'padding-top',
12
+ pr: 'padding-right',
13
+ pb: 'padding-bottom',
14
+ pl: 'padding-left',
15
+ px: 'padding-inline',
16
+ py: 'padding-block',
17
+ // Margin
18
+ m: 'margin',
19
+ mt: 'margin-top',
20
+ mr: 'margin-right',
21
+ mb: 'margin-bottom',
22
+ ml: 'margin-left',
23
+ mx: 'margin-inline',
24
+ my: 'margin-block',
25
+ // Size
26
+ w: 'width',
27
+ h: 'height',
28
+ minw: 'min-width',
29
+ maxw: 'max-width',
30
+ minh: 'min-height',
31
+ maxh: 'max-height',
32
+ // Display
33
+ display: 'display',
34
+ // Color and Background
35
+ c: 'color',
36
+ bg: 'background',
37
+ // Border
38
+ bd: 'border',
39
+ rounded: 'border-radius',
40
+ // Shadow
41
+ shadow: 'box-shadow',
42
+ // Stack
43
+ spacing: 'gap',
44
+ align: 'align-items',
45
+ justify: 'justify-content'
46
+ };
47
+
48
+ // Breakpoint values in pixels - matching SCSS variables
49
+ const breakpointValues = {
50
+ xs: 0,
51
+ // Base mobile first
52
+ sm: 576,
53
+ // $screen-sm
54
+ md: 768,
55
+ // $screen-md
56
+ lg: 992,
57
+ // $screen-lg
58
+ xl: 1200,
59
+ // $screen-xl
60
+ xxl: 1400 // $screen-xxl
61
+ };
62
+
63
+ /**
64
+ * Options for the useStyled hook
65
+ */
66
+
67
+ /**
68
+ * Result of the useStyled hook
69
+ */
70
+
71
+ /**
72
+ * Checks if a value is a responsive value object
73
+ * @param value - Value to check
74
+ * @returns True if the value is a responsive value object
75
+ */
76
+ function isResponsiveValue(value) {
77
+ return value !== null && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).some(key => BREAKPOINTS.includes(key));
78
+ }
79
+
80
+ /**
81
+ * Custom hook for managing component styling with scoped CSS variables
82
+ *
83
+ * This hook handles:
84
+ * 1. Generating a unique class name for the component
85
+ * 2. Creating a scoped style rule to prevent CSS variable inheritance
86
+ * 3. Managing the lifecycle of style rules
87
+ * 4. Handling responsive values for different breakpoints
88
+ *
89
+ * @param options - Styling options
90
+ * @returns Styling properties to apply to the component
91
+ */
92
+ export function useStyled(options) {
93
+ const {
94
+ cssVars = {},
95
+ className,
96
+ style,
97
+ enabled = true,
98
+ prefix = 'box'
99
+ } = options;
100
+
101
+ // CSS Variable Prefix, e.g. --rs-box-
102
+ const cssVarPrefix = `--rs-${prefix}-`;
103
+ const {
104
+ csp
105
+ } = useContext(CustomContext);
106
+
107
+ // Generate a unique ID for this component instance
108
+ const uniqueId = useId().replace(/:/g, '');
109
+ const componentId = `rs-${prefix}-${uniqueId}`;
110
+
111
+ // Only apply styling if enabled and there are CSS variables
112
+ const shouldApplyStyles = enabled && !isEmpty(cssVars);
113
+
114
+ // Apply CSS variables through StyleManager
115
+ useLayoutEffect(() => {
116
+ if (!shouldApplyStyles) return;
117
+
118
+ // Create base CSS rules for the variables
119
+ let baseVarRules = '';
120
+ let basePropRules = '';
121
+
122
+ // Track responsive variables to handle separately
123
+ const responsiveVars = {};
124
+
125
+ // Process CSS variables, separating responsive from non-responsive
126
+ Object.entries(cssVars).forEach(([key, value]) => {
127
+ if (value !== undefined) {
128
+ if (isResponsiveValue(value)) {
129
+ // Store responsive values for later processing
130
+ responsiveVars[key] = value;
131
+
132
+ // Add xs (mobile first) values to base styles if present
133
+ const xsValue = value.xs;
134
+ if (xsValue !== undefined) {
135
+ baseVarRules += `${key}: ${xsValue}; `;
136
+ }
137
+ } else {
138
+ // Add non-responsive values directly
139
+ baseVarRules += `${key}: ${value}; `;
140
+ }
141
+ }
142
+ });
143
+
144
+ // Add actual style rules based on CSS variables
145
+ Object.keys(cssVars).forEach(varName => {
146
+ // Skip responsive values that don't have xs values
147
+ if (responsiveVars[varName] && !responsiveVars[varName].xs) return;
148
+
149
+ // Extract property name from variable name (remove prefix)
150
+ const propName = varName.startsWith(cssVarPrefix) ? varName.substring(cssVarPrefix.length) : varName;
151
+
152
+ // Check if the property has a corresponding CSS property mapping
153
+ const cssProperty = propertyMap[propName];
154
+ if (cssProperty) {
155
+ basePropRules += `${cssProperty}: var(${varName}); `;
156
+ }
157
+ });
158
+
159
+ // Combine variable definitions and property assignments
160
+ const baseCssRules = baseVarRules + basePropRules;
161
+
162
+ // Add the base rule to the style manager
163
+ StyleManager.addRule(`.${componentId}`, baseCssRules, {
164
+ nonce: csp === null || csp === void 0 ? void 0 : csp.nonce
165
+ });
166
+
167
+ // Process responsive variables
168
+ if (!isEmpty(responsiveVars)) {
169
+ // Create media queries for each breakpoint
170
+ const breakpointVarRules = {
171
+ xs: '',
172
+ // xs rules will be merged into base styles
173
+ sm: '',
174
+ md: '',
175
+ lg: '',
176
+ xl: '',
177
+ xxl: ''
178
+ };
179
+ const breakpointPropRules = {
180
+ xs: '',
181
+ sm: '',
182
+ md: '',
183
+ lg: '',
184
+ xl: '',
185
+ xxl: ''
186
+ };
187
+
188
+ // Group styles by breakpoint
189
+ Object.entries(responsiveVars).forEach(([varName, responsiveValue]) => {
190
+ Object.entries(responsiveValue).forEach(([breakpoint, value]) => {
191
+ const bp = breakpoint;
192
+ if (value !== undefined && bp !== 'xs') {
193
+ // Skip xs as it's already in base styles
194
+ // Add the CSS variable definition for this breakpoint
195
+ breakpointVarRules[bp] += `${varName}: ${value}; `;
196
+
197
+ // Extract property name from variable name (remove prefix)
198
+ const propName = varName.startsWith(cssVarPrefix) ? varName.substring(cssVarPrefix.length) : varName;
199
+
200
+ // Check if the property has a corresponding CSS property mapping
201
+ const cssProperty = propertyMap[propName];
202
+ if (cssProperty) {
203
+ breakpointPropRules[bp] += `${cssProperty}: var(${varName}); `;
204
+ }
205
+ }
206
+ });
207
+ });
208
+
209
+ // Combine variable definitions and property assignments for each breakpoint
210
+ const breakpointRules = {
211
+ xs: '',
212
+ sm: breakpointVarRules.sm + breakpointPropRules.sm,
213
+ md: breakpointVarRules.md + breakpointPropRules.md,
214
+ lg: breakpointVarRules.lg + breakpointPropRules.lg,
215
+ xl: breakpointVarRules.xl + breakpointPropRules.xl,
216
+ xxl: breakpointVarRules.xxl + breakpointPropRules.xxl
217
+ };
218
+
219
+ // Add media queries for each breakpoint with rules (skip xs)
220
+ Object.entries(breakpointRules).forEach(([breakpoint, rules]) => {
221
+ if (rules && breakpoint !== 'xs') {
222
+ const bp = breakpoint;
223
+ const minWidth = breakpointValues[bp];
224
+ StyleManager.addRule(`@media (min-width: ${minWidth}px)`, `.${componentId} { ${rules} }`, {
225
+ nonce: csp === null || csp === void 0 ? void 0 : csp.nonce
226
+ });
227
+ }
228
+ });
229
+ }
230
+ return () => {
231
+ // Clean up rules when component unmounts
232
+ StyleManager.removeRule(`.${componentId}`);
233
+
234
+ // Clean up media query rules
235
+ Object.keys(breakpointValues).forEach(breakpoint => {
236
+ const bp = breakpoint;
237
+ const minWidth = breakpointValues[bp];
238
+ StyleManager.removeRule(`@media (min-width: ${minWidth}px)`);
239
+ });
240
+ };
241
+ }, [componentId, cssVars, shouldApplyStyles]);
242
+
243
+ // Combine class names
244
+ const combinedClassName = shouldApplyStyles ? `${className || ''} ${componentId}`.trim() : className;
245
+ return {
246
+ className: combinedClassName || undefined,
247
+ style,
248
+ id: componentId
249
+ };
250
+ }
251
+ export default useStyled;
@@ -19,7 +19,7 @@ export const getColorVar = color => {
19
19
 
20
20
  // Check if color is a color with shade (e.g., 'red.50', 'gray.900')
21
21
  const colorWithShadeRegex = /^(red|orange|yellow|green|cyan|blue|violet|gray)\.([1-9]00|50)$/;
22
- const match = color.match(colorWithShadeRegex);
22
+ const match = color === null || color === void 0 ? void 0 : color.match(colorWithShadeRegex);
23
23
  if (match) {
24
24
  const [, colorName, shade] = match;
25
25
  return `var(--rs-${colorName}-${shade})`;
@@ -3,7 +3,7 @@ import type { StyleProperties } from '../../types';
3
3
  /**
4
4
  * Processes and returns a value suitable for CSS (with a unit).
5
5
  */
6
- export declare function getCssValue(value?: number | string | null, unit?: string): string;
6
+ export declare function getCssValue(value?: number | string | null, unit?: string): string | undefined;
7
7
  /**
8
8
  * Merge multiple style objects, filtering out undefined values
9
9
  */
@@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty';
5
5
  */
6
6
  export function getCssValue(value, unit = 'px') {
7
7
  if (value === undefined || value === null || value === '') {
8
- return '';
8
+ return undefined;
9
9
  }
10
10
 
11
11
  // If the value is 0, return it as a string without unit
@@ -2,3 +2,4 @@ export * from './styles';
2
2
  export * from './css';
3
3
  export * from './prefix';
4
4
  export * from './responsive';
5
+ export * from './style-manager';
@@ -2,4 +2,5 @@
2
2
  export * from "./styles.js";
3
3
  export * from "./css.js";
4
4
  export * from "./prefix.js";
5
- export * from "./responsive.js";
5
+ export * from "./responsive.js";
6
+ export * from "./style-manager.js";