gbs-add-block 1.0.7 → 1.0.8

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 (v1.0.7)
1
+ # GBS Building Blocks 2.0 (v1.0.8)
2
2
 
3
3
  Latest and upgraded version of GBS building blocks with headless UI and removed dependencies.
4
4
 
@@ -6,7 +6,7 @@ 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 1.0.7)
9
+ ## What's New 🎉 (Ver 1.0.8)
10
10
 
11
11
  - Uploader Enhancement
12
12
  - Select Bug Fix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gbs-add-block",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "React Component Library",
5
5
  "type": "module",
6
6
  "files": [
@@ -12,6 +12,7 @@ import React, {
12
12
  useEffect,
13
13
  useImperativeHandle,
14
14
  useRef,
15
+ useState,
15
16
  } from "react";
16
17
  import { createPortal } from "react-dom";
17
18
  import Icon from "../icon/Icon";
@@ -22,13 +23,51 @@ import { iconClass, popUp, primary } from "../globalStyle";
22
23
  import {
23
24
  useSelectState,
24
25
  useSelectData,
26
+ useClickOutside,
25
27
  applyScrollbarStyles,
26
28
  useKeyboardNavigation,
27
- usePortalPopup,
28
- getPortalStyles,
29
- getAnimationClasses,
30
29
  } from "@grampro/headless-helpers";
31
30
 
31
+ // Portal Dropdown Component
32
+ const PortalDropdown = ({ targetRef, children, isVisible }: any) => {
33
+ const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });
34
+
35
+ useEffect(() => {
36
+ if (isVisible && targetRef.current) {
37
+ const rect = targetRef.current.getBoundingClientRect();
38
+ const scrollTop =
39
+ window.pageYOffset || document.documentElement.scrollTop;
40
+ const scrollLeft =
41
+ window.pageXOffset || document.documentElement.scrollLeft;
42
+
43
+ setPosition({
44
+ top: rect.bottom + scrollTop + 4,
45
+ left: rect.left + scrollLeft,
46
+ width: rect.width, // Match the width of the select button
47
+ });
48
+ }
49
+ }, [isVisible, targetRef]);
50
+
51
+ if (!isVisible) return null;
52
+
53
+ return createPortal(
54
+ <div
55
+ style={{
56
+ position: "absolute",
57
+ top: position.top,
58
+ left: position.left,
59
+ width: position.width,
60
+ zIndex: 1000,
61
+ }}
62
+ className={popUp["pop-up-style"]}
63
+ data-select-portal="true"
64
+ >
65
+ {children}
66
+ </div>,
67
+ document.body
68
+ );
69
+ };
70
+
32
71
  const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
33
72
  const {
34
73
  id = "",
@@ -70,17 +109,11 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
70
109
 
71
110
  const inputRef = useRef<HTMLInputElement>(null);
72
111
  const selectRef = useRef<HTMLDivElement>(null);
112
+ const buttonRef = useRef<HTMLButtonElement>(null); // Reference for portal positioning
73
113
 
74
- // Use the custom portal hooks
75
- const position = usePortalPopup({
76
- isOpen: showPopover,
77
- onClose: () => setShowPopover(false),
78
- triggerRef: selectRef,
79
- popupHeight: 250,
80
- offset: 4,
81
- minSpaceRequired: 50,
82
- portalSelector: '[data-select-portal="true"]',
83
- });
114
+ useClickOutside(selectRef as React.RefObject<HTMLElement>, () =>
115
+ setShowPopover(false)
116
+ );
84
117
 
85
118
  // Update the handleSelect to accept a SelectItem
86
119
  const handleSelect = useCallback(
@@ -130,15 +163,9 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
130
163
  selected: selectedItem,
131
164
  }));
132
165
 
