, 'size'> {
+ label?: string;
+ description?: string;
+ leftIcon?: ReactNode;
+ rightIcon?: ReactNode;
+ helperText?: string;
+}
+
+export const Input = ({
+ className,
+ label,
+ description,
+ leftIcon,
+ rightIcon,
+ helperText,
+ size,
+ state,
+ ...props
+}: InputProps) => {
+ const styleProps = (({ size = 'md', state }) => ({
+ size,
+ state,
+ }))({ size, state });
+
+ const {
+ container: containerCls,
+ label: labelCls,
+ description: descriptionCls,
+ input: inputCls,
+ icon: iconCls,
+ iconContainer: iconContainerCls,
+ helperText: helperTextCls,
+ helperIcon: helperIconCls,
+ } = inputTheme({ ...styleProps });
+
+ const renderLabels = useMemo(
+ () => (
+
+
{label}
+
{description}
+
+ ),
+ [labelCls, descriptionCls, label, description],
+ );
+
+ const renderLeftIcon = useMemo(() => {
+ return (
+
+ {cloneIcon(leftIcon, { className: iconCls(), ariaHidden: true })}
+
+ );
+ }, [cloneIcon, iconCls, iconContainerCls, leftIcon]);
+
+ const renderRightIcon = useMemo(() => {
+ return (
+
+ {cloneIcon(rightIcon, { className: iconCls(), ariaHidden: true })}
+
+ );
+ }, [cloneIcon, iconCls, iconContainerCls, rightIcon]);
+
+ const renderHelperText = useMemo(
+ () => (
+
+ {state &&
+ cloneIcon(
, {
+ ariaHidden: true,
+ })}
+
{helperText}
+
+ ),
+ [cloneIcon, state, helperIconCls, helperText, helperTextCls],
+ );
+
+ return (
+
+ {renderLabels}
+
+ {leftIcon && renderLeftIcon}
+
+ {rightIcon && renderRightIcon}
+
+ {renderHelperText}
+
+ );
+};
diff --git a/packages/frontend/src/components/shared/Input/index.ts b/packages/frontend/src/components/shared/Input/index.ts
new file mode 100644
index 00000000..9ffcc229
--- /dev/null
+++ b/packages/frontend/src/components/shared/Input/index.ts
@@ -0,0 +1,2 @@
+export * from './Input';
+export * from './Input.theme';
diff --git a/packages/frontend/src/pages/components/index.tsx b/packages/frontend/src/pages/components/index.tsx
index 07ffedb7..b2c81d31 100644
--- a/packages/frontend/src/pages/components/index.tsx
+++ b/packages/frontend/src/pages/components/index.tsx
@@ -7,7 +7,11 @@ import {
} from './renders/checkbox';
import { avatars, avatarsFallback } from './renders/avatar';
import { renderBadges } from './renders/badge';
-import { renderButtonIcons, renderButtons } from './renders/button';
+import {
+ renderButtonIcons,
+ renderButtons,
+ renderLinks,
+} from './renders/button';
import {
renderTabWithBadges,
renderTabs,
@@ -17,6 +21,7 @@ import {
renderInlineNotificationWithDescriptions,
renderInlineNotifications,
} from './renders/inlineNotifications';
+import { renderInputs } from './renders/input';
const Page = () => {
const [singleDate, setSingleDate] = useState();
@@ -37,6 +42,11 @@ const Page = () => {
{/* Button */}
+
Input
+
{renderInputs()}
+
+
+
Button
{renderButtons()}
@@ -129,6 +139,16 @@ const Page = () => {
{renderInlineNotificationWithDescriptions()}
+
+
+
+ {/* Link */}
+
+
Link
+
+ {renderLinks()}
+
+
diff --git a/packages/frontend/src/pages/components/renders/button.tsx b/packages/frontend/src/pages/components/renders/button.tsx
index c1c69c48..f5272d3e 100644
--- a/packages/frontend/src/pages/components/renders/button.tsx
+++ b/packages/frontend/src/pages/components/renders/button.tsx
@@ -47,3 +47,19 @@ export const renderButtonIcons = () => {
));
};
+
+export const renderLinks = () => {
+ return ['link', 'link-emphasized', 'disabled'].map((variant) => (
+ }
+ rightIcon={}
+ disabled={variant === 'disabled'}
+ >
+ Link
+
+ ));
+};
diff --git a/packages/frontend/src/pages/components/renders/input.tsx b/packages/frontend/src/pages/components/renders/input.tsx
new file mode 100644
index 00000000..bc0b79ff
--- /dev/null
+++ b/packages/frontend/src/pages/components/renders/input.tsx
@@ -0,0 +1,57 @@
+import React from 'react';
+import { Input } from 'components/shared/Input';
+import { SearchIcon, CrossIcon } from 'components/shared/CustomIcon';
+
+export const renderInputs = () => {
+ return (
+ <>
+
+ }
+ rightIcon={}
+ placeholder="Placeholder text"
+ />
+
+
+
+
+ }
+ rightIcon={}
+ description="Additional information or context"
+ placeholder="Placeholder text"
+ size="sm"
+ />
+
+
+
+ >
+ );
+};
diff --git a/packages/frontend/src/utils/classnames.ts b/packages/frontend/src/utils/classnames.ts
new file mode 100644
index 00000000..7c5139f9
--- /dev/null
+++ b/packages/frontend/src/utils/classnames.ts
@@ -0,0 +1,13 @@
+import { clsx } from 'clsx';
+import type { ClassValue } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+/**
+ * Returns a merged class name string by merging and processing multiple class names and Tailwind CSS styles.
+ *
+ * @param {...string[]} args - One or more class names and/or Tailwind CSS styles to be merged.
+ * @returns {string} - The merged class name string.
+ */
+export function cn(...args: ClassValue[]): string {
+ return twMerge(clsx(args));
+}
diff --git a/yarn.lock b/yarn.lock
index d24c5a8a..c8881430 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6327,7 +6327,7 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
-clsx@^2.0.0:
+clsx@^2.0.0, clsx@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==