` HTML
element. This enables making the component interactive and helps to improve
its accessibility.
-👉 For the full list of supported attributes refer to:
+👉 For forwarding HTML attributes programmatically, you can use the `transferProps` function. For detailed usage examples, refer to the [TransferProps documentation](/src/docs/js-helpers/transferProps.md).
+
+For the full list of supported attributes, you can also refer to:
- [`
` HTML element attributes][div-attributes]{:target="_blank"}
- [React common props]{:target="_blank"}
+
## API
diff --git a/src/components/_helpers/transferProps.js b/src/components/_helpers/transferProps.js
index d9d60729..c22a2398 100644
--- a/src/components/_helpers/transferProps.js
+++ b/src/components/_helpers/transferProps.js
@@ -24,6 +24,8 @@ export const transferProps = (props) => {
} = props;
if (process.env.NODE_ENV !== 'production') {
+ // eslint-disable-next-line no-console
+ console.log('props', props);
const invalidProps = [
'children', // It is always either handled by the component itself or not supported.
'className', // Classes are set by component authors, changing it arbitrarily might break things.
diff --git a/src/docs/js-helpers/classnames.md b/src/docs/js-helpers/classnames.md
index 3f66fbcc..232597a5 100644
--- a/src/docs/js-helpers/classnames.md
+++ b/src/docs/js-helpers/classnames.md
@@ -19,7 +19,7 @@ And use it:
1609455600 && 'text-warning',
+ Date.now() > 1609455600 && 'text-warning',
Date.now() > 1622498400 ? 'text-secondary' : null,
)}
>
diff --git a/src/docs/js-helpers/transferProps.md b/src/docs/js-helpers/transferProps.md
new file mode 100644
index 00000000..86c90d61
--- /dev/null
+++ b/src/docs/js-helpers/transferProps.md
@@ -0,0 +1,23 @@
+# TransferProps Function
+
+The `transferProps` function is a utility used to transfer props from one component to another while keeping the component code concise and manageable.
+
+## Basic Usage
+
+To use the `transferProps` function, you first need to import it:
+
+```javascript
+import { transferProps } from '../../utils/transferProps';
+
+```
+
+You can then use it within your components like so:
+
+```javascript
+const ChildComponent = (props) => {
+ // Transfer props to a child component
+ return ;
+};
+```
+
+The transferProps function ensures that only valid props are transferred, providing a clean and efficient way to pass props down the component tree.
diff --git a/src/utils/transferProps.js b/src/utils/transferProps.js
new file mode 100644
index 00000000..54ce580c
--- /dev/null
+++ b/src/utils/transferProps.js
@@ -0,0 +1,51 @@
+/**
+ * Controls passing of props from the React component to the HTML element
+ *
+ * Sometimes it is useful to have a mechanism to pass props from the React component to a rendered HTML element.
+ * It enables making the component interactive and helps improve its accessibility. However some props should
+ * never be passed to the HTML element as it would break things. This function is used to filter out such props.
+ *
+ * When run in development mode, the function will log the error to the console if any invalid props are passed.
+ *
+ * @param props The props that were passed to the React component and were not used by it
+ * @returns The props to be passed to the HTML element
+ */
+export const transferProps = (props) => {
+ const {
+ children,
+ className,
+ contentEditable,
+ dangerouslySetInnerHTML,
+ ref,
+ staticContext,
+ style,
+ suppressContentEditableWarning,
+ ...restProps
+ } = props;
+
+ if (process.env.NODE_ENV !== 'production') {
+ // eslint-disable-next-line no-console
+ console.log('props', props);
+ const invalidProps = [
+ 'children', // It is always either handled by the component itself or not supported.
+ 'className', // Classes are set by component authors, changing it arbitrarily might break things.
+ 'contentEditable', // Components are either interactive or not, changing it arbitrarily might break things.
+ 'dangerouslySetInnerHTML', // This might break things and allow for XSS attacks.
+ 'ref', // Forwarding `ref` is hardcoded and documented for each component.
+ 'staticContext', // In `react-router` (v4, v5) this is used during server side rendering, it makes no sense to pass it to a component.
+ 'style', // Styles are set by component authors, changing it arbitrarily might break things.
+ 'suppressContentEditableWarning', // Since setting `contentEditable` is not allowed, this is not needed.
+ ].filter((key) => props[key] !== undefined);
+
+ if (invalidProps.length > 0) {
+ // eslint-disable-next-line no-console
+ console.error(
+ `Invalid prop(s) supplied to the "transferProps" function: "${invalidProps.join(
+ '", "',
+ )}"`,
+ );
+ }
+ }
+
+ return restProps;
+};