Skip to content

Commit 30c7db5

Browse files
author
Marcin Charmułowicz
committed
[Fix] inputClassName, containerClassName, and toggleClassName accept functions to override component className (#64)
1 parent f58c597 commit 30c7db5

File tree

5 files changed

+40
-36
lines changed

5 files changed

+40
-36
lines changed

pages/index.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { useState } from "react";
33
import { COLORS } from "../src/constants";
44
import dayjs from "dayjs";
55
import Head from "next/head";
6-
import { twMerge } from "tailwind-merge";
76

87
export default function Playground() {
98
const [value, setValue] = useState({
@@ -79,10 +78,6 @@ export default function Playground() {
7978
i18n={i18n}
8079
disabled={disabled}
8180
inputClassName={inputClassName}
82-
/**
83-
* `twMerge` Test
84-
*/
85-
// inputClassName={twMerge(inputClassName, 'dark:bg-white')}
8681
containerClassName={containerClassName}
8782
toggleClassName={toggleClassName}
8883
displayFormat={displayFormat}

src/components/Datepicker.tsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,7 @@ import { COLORS, DATE_FORMAT, DEFAULT_COLOR, LANGUAGE } from "../constants";
99
import DatepickerContext from "../contexts/DatepickerContext";
1010
import { formatDate, nextMonth, previousMonth } from "../helpers";
1111
import useOnClickOutside from "../hooks";
12-
import {
13-
Period,
14-
DateValueType,
15-
DateType,
16-
DateRangeType,
17-
ClassNamesTypeProp,
18-
ClassNameParam
19-
} from "../types";
12+
import { Period, DateValueType, DateType, DateRangeType, ClassNamesTypeProp } from "../types";
2013

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

@@ -46,13 +39,13 @@ interface Props {
4639
startFrom?: Date | null;
4740
i18n?: string;
4841
disabled?: boolean;
49-
classNames?: ClassNamesTypeProp | undefined;
50-
inputClassName?: ((args?: ClassNameParam) => string) | string | null;
51-
toggleClassName?: string | null;
52-
toggleIcon?: ((open: ClassNameParam) => React.ReactNode) | undefined;
42+
classNames?: ClassNamesTypeProp;
43+
inputClassName?: ((className: string) => string) | string | null;
44+
containerClassName?: ((className: string) => string) | string | null;
45+
toggleClassName?: ((className: string) => string) | string | null;
46+
toggleIcon?: (open: boolean) => React.ReactNode;
5347
inputId?: string;
5448
inputName?: string;
55-
containerClassName?: ((args?: ClassNameParam) => string) | string | null;
5649
displayFormat?: string;
5750
readOnly?: boolean;
5851
minDate?: DateType | null;
@@ -348,12 +341,18 @@ const Datepicker: React.FC<Props> = ({
348341
inputRef
349342
]);
350343

344+
const defaultContainerClassName = "relative w-full text-gray-700";
345+
346+
const containerClassNameOverload =
347+
typeof containerClassName === "function"
348+
? containerClassName(defaultContainerClassName)
349+
: typeof containerClassName === "string"
350+
? `${defaultContainerClassName} ${containerClassName}`
351+
: defaultContainerClassName;
352+
351353
return (
352354
<DatepickerContext.Provider value={contextValues}>
353-
<div
354-
className={`relative w-full text-gray-700 ${containerClassName}`}
355-
ref={containerRef}
356-
>
355+
<div className={containerClassNameOverload} ref={containerRef}>
357356
<Input setContextRef={setInputRef} />
358357

359358
<div

src/components/Input.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,21 @@ const Input: React.FC<Props> = (e: Props) => {
5252
const getClassName = useCallback(() => {
5353
const input = inputRef.current;
5454

55-
if (input && typeof classNames != "undefined" && typeof classNames.input === "function") {
56-
return classNames?.input(input);
55+
if (input && typeof classNames !== "undefined" && typeof classNames?.input === "function") {
56+
return classNames.input(input);
5757
}
5858

5959
const border = BORDER_COLOR.focus[primaryColor as keyof typeof BORDER_COLOR.focus];
6060
const ring =
6161
RING_COLOR["second-focus"][primaryColor as keyof (typeof RING_COLOR)["second-focus"]];
62-
const classNameOverload = typeof inputClassName === "string" ? inputClassName : "";
63-
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}`;
62+
63+
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}`;
64+
65+
return typeof inputClassName === "function"
66+
? inputClassName(defaultInputClassName)
67+
: typeof inputClassName === "string"
68+
? `${defaultInputClassName} ${inputClassName}`
69+
: defaultInputClassName;
6470
}, [inputRef, classNames, primaryColor, inputClassName]);
6571

6672
const handleInputChange = useCallback(
@@ -210,12 +216,19 @@ const Input: React.FC<Props> = (e: Props) => {
210216
if (
211217
button &&
212218
typeof classNames !== "undefined" &&
213-
typeof classNames.toggleButton === "function"
219+
typeof classNames?.toggleButton === "function"
214220
) {
215221
return classNames.toggleButton(button);
216222
}
217223

218-
return `absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed ${toggleClassName}`;
224+
const defaultToggleClassName =
225+
"absolute right-0 h-full px-3 text-gray-400 focus:outline-none disabled:opacity-40 disabled:cursor-not-allowed";
226+
227+
return typeof toggleClassName === "function"
228+
? toggleClassName(defaultToggleClassName)
229+
: typeof toggleClassName === "string"
230+
? `${defaultToggleClassName} ${toggleClassName}`
231+
: defaultToggleClassName;
219232
}, [toggleClassName, buttonRef, classNames]);
220233

221234
return (

src/contexts/DatepickerContext.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import {
88
DateValueType,
99
DateType,
1010
DateRangeType,
11-
ClassNamesTypeProp,
12-
ClassNameParam
11+
ClassNamesTypeProp
1312
} from "../types";
1413

1514
interface DatepickerStore {
@@ -34,9 +33,9 @@ interface DatepickerStore {
3433
i18n: string;
3534
value: DateValueType;
3635
disabled?: boolean;
37-
inputClassName?: ((args?: ClassNameParam) => string) | string | null;
38-
containerClassName?: ((args?: ClassNameParam) => string) | string | null;
39-
toggleClassName?: ((args?: ClassNameParam) => string) | string | null;
36+
inputClassName?: ((className: string) => string) | string | null;
37+
containerClassName?: ((className: string) => string) | string | null;
38+
toggleClassName?: ((className: string) => string) | string | null;
4039
toggleIcon?: (open: boolean) => React.ReactNode;
4140
readOnly?: boolean;
4241
startWeekOn?: string | null;
@@ -46,7 +45,7 @@ interface DatepickerStore {
4645
disabledDates?: DateRangeType[] | null;
4746
inputId?: string;
4847
inputName?: string;
49-
classNames?: ClassNamesTypeProp | undefined;
48+
classNames?: ClassNamesTypeProp;
5049
}
5150

5251
const DatepickerContext = createContext<DatepickerStore>({

src/types/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,3 @@ export type ClassNamesTypeProp = {
4141
toggleButton?: (p?: object | null | undefined) => string | undefined;
4242
footer?: (p?: object | null | undefined) => string | undefined;
4343
};
44-
45-
export type ClassNameParam = ClassNameParam[] | string | number | boolean | undefined;

0 commit comments

Comments
 (0)