Skip to content

Commit

Permalink
Add Input component
Browse files Browse the repository at this point in the history
  • Loading branch information
exoup committed Mar 14, 2024
1 parent be80e8e commit 76c3900
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
70 changes: 70 additions & 0 deletions src/components/Input/Input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useTheme } from "../../context/ThemeContext";
import { twMerge } from "tailwind-merge";
import lookupOptions from "../../util/lookupOptions";
import mapObjectToString from "../../util/mapObjectToString";

const Input = ({ containerProps, labelProps, label, placeholder, typography, color, radius, variant, className, ...args }) => {
const { input, typography: typographyOptions, themeColor } = useTheme();
const { defaultOptions, styles } = input;
const { initial, radii, variants } = styles;

const resolvedColor = color || themeColor || defaultOptions.color;
const resolvedRadius = radius || defaultOptions.radius;
const resolvedVariant = variant || defaultOptions.variant;
const resolvedTypography = typography || themeColor || typographyOptions.defaultOptions.variant;

const initialContainerClasses = mapObjectToString(
lookupOptions(initial, 'container', 'container'),
lookupOptions(typographyOptions.styles.variants, resolvedTypography, typographyOptions.defaultOptions.variant),
);
const initialInputClasses = mapObjectToString(
lookupOptions(initial, 'input', 'input'),
lookupOptions(radii, resolvedRadius, defaultOptions.radius),
);
const initialLabelClasses = mapObjectToString(
lookupOptions(initial, 'label', 'label'),
);
const inputVariant = mapObjectToString(
lookupOptions(variants, resolvedVariant, defaultOptions.variant)['input']['base'],
lookupOptions(variants, resolvedVariant, defaultOptions.variant)['input']['style'][resolvedColor],
);
const labelVariant = mapObjectToString(
lookupOptions(variants, resolvedVariant, defaultOptions.variant)['label']['base'],
lookupOptions(variants, resolvedVariant, defaultOptions.variant)['label']['style'][resolvedColor],
);

const containerClasses = twMerge(
...initialContainerClasses,
containerProps?.className
);
const inputClasses = twMerge(
...initialInputClasses,
...inputVariant,
className
);
const labelClasses = twMerge(
...initialLabelClasses,
...labelVariant,
labelProps?.className
);

return (
<div
{...containerProps}
className={containerClasses}>
<input
{...args}
placeholder={placeholder || ' '}
type={args.type || 'text'}
className={inputClasses}
/>
<label
{...labelProps}
className={labelClasses}>
{label}
</label>
</div>
)
};

export default Input;
32 changes: 32 additions & 0 deletions src/components/Input/Input.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Input from "./Input.jsx"

export default {
args: {
label: 'Username',
},
argTypes: {
color: {
defaultValue: 'default',
options: ['default', 'primary', 'secondary', 'tertiary', 'neutral'],
control: { type: 'inline-radio' }
},
radius: {
defaultValue: 'round',
options: ['round', 'sharp'],
control: { type: 'inline-radio' }
},
variant: {
defaultValue: 'floating',
options: ['floating', 'stacked'],
control: { type: 'inline-radio' }
}
}
};

export const InputStory = ({ ...args }) => (
<div className="w-72">
<Input {...args} />
</div>
);

InputStory.storyName = "Input";
27 changes: 27 additions & 0 deletions src/theme/components/Input/Input.theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// theme options
import FloatOptions from "./InputFloat.theme";

export const input = {
defaultOptions: {
color: 'default',
radius: 'round',
variant: 'floating',
},
styles: {
initial: {
container: {
position: 'relative'
}
},
radii: {
round: 'rounded-md',
sharp: 'rounded-none'
},
variants: {
floating: FloatOptions,
stacked: '',
}
}
};

export default input;
72 changes: 72 additions & 0 deletions src/theme/components/Input/InputFloat.theme.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const FloatOptions = {
input: {
base: {
initial: 'peer block w-full bg-transparent border-2',
animation: 'motion-safe:transition-all',
reset: 'focus:ring-0 focus-visible:outline-0',
light: 'border-gray-300 bg-white',
dark: 'dark:bg-zinc-900 dark:border-zinc-800',
},
style: {
default: {
light: 'focus-within:border-inherit',
dark: 'dark:focus-within:border-inherit'
},
primary: {
light: 'focus-within:border-primary-500',
dark: 'dark:focus-within:border-primary-500'
},
secondary: {
light: 'focus-within:border-secondary-500',
dark: 'dark:focus-within:border-secondary-500'
},
tertiary: {
light: 'focus-within:border-tertiary-500',
dark: 'dark:focus-within:border-tertiary-500'
}
}
},
label: {
base: {
initial: 'px-1 scale-75 select-none pointer-events-none',
position: 'absolute z-[1] left-3 top-0 -translate-y-1/2 origin-[0]',
placeholder: 'peer-placeholder-shown:scale-100 peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2',
peerfocus: 'peer-focus-within:scale-75 peer-focus-within:top-0 peer-focus-within:-translate-y-1/2',
animation: 'motion-safe:transition-all',
light: 'bg-white',
dark: 'dark:bg-zinc-900',
},
style: {
default: {
light: 'peer-focus-within:text-inherit',
},
primary: {
light: 'peer-focus-within:text-primary-500',
},
secondary: {
light: 'peer-focus-within:text-secondary-500',
},
tertiary: {
light: 'peer-focus-within:text-tertiary-500',
}
}
},
};

export default FloatOptions;

// const OverlapOptions = {
// input: {
// base: 'block w-full px-4 bg-transparent peer',
// animation: 'transition-all',
// reset: 'border-none focus:ring-0 focus-visible:outline-0',
// },
// label: {
// base: 'w-full pointer-events-none',
// position: 'absolute top-1/2 left-3 -translate-y-1/2',
// focus: 'peer-focus:-top-2.5 peer-focus:text-sm peer-focus:bg-white peer-focus:translate-y-[unset] peer-focus:px-1',
// animation: 'transition-all',
// },
// };

// export default OverlapOptions;
2 changes: 2 additions & 0 deletions src/theme/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import accordion from "./components/Accordion/Accordion.theme";
import avatar from "./components/Avatar/Avatar.theme";
import button from "./components/Button/Button.theme";
import card from "./components/Card/Card.theme";
import input from "./components/Input/Input.theme";
import menu from "./components/Menu/Menu.theme";
import typography from "./components/Typography/Typography.theme";

Expand All @@ -10,6 +11,7 @@ const theme = {
avatar,
button,
card,
input,
menu,
typography
}
Expand Down

0 comments on commit 76c3900

Please sign in to comment.