Skip to content

Commit

Permalink
[Fix] inputClassName, containerClassName, and toggleClassName accept…
Browse files Browse the repository at this point in the history
… functions to override component className (onesine#64)
  • Loading branch information
Marcin Charmułowicz committed Mar 2, 2023
1 parent f58c597 commit 30c7db5
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 36 deletions.
5 changes: 0 additions & 5 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { useState } from "react";
import { COLORS } from "../src/constants";
import dayjs from "dayjs";
import Head from "next/head";
import { twMerge } from "tailwind-merge";

export default function Playground() {
const [value, setValue] = useState({
Expand Down Expand Up @@ -79,10 +78,6 @@ export default function Playground() {
i18n={i18n}
disabled={disabled}
inputClassName={inputClassName}
/**
* `twMerge` Test
*/
// inputClassName={twMerge(inputClassName, 'dark:bg-white')}
containerClassName={containerClassName}
toggleClassName={toggleClassName}
displayFormat={displayFormat}
Expand Down
33 changes: 16 additions & 17 deletions src/components/Datepicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ import { COLORS, DATE_FORMAT, DEFAULT_COLOR, LANGUAGE } from "../constants";
import DatepickerContext from "../contexts/DatepickerContext";
import { formatDate, nextMonth, previousMonth } from "../helpers";
import useOnClickOutside from "../hooks";
import {
Period,
DateValueType,
DateType,
DateRangeType,
ClassNamesTypeProp,
ClassNameParam
} from "../types";
import { Period, DateValueType, DateType, DateRangeType, ClassNamesTypeProp } from "../types";

import { Arrow, VerticalDash } from "./utils";

Expand Down Expand Up @@ -46,13 +39,13 @@ interface Props {
startFrom?: Date | null;
i18n?: string;
disabled?: boolean;
classNames?: ClassNamesTypeProp | undefined;
inputClassName?: ((args?: ClassNameParam) => string) | string | null;
toggleClassName?: string | null;
toggleIcon?: ((open: ClassNameParam) => React.ReactNode) | undefined;
classNames?: ClassNamesTypeProp;
inputClassName?: ((className: string) => string) | string | null;
containerClassName?: ((className: string) => string) | string | null;
toggleClassName?: ((className: string) => string) | string | null;
toggleIcon?: (open: boolean) => React.ReactNode;
inputId?: string;
inputName?: string;
containerClassName?: ((args?: ClassNameParam) => string) | string | null;
displayFormat?: string;
readOnly?: boolean;
minDate?: DateType | null;
Expand Down Expand Up @@ -348,12 +341,18 @@ const Datepicker: React.FC<Props> = ({
inputRef
]);

const defaultContainerClassName = "relative w-full text-gray-700";

const containerClassNameOverload =
typeof containerClassName === "function"
? containerClassName(defaultContainerClassName)
: typeof containerClassName === "string"
? `${defaultContainerClassName} ${containerClassName}`
: defaultContainerClassName;

return (
<DatepickerContext.Provider value={contextValues}>
<div
className={`relative w-full text-gray-700 ${containerClassName}`}
ref={containerRef}
>
<div className={containerClassNameOverload} ref={containerRef}>
<Input setContextRef={setInputRef} />

<div
Expand Down
25 changes: 19 additions & 6 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,21 @@ const Input: React.FC<Props> = (e: Props) => {
const getClassName = useCallback(() => {
const input = inputRef.current;

if (input && typeof classNames != "undefined" && typeof classNames.input === "function") {
return classNames?.input(input);
if (input && typeof classNames !== "undefined" && typeof classNames?.input === "function") {
return classNames.input(input);
}

const border = BORDER_COLOR.focus[primaryColor as keyof typeof BORDER_COLOR.focus];
const ring =
RING_COLOR["second-focus"][primaryColor as keyof (typeof RING_COLOR)["second-focus"]];
const classNameOverload = typeof inputClassName === "string" ? inputClassName : "";
return `relative transition-all duration-300 py-2.5 pl-4 pr-14 w-full border-gray-300 dark:bg-slate-800 dark:text-white/80 dark:border-slate-600 rounded-lg tracking-wide font-light text-sm placeholder-gray-400 bg-white focus:ring disabled:opacity-40 disabled:cursor-not-allowed ${border} ${ring} ${classNameOverload}`;

const defaultInputClassName = `relative transition-all duration-300 py-2.5 pl-4 pr-14 w-full border-gray-300 dark:bg-slate-800 dark:text-white/80 dark:border-slate-600 rounded-lg tracking-wide font-light text-sm placeholder-gray-400 bg-white focus:ring disabled:opacity-40 disabled:cursor-not-allowed ${border} ${ring}`;

return typeof inputClassName === "function"
? inputClassName(defaultInputClassName)
: typeof inputClassName === "string"
? `${defaultInputClassName} ${inputClassName}`
: defaultInputClassName;
}, [inputRef, classNames, primaryColor, inputClassName]);

const handleInputChange = useCallback(
Expand Down Expand Up @@ -210,12 +216,19 @@ const Input: React.FC<Props> = (e: Props) => {
if (
button &&
typeof classNames !== "undefined" &&
typeof classNames.toggleButton === "function"
typeof classNames?.toggleButton === "function"
) {
return classNames.toggleButton(button);
}

return `absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed ${toggleClassName}`;
const defaultToggleClassName =
"absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed";

return typeof toggleClassName === "function"
? toggleClassName(defaultToggleClassName)
: typeof toggleClassName === "string"
? `${defaultToggleClassName} ${toggleClassName}`
: defaultToggleClassName;
}, [toggleClassName, buttonRef, classNames]);

return (
Expand Down
11 changes: 5 additions & 6 deletions src/contexts/DatepickerContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
DateValueType,
DateType,
DateRangeType,
ClassNamesTypeProp,
ClassNameParam
ClassNamesTypeProp
} from "../types";

interface DatepickerStore {
Expand All @@ -34,9 +33,9 @@ interface DatepickerStore {
i18n: string;
value: DateValueType;
disabled?: boolean;
inputClassName?: ((args?: ClassNameParam) => string) | string | null;
containerClassName?: ((args?: ClassNameParam) => string) | string | null;
toggleClassName?: ((args?: ClassNameParam) => string) | string | null;
inputClassName?: ((className: string) => string) | string | null;
containerClassName?: ((className: string) => string) | string | null;
toggleClassName?: ((className: string) => string) | string | null;
toggleIcon?: (open: boolean) => React.ReactNode;
readOnly?: boolean;
startWeekOn?: string | null;
Expand All @@ -46,7 +45,7 @@ interface DatepickerStore {
disabledDates?: DateRangeType[] | null;
inputId?: string;
inputName?: string;
classNames?: ClassNamesTypeProp | undefined;
classNames?: ClassNamesTypeProp;
}

const DatepickerContext = createContext<DatepickerStore>({
Expand Down
2 changes: 0 additions & 2 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,3 @@ export type ClassNamesTypeProp = {
toggleButton?: (p?: object | null | undefined) => string | undefined;
footer?: (p?: object | null | undefined) => string | undefined;
};

export type ClassNameParam = ClassNameParam[] | string | number | boolean | undefined;

0 comments on commit 30c7db5

Please sign in to comment.