Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,8 @@ export default function Playground() {
const [startFrom, setStartFrom] = useState("2023-03-01");
const [startWeekOn, setStartWeekOn] = useState("");

const handleChange = (value, e) => {
const handleChange = value => {
setValue(value);
console.log(e);
console.log("value", value);
};
return (
<div className="px-4 py-8">
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/checkClassName.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { describe, expect, test, jest } from "@jest/globals";

import { checkClassName } from "../helpers";

describe("checkClassName", () => {
const defaultClassName = "default-class";

test("should return result of toggleClassName function when it is a function", () => {
const toggleFunction = jest.fn(() => "custom-class");
const result = checkClassName(defaultClassName, toggleFunction);
expect(result).toBe("custom-class");
expect(toggleFunction).toHaveBeenCalledWith(defaultClassName);
});

test("should return toggleClassName when it is a non-empty string", () => {
const result = checkClassName(defaultClassName, "custom-class");
expect(result).toBe("custom-class");
});

test("should return defaultToggleClassName when toggleClassName is an empty string", () => {
const result = checkClassName(defaultClassName, "");
expect(result).toBe(defaultClassName);
});

test("should return defaultToggleClassName when toggleClassName is null", () => {
const result = checkClassName(defaultClassName, null);
expect(result).toBe(defaultClassName);
});

test("should return defaultToggleClassName when toggleClassName is undefined", () => {
const result = checkClassName(defaultClassName, undefined);
expect(result).toBe(defaultClassName);
});
});
41 changes: 18 additions & 23 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import React, { useCallback, useContext, useEffect, useRef } from "react";

import { BORDER_COLOR, DATE_FORMAT, RING_COLOR } from "../constants";
import DatepickerContext from "../contexts/DatepickerContext";
import { clearInvalidInput, dateIsValid, parseFormattedDate, shortString } from "../helpers";
import {
checkClassName,
clearInvalidInput,
dateIsValid,
parseFormattedDate,
shortString
} from "../helpers";

import ToggleButton from "./ToggleButton";

Expand Down Expand Up @@ -51,18 +57,13 @@ const Input: React.FC<Props> = (e: Props) => {
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 border = BORDER_COLOR.focus[primaryColor];
const ring = RING_COLOR["second-focus"][primaryColor];

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" && inputClassName !== ""
? inputClassName
: defaultInputClassName;
}, [inputRef, classNames, primaryColor, inputClassName]);
return checkClassName(defaultInputClassName, inputClassName);
}, [classNames, inputClassName, primaryColor]);

/**
* automatically adds correct separator character to date input
Expand Down Expand Up @@ -197,7 +198,7 @@ const Input: React.FC<Props> = (e: Props) => {
if (input) {
let lastChar = input.value[input.value.length - 1];
// cut off all non-numeric values
while (lastChar?.match(/\D/)) {
while (RegExp(/\D/).exec(lastChar)) {
const shortenedString = shortString(input.value, input.value.length - 1);
input.value = shortenedString;
lastChar = shortenedString[shortenedString.length - 1];
Expand Down Expand Up @@ -242,12 +243,8 @@ const Input: React.FC<Props> = (e: Props) => {
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" && toggleClassName !== ""
? toggleClassName
: defaultToggleClassName;
}, [toggleClassName, buttonRef, classNames]);
return checkClassName(defaultToggleClassName, toggleClassName);
}, [toggleClassName, classNames]);

// UseEffects && UseLayoutEffect
useEffect(() => {
Expand Down Expand Up @@ -309,7 +306,7 @@ const Input: React.FC<Props> = (e: Props) => {
const arrow = arrowContainer?.current;

function showCalendarContainer() {
if (arrow && div && div.classList.contains("hidden")) {
if (arrow && div?.classList.contains("hidden")) {
div.classList.remove("hidden");
div.classList.add("block");

Expand Down Expand Up @@ -361,15 +358,13 @@ const Input: React.FC<Props> = (e: Props) => {
disabled={disabled}
readOnly={readOnly}
placeholder={
placeholder
? placeholder
: `${displayFormat}${asSingle ? "" : ` ${separator} ${displayFormat}`}`
placeholder ||
`${displayFormat}${asSingle ? "" : ` ${separator} ${displayFormat}`}`
}
value={inputText}
id={inputId}
name={inputName}
autoComplete="off"
role="presentation"
onChange={handleInputChange}
onKeyDown={handleInputKeyDown}
/>
Expand All @@ -380,7 +375,7 @@ const Input: React.FC<Props> = (e: Props) => {
disabled={disabled}
className={getToggleClassName()}
>
{renderToggleIcon(inputText == null || !inputText?.length)}
{renderToggleIcon(!inputText.length)}
</button>
</>
);
Expand Down
19 changes: 10 additions & 9 deletions src/contexts/DatepickerContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import React, { createContext } from "react";

import { DATE_FORMAT, LANGUAGE, START_WEEK } from "../constants";
import {
ClassNamesTypeProp,
ClassType,
ColorKeys,
Configs,
Period,
DateValueType,
DateType,
DateRangeType,
ClassNamesTypeProp,
PopoverDirectionType,
ColorKeys
DateType,
DateValueType,
Period,
PopoverDirectionType
} from "../types";

interface DatepickerStore {
Expand All @@ -35,9 +36,9 @@ interface DatepickerStore {
i18n: string;
value: DateValueType;
disabled?: boolean;
inputClassName?: ((className: string) => string) | string | null;
containerClassName?: ((className: string) => string) | string | null;
toggleClassName?: ((className: string) => string) | string | null;
inputClassName?: ClassType;
containerClassName?: ClassType;
toggleClassName?: ClassType;
toggleIcon?: (open: boolean) => React.ReactNode;
readOnly?: boolean;
startWeekOn?: string | null;
Expand Down
18 changes: 17 additions & 1 deletion src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,28 @@ export function classNames(...classes: (false | null | undefined | string)[]) {
* @returns shortened string
*/
export const clearInvalidInput = (value: string): string => {
if (value && value[value.length - 1].match(/\D/g)) {
if (value[value.length - 1]?.match(/\D/g)) {
return shortString(value, value.length - 1);
}
return value;
};

/**
* checks and returns user-defined className or default className
*/
export const checkClassName = (
defaultToggleClassName: string,
toggleClassName?: string | ((className: string) => string) | null
) => {
if (typeof toggleClassName === "function") {
return toggleClassName(defaultToggleClassName);
}
if (typeof toggleClassName === "string" && toggleClassName !== "") {
return toggleClassName;
}
return defaultToggleClassName;
};

export function getTextColorByPrimaryColor(color: string) {
switch (color) {
case "blue":
Expand Down
10 changes: 6 additions & 4 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export type DateRangeType = {

export type DateValueType = DateRangeType | null;

export type ClassType = ((className: string) => string) | string | null;

export type ClassNamesTypeProp = {
container?: (p?: object | null | undefined) => string | undefined;
input?: (p?: object | null | undefined) => string | undefined;
Expand All @@ -67,10 +69,10 @@ export interface DatepickerType {
startFrom?: Date | null;
i18n?: string;
disabled?: boolean;
classNames?: ClassNamesTypeProp | undefined;
containerClassName?: ((className: string) => string) | string | null;
inputClassName?: ((className: string) => string) | string | null;
toggleClassName?: ((className: string) => string) | string | null;
classNames?: ClassNamesTypeProp;
containerClassName?: ClassType;
inputClassName?: ClassType;
toggleClassName?: ClassType;
toggleIcon?: (open: boolean) => React.ReactNode;
inputId?: string;
inputName?: string;
Expand Down