gbs-add-block 0.0.48 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # GBS Building Blocks 2.0 (v0.0.48)
1
+ # GBS Building Blocks 2.0 (v0.0.49)
2
2
 
3
3
  Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
4
4
 
@@ -6,10 +6,10 @@ Latest and upgraded version of GBS building blocks with headless UI and removed
6
6
 
7
7
  For detailed documentation on usage and props, Please visit: [Building Block Documentation v2.0](https://blackmax-designs.gitbook.io/building-block-v2.0)
8
8
 
9
- ## What's New 🎉 (Ver 0.0.48)
9
+ ## What's New 🎉 (Ver 0.0.49)
10
10
 
11
+ - Update on form renderer
11
12
  - Refactored Code for Better Readability
12
- - Code Reusablity and hook update
13
13
 
14
14
  ## Authors
15
15
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gbs-add-block",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "description": "React Component Library",
5
5
  "files": [
6
6
  "index.js",
@@ -11,6 +11,8 @@ const CheckboxHandles = ({
11
11
  }: CheckboxHandlesProps) => {
12
12
  const [checked, setChecked] = useState<boolean>(!!item?.value);
13
13
 
14
+ // We Need this to set the value of the checkbox in the form
15
+ // if the value is not set in the form
14
16
  useEffect(() => {
15
17
  if (item?.name) {
16
18
  handleSelect(checked, item.name);
@@ -40,6 +42,7 @@ const CheckboxHandles = ({
40
42
  <input
41
43
  type="checkbox"
42
44
  checked={checked}
45
+ name={item?.name}
43
46
  onChange={(e) => {
44
47
  const newValue = e.target.checked;
45
48
  setChecked(newValue);
@@ -1,14 +1,6 @@
1
1
  import React from "react";
2
2
  import { DatePicker } from "../../datepicker";
3
- import { FormItem } from "../types";
4
-
5
- interface DatePickerHandlesProps {
6
- item?: FormItem;
7
- requirementError: string[];
8
- setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
9
- formRef?: React.RefObject<HTMLFormElement | null>;
10
- onChangeEvent?: (event: any) => void;
11
- }
3
+ import { DatePickerHandlesProps } from "../types";
12
4
 
13
5
  export default function DatePickerHandles({
14
6
  item,
@@ -1,81 +1,81 @@
1
- import React, { useEffect, useState } from "react";
2
- import { validateEmail, validatePhoneNumber } from "../helperFunctions";
1
+ import React, { useEffect, useState, useCallback } from "react";
2
+ import { validateInput } from "../helperFunctions";
3
3
  import { Input } from "../../input";
4
- import { FieldValue, FormContext, FormItem } from "../types";
4
+ import { InputHandlesProps } from "../types";
5
5
  import { evaluateExpression } from "@grampro/headless-helpers";
6
6
  import { twMerge } from "tailwind-merge";
7
7
 
8
- interface InputHandlesProps {
9
- item?: FormItem;
10
- requirementError: string[];
11
- setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
12
- onChangeEvent?: (event: any) => void;
13
- formRef: React.RefObject<HTMLFormElement | null>;
14
- context: FormContext;
15
- updateContext: (
16
- componentName: string,
17
- fieldName: string,
18
- value: FieldValue
19
- ) => void;
20
- }
21
-
22
- const InputHandles = ({
8
+ const InputHandles: React.FC<InputHandlesProps> = ({
23
9
  item,
24
10
  requirementError,
25
11
  setRequirementError,
26
12
  onChangeEvent,
27
13
  context,
28
14
  updateContext,
29
- }: InputHandlesProps) => {
15
+ }) => {
30
16
  const [inputError, setInputError] = useState<string | null>(null);
31
17
  const [isDisabled, setIsDisabled] = useState<boolean>(false);
32
18
  const [isRequired, setIsRequired] = useState<boolean>(false);
33
19
 
34
- // Initialize context with default values
20
+ // Evaluate expression with memoization
21
+ const evaluateCondition = useCallback(
22
+ (expression: string | boolean | undefined): boolean => {
23
+ if (typeof expression === "string") {
24
+ return evaluateExpression(expression, context);
25
+ }
26
+ return !!expression;
27
+ },
28
+ [context]
29
+ );
30
+
31
+ // Initialize context and handle dynamic states
35
32
  useEffect(() => {
36
33
  if (item?.name && item?.value !== undefined) {
37
34
  updateContext("input", item.name, item.value);
38
35
  }
39
- }, [item?.name, item?.value, updateContext]);
40
36
 
41
- // Handle dynamic disabled/required states expressions
42
- useEffect(() => {
43
- if (typeof item?.disabled === "string") {
44
- setIsDisabled(evaluateExpression(item.disabled, context));
45
- } else if (typeof item?.disabled === "boolean") {
46
- setIsDisabled(item.disabled);
47
- }
37
+ const disabled = evaluateCondition(item?.disabled);
38
+ setIsDisabled(disabled);
48
39
 
49
- if (typeof item?.required === "string") {
50
- setIsRequired(evaluateExpression(item.required, context));
51
- } else if (typeof item?.required === "boolean") {
52
- setIsRequired(item.required);
53
- }
54
- }, [item, context]);
40
+ // Only set required if not disabled
41
+ const required = disabled ? false : evaluateCondition(item?.required);
42
+ setIsRequired(required);
43
+ }, [item, context, evaluateCondition, updateContext]);
55
44
 
56
- const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
57
- const { value } = event.target;
45
+ const handleChange = useCallback(
46
+ (event: React.ChangeEvent<HTMLInputElement>) => {
47
+ const { value } = event.target;
58
48
 
59
- if (item?.name) {
60
- updateContext("input", item.name, value);
49
+ if (item?.name) {
50
+ updateContext("input", item.name, value);
51
+ setRequirementError?.((prev) =>
52
+ prev.filter((error) => error !== item.name)
53
+ );
54
+ }
61
55
 
62
- setRequirementError?.((prevErrors) =>
63
- prevErrors.filter((error) => error !== item.name)
64
- );
65
- }
56
+ const validationError = validateInput(value, item?.type);
57
+ setInputError(validationError);
66
58
 
67
- // Validation based on input type
68
- if (item?.type === "email" && !validateEmail(value)) {
69
- setInputError("Invalid email format");
70
- } else if (item?.type === "tel" && !validatePhoneNumber(value)) {
71
- setInputError("Invalid phone number. Must be 10 digits.");
72
- } else {
73
- setInputError(null);
74
- }
59
+ onChangeEvent?.(event);
60
+ },
61
+ [
62
+ item?.name,
63
+ item?.type,
64
+ updateContext,
65
+ setRequirementError,
66
+ onChangeEvent,
67
+ validateInput,
68
+ ]
69
+ );
75
70
 
76
- // Trigger onChange event
77
- onChangeEvent?.(event);
78
- };
71
+ // Merge input classes
72
+ const inputClassName = twMerge(
73
+ "border rounded-md px-4 py-[6px] w-full text-black",
74
+ inputError || (item?.name && requirementError.includes(item?.name))
75
+ ? "border-red-500"
76
+ : "border-gray-300",
77
+ item?.stepProperty?.customClass?.inputClass
78
+ );
79
79
 
80
80
  return (
81
81
  <div className="w-full">
@@ -88,22 +88,15 @@ const InputHandles = ({
88
88
  <Input
89
89
  type={item?.type}
90
90
  name={item?.name}
91
- placeholder={item?.placeholder || ""}
91
+ placeholder={item?.placeholder ?? ""}
92
92
  onChange={handleChange}
93
- className={twMerge(
94
- `border rounded-md px-4 py-[6px] w-full text-black ${
95
- inputError || (item?.name && requirementError.includes(item?.name))
96
- ? "border-red-500"
97
- : "border-gray-300"
98
- }`,
99
- item?.stepProperty?.customClass?.inputClass
100
- )}
93
+ className={inputClassName}
101
94
  defaultValue={item?.value ?? ""}
102
95
  disabled={isDisabled}
103
96
  required={isRequired}
104
97
  />
105
98
  {item?.name && requirementError.includes(item.name) && (
106
- <p className="text-red-500 text-xs">{`${item?.name} is required`}</p>
99
+ <p className="text-red-500 text-xs">{`${item.name} is required`}</p>
107
100
  )}
108
101
  {inputError && <p className="text-red-500 text-xs">{inputError}</p>}
109
102
  </div>
@@ -1,14 +1,7 @@
1
- import React from "react";
2
- import { FormItem } from "../types";
1
+ import React, { useCallback, useEffect, useState } from "react";
2
+ import { MultiSelectHandlesProps } from "../types";
3
3
  import { MultiSelect } from "../../multiselect";
4
-
5
- interface MultiSelectHandlesProps {
6
- item?: FormItem;
7
- requirementError: string[];
8
- setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
9
- formRef?: React.RefObject<HTMLFormElement | null>;
10
- onChangeEvent?: (event: any) => void;
11
- }
4
+ import { evaluateExpression } from "@grampro/headless-helpers";
12
5
 
13
6
  export default function MultiHandles({
14
7
  item,
@@ -16,7 +9,39 @@ export default function MultiHandles({
16
9
  setRequirementError,
17
10
  formRef,
18
11
  onChangeEvent,
12
+ context,
13
+ updateContext,
19
14
  }: MultiSelectHandlesProps) {
15
+ const [isDisabled, setIsDisabled] = useState<boolean>(false);
16
+ const [isRequired, setIsRequired] = useState<boolean>(false);
17
+
18
+ // Evaluate expression with memoization
19
+ const evaluateCondition = useCallback(
20
+ (expression: string | boolean | undefined): boolean => {
21
+ if (typeof expression === "string") {
22
+ return evaluateExpression(expression, context);
23
+ }
24
+ return !!expression;
25
+ },
26
+ [context]
27
+ );
28
+
29
+ // Initialize context and handle dynamic states
30
+ useEffect(() => {
31
+ if (item?.name && item?.value !== undefined) {
32
+ updateContext("select", item.name, item.value);
33
+ }
34
+
35
+ const disabled = evaluateCondition(item?.disabled);
36
+ console.log("disabled", disabled);
37
+
38
+ setIsDisabled(disabled);
39
+
40
+ // Only set required if not disabled
41
+ const required = disabled ? false : evaluateCondition(item?.required);
42
+ setIsRequired(required);
43
+ }, [item, context, evaluateCondition, updateContext]);
44
+
20
45
  const handleSelect = (value: string[], key: string) => {
21
46
  if (formRef && formRef.current) {
22
47
  const hiddenInput = formRef.current.querySelector(
@@ -42,7 +67,7 @@ export default function MultiHandles({
42
67
  {item?.label && (
43
68
  <label htmlFor={item.name} className="font-medium text-sm">
44
69
  {item.label}
45
- {item.required && <span className="text-red-500">*</span>}
70
+ {isRequired && <span className="text-red-500">*</span>}
46
71
  </label>
47
72
  )}
48
73
  <MultiSelect
@@ -62,6 +87,7 @@ export default function MultiHandles({
62
87
  ? `${item.name} is required`
63
88
  : undefined
64
89
  }
90
+ disabled={isDisabled}
65
91
  />
66
92
  </div>
67
93
  );
@@ -1,24 +1,7 @@
1
- import React, { useState } from "react";
1
+ import React, { useCallback, useEffect, useState } from "react";
2
2
  import { Select } from "../../select";
3
-
4
- interface Option {
5
- value: string;
6
- label: string;
7
- }
8
-
9
- interface SelectHandlesProps {
10
- item?: {
11
- name?: string;
12
- label?: string;
13
- options?: Option[];
14
- value?: string;
15
- required?: boolean;
16
- };
17
- requirementError: string[];
18
- setRequirementError: React.Dispatch<React.SetStateAction<string[]>>;
19
- formRef: React.RefObject<HTMLFormElement | null>;
20
- onChangeEvent?: (event: any) => void;
21
- }
3
+ import { Option, SelectHandlesProps } from "../types";
4
+ import { evaluateExpression } from "@grampro/headless-helpers";
22
5
 
23
6
  export default function SelectHandles({
24
7
  item,
@@ -26,9 +9,41 @@ export default function SelectHandles({
26
9
  setRequirementError,
27
10
  formRef,
28
11
  onChangeEvent,
12
+ context,
13
+ updateContext,
29
14
  }: SelectHandlesProps) {
30
15
  const [options] = useState<Option[]>(item?.options || []);
16
+ const [isDisabled, setIsDisabled] = useState<boolean>(false);
17
+ const [isRequired, setIsRequired] = useState<boolean>(false);
18
+
19
+ // Evaluate expression with memoization
20
+ const evaluateCondition = useCallback(
21
+ (expression: string | boolean | undefined): boolean => {
22
+ if (typeof expression === "string") {
23
+ return evaluateExpression(expression, context);
24
+ }
25
+ return !!expression;
26
+ },
27
+ [context]
28
+ );
29
+
30
+ // Initialize context and handle dynamic states
31
+ useEffect(() => {
32
+ if (item?.name && item?.value !== undefined) {
33
+ updateContext("select", item.name, item.value);
34
+ }
35
+
36
+ const disabled = evaluateCondition(item?.disabled);
37
+ console.log("disabled", disabled);
38
+
39
+ setIsDisabled(disabled);
40
+
41
+ // Only set required if not disabled
42
+ const required = disabled ? false : evaluateCondition(item?.required);
43
+ setIsRequired(required);
44
+ }, [item, context, evaluateCondition, updateContext]);
31
45
 
46
+ // Handle select change event
32
47
  const handleSelect = (value: string | undefined, key: string) => {
33
48
  if (!formRef?.current) return;
34
49
 
@@ -55,7 +70,7 @@ export default function SelectHandles({
55
70
  {item?.label && (
56
71
  <label htmlFor={item.name} className="font-medium text-sm">
57
72
  {item.label}
58
- {item.required && <span className="text-red-500">*</span>}
73
+ {isRequired && <span className="text-red-500">*</span>}
59
74
  </label>
60
75
  )}
61
76
  <Select
@@ -74,6 +89,7 @@ export default function SelectHandles({
74
89
  ? `${item.name} is required`
75
90
  : undefined
76
91
  }
92
+ disabled={isDisabled}
77
93
  />
78
94
  </div>
79
95
  );
@@ -20,3 +20,18 @@ export const formDataToObject = (formData: FormData) => {
20
20
  });
21
21
  return obj;
22
22
  };
23
+
24
+ export const validateInput = (value: string, type?: string): string | null => {
25
+ if (!value) return null;
26
+
27
+ switch (type) {
28
+ case "email":
29
+ return validateEmail(value) ? null : "Invalid email format";
30
+ case "tel":
31
+ return validatePhoneNumber(value)
32
+ ? null
33
+ : "Invalid phone number. Must be 10 digits.";
34
+ default:
35
+ return null;
36
+ }
37
+ };
@@ -5,7 +5,7 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import React, { useRef, useState } from "react";
8
+ import React, { useEffect, useRef, useState } from "react";
9
9
  import { useFormContext } from "@grampro/headless-helpers";
10
10
  import { FormElement, FormItem, FormRendererProps } from "./types";
11
11
  import InputHandles from "./componentHandles/InputHandles";
@@ -73,17 +73,13 @@ const FormRenderer = ({
73
73
  return (
74
74
  <SelectHandles
75
75
  key={index}
76
- item={{
77
- name: item.name,
78
- label: item.label,
79
- options: item.options,
80
- value: item.value,
81
- required: Boolean(item.required),
82
- }}
76
+ item={item}
83
77
  requirementError={requirementError}
84
78
  setRequirementError={setRequirementError}
85
79
  formRef={formRef}
86
80
  onChangeEvent={item.onChangeEvent}
81
+ context={context}
82
+ updateContext={updateContext}
87
83
  />
88
84
  );
89
85
 
@@ -96,6 +92,8 @@ const FormRenderer = ({
96
92
  setRequirementError={setRequirementError}
97
93
  formRef={formRef}
98
94
  onChangeEvent={item.onChangeEvent}
95
+ context={context}
96
+ updateContext={updateContext}
99
97
  />
100
98
  );
101
99
 
@@ -131,7 +129,7 @@ const FormRenderer = ({
131
129
  <div key={index} className="w-full mt-1">
132
130
  <button
133
131
  type={item.button_type}
134
- className="w-full bg-black text-white py-2 rounded-xl hover:bg-gray-800 dark:hover:bg-gray-300 dark:bg-white dark:text-black"
132
+ className="w-full bg-black text-white py-2 rounded-xl hover:bg-gray-800"
135
133
  >
136
134
  {item.value}
137
135
  </button>
@@ -1,3 +1,7 @@
1
+ export type Option = {
2
+ value: string;
3
+ label: string;
4
+ };
1
5
  export interface FormElement extends HTMLFormElement {
2
6
  [key: string]: any;
3
7
  }
@@ -26,39 +30,15 @@ export type FormItem = {
26
30
  };
27
31
  };
28
32
 
29
- interface DependencyConfig {
30
- source: string;
31
- parent?: string;
32
- dataStructure: any;
33
- }
34
-
35
33
  export type FormRendererProps = {
36
34
  onSubmit?: (formData: FormData) => void;
37
35
  sourceData?: FormItem[] | undefined;
38
36
  formFormationClass?: string;
39
37
  formParentClass?: string;
40
- dependencyConfig?: Record<string, DependencyConfig>;
41
- };
42
-
43
- export type SelectHandlesProps = {
44
- item?: FormItem;
45
- requirementError: string[];
46
- setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
47
- formRef?: React.RefObject<HTMLFormElement | null>;
48
- dependencyMap?: Record<
49
- string,
50
- {
51
- source: string;
52
- parent?: string;
53
- dataStructure: any;
54
- }
55
- >;
56
38
  };
57
39
 
58
- export type Option = {
59
- value: string;
60
- label: string;
61
- };
40
+ // Handler Props Starts here
41
+ export type FieldValue = string | boolean | number | null;
62
42
 
63
43
  export type CheckboxHandlesProps = {
64
44
  item?: FormItem;
@@ -77,10 +57,59 @@ export type CheckboxHandlesProps = {
77
57
  ) => void;
78
58
  };
79
59
 
80
- export type FieldValue = string | boolean | number | null;
81
-
82
60
  export interface FormContext {
83
61
  [componentName: string]: {
84
62
  [fieldName: string]: FieldValue;
85
63
  };
86
64
  }
65
+
66
+ export type InputHandlesProps = {
67
+ item?: FormItem;
68
+ requirementError: string[];
69
+ setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
70
+ onChangeEvent?: (event: React.ChangeEvent<HTMLInputElement>) => void;
71
+ formRef: React.RefObject<HTMLFormElement | null>;
72
+ context: FormContext;
73
+ updateContext: (
74
+ componentName: string,
75
+ fieldName: string,
76
+ value: FieldValue
77
+ ) => void;
78
+ };
79
+
80
+ export type DatePickerHandlesProps = {
81
+ item?: FormItem;
82
+ requirementError: string[];
83
+ setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
84
+ formRef?: React.RefObject<HTMLFormElement | null>;
85
+ onChangeEvent?: (event: any) => void;
86
+ };
87
+
88
+ export type SelectHandlesProps = {
89
+ item?: FormItem;
90
+ requirementError: string[];
91
+ setRequirementError: React.Dispatch<React.SetStateAction<string[]>>;
92
+ formRef: React.RefObject<HTMLFormElement | null>;
93
+ onChangeEvent?: (event: any) => void;
94
+ context: FormContext;
95
+ updateContext: (
96
+ componentName: string,
97
+ fieldName: string,
98
+ value: FieldValue
99
+ ) => void;
100
+ };
101
+
102
+ export type MultiSelectHandlesProps = {
103
+ item?: FormItem;
104
+ requirementError: string[];
105
+ setRequirementError?: React.Dispatch<React.SetStateAction<string[]>>;
106
+ formRef?: React.RefObject<HTMLFormElement | null>;
107
+ onChangeEvent?: (event: any) => void;
108
+ context: FormContext;
109
+ updateContext: (
110
+ componentName: string,
111
+ fieldName: string,
112
+ value: FieldValue
113
+ ) => void;
114
+ };
115
+ // Handler Props Ends here
@@ -17,6 +17,7 @@ import type { MultiSelectHandle, MultiSelectProps } from "./types";
17
17
  import {
18
18
  useMultiSelectState,
19
19
  useClickOutside,
20
+ applyScrollbarStyles,
20
21
  } from "@grampro/headless-helpers";
21
22
  import Icon from "../icon/Icon";
22
23
  import { check, search, upDown, x } from "../icon/iconPaths";
@@ -34,8 +35,11 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
34
35
  selectedItems = [],
35
36
  name,
36
37
  error,
38
+ disabled = false,
37
39
  } = props;
38
40
 
41
+ applyScrollbarStyles();
42
+
39
43
  const inputRef = useRef<HTMLInputElement>(null);
40
44
  const selectRef = useRef<HTMLDivElement>(null);
41
45
 
@@ -78,6 +82,12 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
78
82
  return display;
79
83
  }, [selected, workingDataSource, placeholder, truncate]);
80
84
 
85
+ const handleClear = () => {
86
+ if (disabled) return;
87
+ clearSelected();
88
+ if (onSelect) onSelect([]);
89
+ };
90
+
81
91
  useImperativeHandle(
82
92
  ref,
83
93
  () => ({
@@ -109,8 +119,11 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
109
119
  >
110
120
  <button
111
121
  onClick={togglePopover}
112
- className="flex-grow text-sm text-left font-medium"
122
+ className={`flex-grow text-sm text-left font-medium ${
123
+ disabled ? "opacity-50 cursor-not-allowed" : ""
124
+ }`}
113
125
  type="button"
126
+ disabled={disabled}
114
127
  >
115
128
  {getSelectedDisplay()}
116
129
  </button>
@@ -118,14 +131,19 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
118
131
  {selected.length > 0 && (
119
132
  <button
120
133
  className="flex items-center px-2"
121
- onClick={clearSelected}
134
+ onClick={handleClear}
122
135
  type="button"
123
136
  >
124
137
  <Icon elements={x} svgClass={iconClass["grey-common"]} />
125
138
  </button>
126
139
  )}
127
140
  <button onClick={togglePopover} type="button">
128
- <Icon elements={upDown} svgClass={iconClass["grey-common"]} />
141
+ <Icon
142
+ elements={upDown}
143
+ svgClass={`${iconClass["grey-common"]} ${
144
+ disabled ? "opacity-50" : ""
145
+ }`}
146
+ />
129
147
  </button>
130
148
  </div>
131
149
  </div>
@@ -138,7 +156,7 @@ const MultiSelect = forwardRef<MultiSelectHandle, MultiSelectProps>(
138
156
  readOnly
139
157
  />
140
158
 
141
- {showPopover && (
159
+ {showPopover && !disabled && (
142
160
  <div className={popUp["pop-up-style"]}>
143
161
  {showSearch && (
144
162
  <div className="flex p-2 gap-1 items-center sticky top-0 bg-white border-b dark:bg-black">
@@ -8,11 +8,12 @@ export type MultiSelectProps = {
8
8
  items?: ItemsProps[] | string;
9
9
  lazy?: boolean;
10
10
  showSearch?: boolean;
11
- onSelect?: (selectedItem: string[]) => void;
11
+ onSelect?: (selectedItem: string[]) => void | [];
12
12
  truncate?: boolean;
13
13
  selectedItems?: string[];
14
14
  name?: string;
15
15
  error?: string;
16
+ disabled?: boolean;
16
17
  };
17
18
 
18
19
  export type MultiSelectHandle = {
@@ -22,6 +22,7 @@ import {
22
22
  useSelectState,
23
23
  useSelectData,
24
24
  useClickOutside,
25
+ applyScrollbarStyles,
25
26
  } from "@grampro/headless-helpers";
26
27
 
27
28
  const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
@@ -36,8 +37,11 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
36
37
  selectedItem: initialSelectedItem,
37
38
  error = undefined,
38
39
  onFiltering,
40
+ disabled = false,
39
41
  } = props;
40
42
 
43
+ applyScrollbarStyles();
44
+
41
45
  const {
42
46
  showPopover,
43
47
  setShowPopover,
@@ -90,6 +94,7 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
90
94
  );
91
95
 
92
96
  const handleClear = () => {
97
+ if (disabled) return;
93
98
  clearSelected();
94
99
  if (onSelect) onSelect(undefined);
95
100
  };
@@ -110,14 +115,20 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
110
115
  <button
111
116
  className={`${error ? primary["error-border"] : "border"} ${
112
117
  selectStyle["select-button"]
113
- }`}
118
+ } ${disabled ? "opacity-50 cursor-not-allowed" : ""}`}
114
119
  onClick={togglePopover}
115
120
  type="button"
121
+ disabled={disabled}
116
122
  >
117
123
  {selectedDisplay || placeholder}
118
- <Icon elements={upDown} svgClass={iconClass["grey-common"]} />
124
+ <Icon
125
+ elements={upDown}
126
+ svgClass={`${iconClass["grey-common"]} ${
127
+ disabled ? "opacity-50" : ""
128
+ }`}
129
+ />
119
130
  </button>
120
- {selectedDisplay && (
131
+ {selectedDisplay && !disabled && (
121
132
  <button
122
133
  className={selectStyle["selectedDisplay-Button"]}
123
134
  onClick={handleClear}
@@ -130,7 +141,7 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
130
141
 
131
142
  <input type="hidden" name={name} value={selectedItem || ""} readOnly />
132
143
 
133
- {showPopover && (
144
+ {showPopover && !disabled && (
134
145
  <div className={popUp["pop-up-style"]}>
135
146
  {showSearch && (
136
147
  <div className={selectStyle["input-parent"]}>
@@ -141,7 +152,7 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
141
152
  name="search"
142
153
  id="search"
143
154
  placeholder="Search a value"
144
- className="w-full outline-none dark:bg-black"
155
+ className="w-full outline-none"
145
156
  ref={inputRef}
146
157
  value={searchTerm}
147
158
  onChange={(e) => {
@@ -1,10 +1,9 @@
1
1
  export const selectStyle = {
2
2
  "select-button":
3
- "flex items-center px-4 py-2 w-full justify-between rounded-lg font-medium text-sm dark:bg-black dark:border-white dark:text-white",
3
+ "flex items-center px-4 py-2 w-full justify-between rounded-lg font-medium text-sm",
4
4
  "filter-button":
5
5
  "flex items-center w-full px-2 py-1 text-left hover:bg-blue-100 gap-2 rounded-lg mt-1 text-sm dark:hover:bg-blue-600",
6
- "input-parent":
7
- "flex p-2 gap-1 items-center sticky top-0 bg-white border-b dark:bg-black",
6
+ "input-parent": "flex p-2 gap-1 items-center sticky top-0 bg-white border-b",
8
7
  "selectedDisplay-Button":
9
8
  "absolute right-8 top-0 h-full flex items-center px-2 z-20",
10
9
  };
@@ -14,6 +14,7 @@ export type SelectProps = {
14
14
  onSelect?: (selectedItem: string | undefined) => void;
15
15
  selectedItem?: string;
16
16
  onFiltering?: (searchTerm: string) => void;
17
+ disabled?: boolean;
17
18
  };
18
19
 
19
20
  export type SelectHandle = {