133
- // Portal popup content with smart positioning
134
- const popupContent = showPopover && !disabled && (
135
- <div
136
- className={`${popUp["pop-up-style"]} ${getAnimationClasses(
137
- position.placement
138
- )}`}
139
- style={getPortalStyles(position, 250)}
140
- data-select-portal="true"
141
- >
166
+ // Portal dropdown content
167
+ const dropdownContent = (
168
+ <>
142
169
  {showSearch && (
143
170
  <div className={selectStyle["input-parent"]}>
144
171
  <Icon elements={search} svgClass={iconClass["grey-common"]} />
@@ -182,61 +209,61 @@ const Select = forwardRef<SelectHandle, SelectProps>((props, ref) => {
182
209
  ) : (
183
210
  <div className="text-sm text-center p-2">No Data Found</div>
184
211
  )}
185
- </div>
212
+ </>
186
213
  );
187
214
 
188
215
  return (
189
- <>
190
- <div
191
- className="relative w-full mt-2"
192
- ref={selectRef}
193
- id={id}
194
- onKeyDown={handleKeyDown}
195
- >
196
- <div className="w-full relative">
216
+ <div
217
+ className="relative w-full mt-2"
218
+ ref={selectRef}
219
+ id={id}
220
+ onKeyDown={handleKeyDown}
221
+ >
222
+ <div className="w-full relative">
223
+ <button
224
+ ref={buttonRef} // Add ref for portal positioning
225
+ className={`${error ? primary["error-border"] : "border"} ${
226
+ selectStyle["select-button"]
227
+ } ${disabled ? "opacity-50 cursor-not-allowed" : ""}`}
228
+ onClick={togglePopover}
229
+ type="button"
230
+ disabled={disabled}
231
+ >
232
+ {selectedDisplay || placeholder}
233
+ <Icon
234
+ elements={upDown}
235
+ svgClass={`${iconClass["grey-common"]} ${
236
+ disabled ? "opacity-50" : ""
237
+ }`}
238
+ />
239
+ </button>
240
+ {selectedDisplay && !disabled && (
197
241
  <button
198
- className={`${error ? primary["error-border"] : "border"} ${
199
- selectStyle["select-button"]
200
- } ${disabled ? "opacity-50 cursor-not-allowed" : ""}`}
201
- onClick={togglePopover}
202
- type="button"
203
- disabled={disabled}
242
+ className={selectStyle["selectedDisplay-Button"]}
243
+ onClick={handleClear}
204
244
  >
205
- {selectedDisplay || placeholder}
206
- <Icon
207
- elements={upDown}
208
- svgClass={`${iconClass["grey-common"]} ${
209
- disabled ? "opacity-50" : ""
210
- } ${
211
- showPopover && position.placement === "top" ? "rotate-180" : ""
212
- }`}
213
- />
245
+ <Icon elements={x} svgClass={iconClass["grey-common"]} />
214
246
  </button>
215
- {selectedDisplay && !disabled && (
216
- <button
217
- className={selectStyle["selectedDisplay-Button"]}
218
- onClick={handleClear}
219
- >
220
- <Icon elements={x} svgClass={iconClass["grey-common"]} />
221
- </button>
222
- )}
223
- {error && <p className={primary["error-primary"]}>{error}</p>}
224
- </div>
225
-
226
- <input
227
- type="hidden"
228
- name={name}
229
- value={selectedItem || ""}
230
- readOnly
231
- disabled={disabled}
232
- />
247
+ )}
248
+ {error && <p className={primary["error-primary"]}>{error}</p>}
233
249
  </div>
234
250
 
235
- {/* Render popup in portal to document.body */}
236
- {typeof document !== "undefined" &&
237
- popupContent &&
238
- createPortal(popupContent, document.body)}
239
- </>
251
+ <input
252
+ type="hidden"
253
+ name={name}
254
+ value={selectedItem || ""}
255
+ readOnly
256
+ disabled={disabled}
257
+ />
258
+
259
+ {/* Portal Dropdown - renders to document.body */}
260
+ <PortalDropdown
261
+ targetRef={buttonRef}
262
+ isVisible={showPopover && !disabled}
263
+ >
264
+ {dropdownContent}
265
+ </PortalDropdown>
266
+ </div>
240
267
  );
241
268
  });
242
269
 
@@ -5,7 +5,7 @@ export const primary = {
5
5
 
6
6
  export const popUp = {
7
7
  "pop-up-style":
8
- "overflow-y-auto px-2 border border-slate-200 rounded-lg scrollbar bg-white scrollbar h-auto dark:bg-black dark:text-white animate-fade-down animate-once animate-duration-200",
8
+ "w-full absolute overflow-y-auto border px-2 rounded-lg mt-[1px] scrollbar bg-white z-50 scrollbar h-auto dark:bg-black dark:text-white animate-fade-down animate-once animate-duration-200",
9
9
  };
10
10
 
11
11
  export const iconClass = {