Skip to content

Commit 6981b4f

Browse files
authored
Adds new component NoTableEntriesYet (#5)
* Adds new component * Changes default text & height * Adds type files for components
1 parent 0bbfc2d commit 6981b4f

File tree

6 files changed

+129
-42
lines changed

6 files changed

+129
-42
lines changed

components/InfoButton.tsx

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,10 @@ import BaseModal from "../../../src/components/Common/Modal";
66
import { InformationCircleIcon } from "@heroicons/react/20/solid";
77
import useOnClickOutside from "@/submodules/react-components/hooks/useHooks/useOnClickOutside";
88
import { Transition } from "@headlessui/react";
9+
import { INFO_BUTTON_DEFAULT_VALUES, InfoButtonConfig, InfoButtonProps } from "../types/infoButton";
910

10-
type InfoButtonProps = {
11-
content: string | JSX.Element;
12-
infoButtonSize?: "xs" | "sm" | "md" | "lg";
13-
infoButtonColorClass?: string;
14-
access?: "hover" | "click";
15-
display?: "absoluteDiv" | "modal"
16-
divPosition?: "top" | "bottom" | "left" | "right"; // only for absoluteDiv relevant
17-
divZIndexClass?: string;
18-
}
19-
20-
type InfoConfig = {
21-
size: number;
22-
cursorClass: string;
23-
positionClass: string;
24-
hideInfo: () => void;
25-
showInfo: () => void;
26-
}
2711

28-
function generateAndCheckConfig(props: InfoButtonProps, setOpen: Dispatch<SetStateAction<boolean>>): InfoConfig {
12+
function generateAndCheckConfig(props: InfoButtonProps, setOpen: Dispatch<SetStateAction<boolean>>): InfoButtonConfig {
2913
if (props.access == "hover" && props.display == "modal") console.warn("InfoButton - Hover access and modal display are not recommended")
3014
const config: any = {};
3115
switch (props.infoButtonSize) {
@@ -53,17 +37,10 @@ function generateAndCheckConfig(props: InfoButtonProps, setOpen: Dispatch<SetSta
5337
return config;
5438
}
5539

56-
const DEFAULT_VALUES = {
57-
size: "sm",
58-
access: "hover",
59-
display: "absoluteDiv",
60-
divPosition: "top",
61-
divZIndexClass: "z-10"
62-
}
6340

6441
export function InfoButton(_props: InfoButtonProps) {
65-
const [props] = useDefaults<InfoButtonProps>(_props, DEFAULT_VALUES);
66-
const [config, setConfig] = useState<InfoConfig>(null);
42+
const [props] = useDefaults<InfoButtonProps>(_props, INFO_BUTTON_DEFAULT_VALUES);
43+
const [config, setConfig] = useState<InfoButtonConfig>(null);
6744
const [open, setOpen] = useState(false);
6845

6946
useEffect(() => setConfig(generateAndCheckConfig(props, setOpen)), [props.infoButtonSize, props.access, props.display, props.divPosition]);

components/LocalStorageDropdown.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,8 @@ import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useSta
44
import { useDefaults, useDefaultsByRef } from "../hooks/useDefaults";
55
import Dropdown from "./Dropdown";
66
import { CompareOptions, inStringList } from "@/submodules/javascript-functions/validations";
7+
import { LOCAL_STORAGE_DROPDOWN_DEFAULTS, LocalStorageDropdownProps } from "../types/localStorageDropdown";
78

8-
type LocalStorageDropdownProps = {
9-
buttonName: string;
10-
storageKey: string;
11-
storageGroupKey?: string; //defaults to localDropdown
12-
onOptionSelected?: (option: string) => void;
13-
searchDefaultValue?: string;
14-
excludedFromStorage?: { values: string[]; compareOptions?: CompareOptions[] }; // if the value is in this list it will not be added to the storage //setting this to null will assume all values are valid
15-
}
16-
17-
const DEFAULTS = {
18-
storageGroupKey: "localDropdown",
19-
excludedFromStorage: { values: ["select", "enter"], compareOptions: [CompareOptions.IGNORE_CASE, CompareOptions.TRIM, CompareOptions.STARTS_WITH] }
20-
}
219

2210
function readFromLocalStorage(group: string, key: string): string[] {
2311
const itemGroupString = localStorage.getItem(group);
@@ -68,8 +56,8 @@ function removeFromLocalStorage(group: string, key: string, rValue: string): str
6856
export const LocalStorageDropdown = forwardRef((_props: LocalStorageDropdownProps, ref) => {
6957

7058

71-
const [props] = useDefaults<LocalStorageDropdownProps>(_props, DEFAULTS);
72-
const [propRef] = useDefaultsByRef<LocalStorageDropdownProps>(_props, DEFAULTS); // for unmounting
59+
const [props] = useDefaults<LocalStorageDropdownProps>(_props, LOCAL_STORAGE_DROPDOWN_DEFAULTS);
60+
const [propRef] = useDefaultsByRef<LocalStorageDropdownProps>(_props, LOCAL_STORAGE_DROPDOWN_DEFAULTS); // for unmounting
7361
const [options, setOptions] = useState<string[]>(); // initially built with useLocalStorage however as state setters don't work during unmount changed to a common state
7462
const [inputText, setInputText] = useState(props.buttonName ?? ''); // holds the current option independent of input field or dropdown so it can be collected if necessary
7563
const inputTextRef = useRef<string>(); //ref is used to access data from a pointer which in turn can be access in the unmounting

components/NoTableEntriesYet.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { memo } from "react";
2+
import { useDefaults } from "../hooks/useDefaults";
3+
import { NO_TABLE_ENTRIES_YET_DEFAULTS, NoTableEntriesYetProps } from "../types/noTableEntriesYet";
4+
5+
6+
function GetNoTableEntriesYet(_props: NoTableEntriesYetProps) {
7+
const [props] = useDefaults<NoTableEntriesYetProps>(_props, NO_TABLE_ENTRIES_YET_DEFAULTS);
8+
9+
return <tr>
10+
<td colSpan={props.tableColumns}>
11+
<div className={`flex justify-center items-center w-full text-sm ${props.heightClass + " " + props.backgroundColorClass + " " + props.textColorClass + " " + props.marginBottomClass}`}>
12+
{props.text}
13+
</div>
14+
</td>
15+
</tr>
16+
17+
}
18+
19+
export const NoTableEntriesYet = memo(GetNoTableEntriesYet)

types/infoButton.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Options for the InfoButton component
3+
* @content {string | JSX.Element} - The content of the info button
4+
* @infoButtonSize {"xs" | "sm" | "md" | "lg", optional} - The size of the info icon used as button
5+
* @infoButtonColorClass {string, optional} - The color of the info icon used as button
6+
* @access {"hover" | "click", optional} - How to access the info content
7+
* @display {"absoluteDiv" | "modal"} - The display of the info button
8+
* @divPosition {"top" | "bottom" | "left" | "right", optional} - The position of the info div - only used if display is absoluteDiv
9+
* @divZIndexClass {string, optional} - The z-index of the info div - only used if display is absoluteDiv
10+
*/
11+
12+
export type InfoButtonProps = {
13+
content: string | JSX.Element;
14+
infoButtonSize?: "xs" | "sm" | "md" | "lg";
15+
infoButtonColorClass?: string;
16+
access?: "hover" | "click";
17+
display?: "absoluteDiv" | "modal"
18+
divPosition?: "top" | "bottom" | "left" | "right";
19+
divZIndexClass?: string;
20+
}
21+
22+
/**
23+
* Return type of the InfoButton helper function
24+
* @size {number} - The size of the info icon used as button
25+
* @cursorClass {string} - The cursor of the info icon used as button
26+
* @positionClass {string} - The position of the info div - only used if display is absoluteDiv
27+
* @hideInfo {function} - The function that will be called when the info div should be hidden
28+
* @showInfo {function} - The function that will be called when the info div should be shown
29+
*/
30+
31+
export type InfoButtonConfig = {
32+
size: number;
33+
cursorClass: string;
34+
positionClass: string;
35+
hideInfo: () => void;
36+
showInfo: () => void;
37+
}
38+
39+
40+
export const INFO_BUTTON_DEFAULT_VALUES = {
41+
size: "sm",
42+
access: "hover",
43+
display: "absoluteDiv",
44+
divPosition: "top",
45+
divZIndexClass: "z-10"
46+
}

types/localStorageDropdown.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
import { CompareOptions } from "@/submodules/javascript-functions/validations";
3+
4+
/**
5+
* Options for the LocalStorage Dropdown component
6+
* Note that a ref object can be linked to the component
7+
* @buttonName {string} - The name of the button
8+
* @storageKey {string} - The key inside the storage group
9+
* @storageGroupKey {string, optional} - The key of the local storage value (defaults to localDropdown)
10+
* @onOptionSelected {function, optional} - The function that will be called when an option is selected
11+
* @searchDefaultValue {string, optional} - The default value of the search bar (similar to buttonName)
12+
* @excludedFromStorage {object, optional} - Decided what values are exempt from being added to the storage - defaults to "starting with 'select' or 'enter'"
13+
*/
14+
15+
export type LocalStorageDropdownProps = {
16+
buttonName: string;
17+
storageKey: string;
18+
storageGroupKey?: string; //defaults to localDropdown
19+
onOptionSelected?: (option: string) => void;
20+
searchDefaultValue?: string;
21+
excludedFromStorage?: { values: string[]; compareOptions?: CompareOptions[] }; // if the value is in this list it will not be added to the storage //setting this to null will assume all values are valid
22+
}
23+
24+
25+
26+
export const LOCAL_STORAGE_DROPDOWN_DEFAULTS = {
27+
storageGroupKey: "localDropdown",
28+
excludedFromStorage: { values: ["select", "enter"], compareOptions: [CompareOptions.IGNORE_CASE, CompareOptions.TRIM, CompareOptions.STARTS_WITH] }
29+
}

types/noTableEntriesYet.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
/**
3+
* Options for the No table entries yet component
4+
* @tableColumns {number} - The number of columns in the table (so the text can be across the whole table)
5+
* @text {string, optional} - The text to be displayed
6+
* @heightClass {string, optional} - The height of the component
7+
* @backgroundColorClass {string, optional} - The background color of the component
8+
* @textColorClass {string, optional} - The text color of the component
9+
* @marginBottomClass {string, optional} - The margin bottom of the component
10+
*/
11+
12+
export type NoTableEntriesYetProps = {
13+
tableColumns: number;
14+
text?: string;
15+
heightClass?: string;
16+
backgroundColorClass?: string;
17+
textColorClass?: string;
18+
marginBottomClass?: string; // can be used to offset common table paddings, usually negative
19+
}
20+
21+
22+
export const NO_TABLE_ENTRIES_YET_DEFAULTS = {
23+
text: 'No data yet',
24+
heightClass: 'h-16',
25+
backgroundColorClass: 'bg-gray-50',
26+
textColorClass: 'text-gray-700',
27+
marginBottomClass: "",
28+
}

0 commit comments

Comments
 (0)