@idds/react 1.5.27 → 1.5.29

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/dist/index.es.js CHANGED
@@ -2318,10 +2318,11 @@ function Dropdown({
2318
2318
  dropdownClassName = "",
2319
2319
  dropdownStyle,
2320
2320
  disabled = false,
2321
- dropdownWidth = 160
2321
+ dropdownWidth
2322
2322
  }) {
2323
2323
  const [open, setOpen] = useState(false);
2324
- const [dropdownPosition, setDropdownPosition] = useState({ vertical: "bottom", horizontal: "right" });
2324
+ const [dropdownPosition, setDropdownPosition] = useState({ vertical: "bottom", horizontal: "left" });
2325
+ const [triggerWidth, setTriggerWidth] = useState(0);
2325
2326
  const containerRef = useRef(null);
2326
2327
  const [mounted, setMounted] = useState(false);
2327
2328
  useEffect(() => {
@@ -2344,26 +2345,13 @@ function Dropdown({
2344
2345
  if (disabled) return;
2345
2346
  if (containerRef.current) {
2346
2347
  const rect = containerRef.current.getBoundingClientRect();
2347
- const dropdownHeight = items.length * 40 + 16;
2348
+ setTriggerWidth(rect.width);
2349
+ const dropdownHeight = 200;
2348
2350
  const fitsBelow = rect.bottom + dropdownHeight <= window.innerHeight;
2349
2351
  const vertical = fitsBelow ? "bottom" : "top";
2350
- const fitsRight = rect.right + dropdownWidth <= window.innerWidth;
2351
- const horizontal = fitsRight ? "right" : "left";
2352
- const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
2353
- const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
2354
- let top = 0;
2355
- let left = 0;
2356
- if (vertical === "bottom") {
2357
- top = rect.bottom + scrollTop + 8;
2358
- } else {
2359
- top = rect.top + scrollTop - dropdownHeight - 8;
2360
- }
2361
- if (horizontal === "right") {
2362
- left = rect.left + scrollLeft;
2363
- } else {
2364
- left = rect.right + scrollLeft - dropdownWidth;
2365
- }
2366
- setDropdownPosition({ vertical, horizontal, top, left });
2352
+ const fitsRight = rect.left + (dropdownWidth ?? 160) <= window.innerWidth;
2353
+ const horizontal = fitsRight ? "left" : "right";
2354
+ setDropdownPosition({ vertical, horizontal });
2367
2355
  }
2368
2356
  setOpen((o) => !o);
2369
2357
  };
@@ -2379,40 +2367,66 @@ function Dropdown({
2379
2367
  `ina-dropdown__menu--align-${dropdownPosition.horizontal}`,
2380
2368
  dropdownClassName
2381
2369
  );
2382
- const menuContent = open && mounted ? /* @__PURE__ */ jsx(
2383
- "div",
2384
- {
2385
- className: menuClasses,
2386
- style: {
2387
- width: dropdownWidth,
2388
- position: "absolute",
2389
- top: dropdownPosition.top,
2390
- left: dropdownPosition.left,
2391
- ...dropdownStyle
2392
- },
2393
- role: "menu",
2394
- onMouseDown: (e) => e.stopPropagation(),
2395
- children: /* @__PURE__ */ jsx("ul", { className: "ina-dropdown__list", children: items.map((item, idx) => {
2396
- if (item && typeof item === "object" && "props" in item && item.props.className) {
2397
- return /* @__PURE__ */ jsx("li", {
2398
- role: "none",
2399
- // Clone element dengan className hasil clsx
2400
- // @ts-ignore
2401
- children: React.cloneElement(item, {
2370
+ const effectiveWidth = dropdownWidth ?? triggerWidth;
2371
+ const isStandardTrigger = typeof trigger === "string" || typeof trigger === "number";
2372
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: dropdownContainerClasses, children: [
2373
+ /* @__PURE__ */ jsx("div", { onClick: handleTriggerClick, className: triggerClasses, children: isStandardTrigger ? /* @__PURE__ */ jsxs(
2374
+ "div",
2375
+ {
2376
+ className: clsx(
2377
+ "ina-dropdown__trigger-button",
2378
+ open && "ina-dropdown__trigger-button--open"
2379
+ ),
2380
+ children: [
2381
+ /* @__PURE__ */ jsx("span", { className: "ina-dropdown__trigger-content", children: trigger }),
2382
+ /* @__PURE__ */ jsx(
2383
+ "svg",
2384
+ {
2385
+ className: "ina-dropdown__trigger-icon",
2386
+ width: "16",
2387
+ height: "16",
2388
+ viewBox: "0 0 16 16",
2389
+ fill: "none",
2390
+ xmlns: "http://www.w3.org/2000/svg",
2391
+ children: /* @__PURE__ */ jsx(
2392
+ "path",
2393
+ {
2394
+ d: "M4 6L8 10L12 6",
2395
+ stroke: "currentColor",
2396
+ strokeWidth: "1.5",
2397
+ strokeLinecap: "round",
2398
+ strokeLinejoin: "round"
2399
+ }
2400
+ )
2401
+ }
2402
+ )
2403
+ ]
2404
+ }
2405
+ ) : trigger }),
2406
+ open && /* @__PURE__ */ jsx(
2407
+ "div",
2408
+ {
2409
+ className: menuClasses,
2410
+ style: {
2411
+ width: effectiveWidth || void 0,
2412
+ minWidth: effectiveWidth ? void 0 : "160px",
2413
+ ...dropdownStyle
2414
+ },
2415
+ role: "menu",
2416
+ onMouseDown: (e) => e.stopPropagation(),
2417
+ children: /* @__PURE__ */ jsx("ul", { className: "ina-dropdown__list", children: items.map((item, idx) => {
2418
+ if (item && typeof item === "object" && "props" in item && item.props.className) {
2419
+ return /* @__PURE__ */ jsx("li", { role: "none", children: React.cloneElement(item, {
2402
2420
  className: clsx(
2403
2421
  "ina-dropdown__item",
2404
2422
  item.props.className
2405
2423
  )
2406
- })
2407
- }, idx);
2408
- }
2409
- return /* @__PURE__ */ jsx("li", { role: "none", children: /* @__PURE__ */ jsx("div", { className: "ina-dropdown__item", children: item }) }, idx);
2410
- }) })
2411
- }
2412
- ) : null;
2413
- return /* @__PURE__ */ jsxs(Fragment, { children: [
2414
- /* @__PURE__ */ jsx("div", { ref: containerRef, className: dropdownContainerClasses, children: /* @__PURE__ */ jsx("div", { onClick: handleTriggerClick, className: triggerClasses, children: trigger }) }),
2415
- mounted && createPortal(menuContent, document.body)
2424
+ }) }, idx);
2425
+ }
2426
+ return /* @__PURE__ */ jsx("li", { role: "none", children: /* @__PURE__ */ jsx("div", { className: "ina-dropdown__item", children: item }) }, idx);
2427
+ }) })
2428
+ }
2429
+ )
2416
2430
  ] });
2417
2431
  }
2418
2432
  const ALLOWED_MIME_TYPES = {
@@ -4230,7 +4244,7 @@ const COUNTRIES = [
4230
4244
  { code: "KR", name: "Korea, Republic of", dialCode: "+82" },
4231
4245
  { code: "KW", name: "Kuwait", dialCode: "+965" },
4232
4246
  { code: "KG", name: "Kyrgyzstan", dialCode: "+996" },
4233
- { code: "LA", name: "Lao People's Democratic Republic", dialCode: "+856" },
4247
+ { code: "LA", name: "Laos", dialCode: "+856" },
4234
4248
  { code: "LV", name: "Latvia", dialCode: "+371" },
4235
4249
  { code: "LB", name: "Lebanon", dialCode: "+961" },
4236
4250
  { code: "LS", name: "Lesotho", dialCode: "+266" },
@@ -5067,7 +5081,7 @@ function PhoneInput({
5067
5081
  value: countrySearch,
5068
5082
  onChange: (e) => setCountrySearch(e.target.value),
5069
5083
  type: "text",
5070
- placeholder: "Search countries...",
5084
+ placeholder: "Cari",
5071
5085
  className: "ina-phone-input__country-search-input"
5072
5086
  }
5073
5087
  ) }),
@@ -5091,7 +5105,12 @@ function PhoneInput({
5091
5105
  height: "18"
5092
5106
  }
5093
5107
  ),
5094
- /* @__PURE__ */ jsx("span", { className: "ina-phone-input__country-name", children: country.name }),
5108
+ /* @__PURE__ */ jsxs("span", { className: "ina-phone-input__country-name", children: [
5109
+ country.name,
5110
+ " (",
5111
+ country.code,
5112
+ ")"
5113
+ ] }),
5095
5114
  /* @__PURE__ */ jsx("span", { className: "ina-phone-input__country-dial-code", children: country.dialCode })
5096
5115
  ]
5097
5116
  },
@@ -5194,7 +5213,7 @@ function toCssSize(v) {
5194
5213
  if (v === void 0 || v === null) return void 0;
5195
5214
  return typeof v === "number" ? `${v}px` : v;
5196
5215
  }
5197
- function SelectDropdown({
5216
+ const SelectDropdown = ({
5198
5217
  options,
5199
5218
  selected,
5200
5219
  onSelect,
@@ -5227,8 +5246,9 @@ function SelectDropdown({
5227
5246
  searchable = true,
5228
5247
  onSelectedRawChange,
5229
5248
  label,
5230
- required
5231
- }) {
5249
+ required,
5250
+ selectionTitle
5251
+ }) => {
5232
5252
  const [isOpen, setIsOpen] = useState(false);
5233
5253
  const [internalSearchTerm, setInternalSearchTerm] = useState("");
5234
5254
  const containerRef = useRef(null);
@@ -5285,10 +5305,6 @@ function SelectDropdown({
5285
5305
  }
5286
5306
  };
5287
5307
  }, []);
5288
- const toggleOpen = () => {
5289
- if (disabled) return;
5290
- setIsOpen((prev) => !prev);
5291
- };
5292
5308
  const isArraySelected = multiple && Array.isArray(selected);
5293
5309
  const selectedArray = isArraySelected ? selected : [];
5294
5310
  const singleSelected = !multiple ? selected : null;
@@ -5472,19 +5488,47 @@ function SelectDropdown({
5472
5488
  const triggerClasses = clsx(
5473
5489
  "ina-select-dropdown__trigger",
5474
5490
  `ina-select-dropdown__trigger--size-${size}`,
5491
+ // Status classes
5492
+ // Note: You might want to add props for status (error, warning, etc) if needed
5475
5493
  disabled && "ina-select-dropdown__trigger--disabled",
5476
5494
  triggerClassName
5477
5495
  );
5478
- const triggerTextClasses = clsx(
5479
- "ina-select-dropdown__trigger-text",
5480
- disabled && "ina-select-dropdown__trigger-text--disabled",
5481
- triggerLabel === placeholder && !disabled && "ina-select-dropdown__trigger-text--placeholder",
5482
- triggerLabel !== placeholder && !disabled && "ina-select-dropdown__trigger-text--selected"
5483
- );
5484
5496
  const triggerIconClasses = clsx(
5485
5497
  "ina-select-dropdown__trigger-icon",
5486
5498
  disabled && "ina-select-dropdown__trigger-icon--disabled"
5487
5499
  );
5500
+ const getInputValue = () => {
5501
+ if (multiple) {
5502
+ return searchTerm;
5503
+ }
5504
+ if (isOpen) {
5505
+ return searchTerm;
5506
+ }
5507
+ if (singleSelected !== null && singleSelected !== void 0 && singleSelected !== "") {
5508
+ const label2 = getLabelForValue(singleSelected);
5509
+ return label2 || "";
5510
+ }
5511
+ return "";
5512
+ };
5513
+ const handleTriggerClick = () => {
5514
+ var _a;
5515
+ if (!isOpen && !disabled) {
5516
+ setIsOpen(true);
5517
+ }
5518
+ const input = (_a = containerRef.current) == null ? void 0 : _a.querySelector("input");
5519
+ if (input) {
5520
+ input.focus();
5521
+ }
5522
+ };
5523
+ const onInputChange = (e) => {
5524
+ if (!isOpen) setIsOpen(true);
5525
+ handleSearchChange(e);
5526
+ };
5527
+ const handleInputKeyDown = (e) => {
5528
+ if (e.key === "Enter") {
5529
+ e.preventDefault();
5530
+ }
5531
+ };
5488
5532
  return /* @__PURE__ */ jsxs(
5489
5533
  "div",
5490
5534
  {
@@ -5497,15 +5541,39 @@ function SelectDropdown({
5497
5541
  required && /* @__PURE__ */ jsx("span", { className: "ina-select-dropdown__required", children: "*" })
5498
5542
  ] }),
5499
5543
  /* @__PURE__ */ jsxs(
5500
- "button",
5544
+ "div",
5501
5545
  {
5502
- type: "button",
5503
- onClick: toggleOpen,
5504
- disabled,
5546
+ onClick: handleTriggerClick,
5505
5547
  className: triggerClasses,
5548
+ role: "combobox",
5549
+ "aria-expanded": isOpen,
5550
+ "aria-haspopup": "listbox",
5506
5551
  children: [
5507
5552
  prefixNode && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__trigger-prefix", children: prefixNode }),
5508
- /* @__PURE__ */ jsx("span", { className: triggerTextClasses, children: triggerLabel }),
5553
+ searchable && !disabled ? /* @__PURE__ */ jsx(
5554
+ "input",
5555
+ {
5556
+ type: "text",
5557
+ className: "ina-select-dropdown__trigger-input",
5558
+ placeholder: triggerLabel,
5559
+ value: getInputValue(),
5560
+ onChange: onInputChange,
5561
+ onKeyDown: handleInputKeyDown,
5562
+ disabled,
5563
+ "aria-autocomplete": "list"
5564
+ }
5565
+ ) : /* @__PURE__ */ jsx(
5566
+ "span",
5567
+ {
5568
+ className: clsx(
5569
+ "ina-select-dropdown__trigger-text",
5570
+ disabled && "ina-select-dropdown__trigger-text--disabled",
5571
+ triggerLabel === placeholder && !disabled && "ina-select-dropdown__trigger-text--placeholder",
5572
+ triggerLabel !== placeholder && !disabled && "ina-select-dropdown__trigger-text--selected"
5573
+ ),
5574
+ children: triggerLabel
5575
+ }
5576
+ ),
5509
5577
  isOpen ? /* @__PURE__ */ jsx(
5510
5578
  IconChevronUp,
5511
5579
  {
@@ -5527,26 +5595,11 @@ function SelectDropdown({
5527
5595
  {
5528
5596
  className: clsx("ina-select-dropdown__panel", panelClassName),
5529
5597
  style: {
5530
- width: toCssSize(panelWidth) ?? toCssSize(width),
5598
+ // width is now 100% via CSS, but we can override if panelWidth is provided
5599
+ width: panelWidth ? toCssSize(panelWidth) : void 0,
5531
5600
  maxHeight: toCssSize(panelHeight)
5532
- // ← tinggi popup dapat diatur
5533
5601
  },
5534
5602
  children: [
5535
- searchable && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__search", children: /* @__PURE__ */ jsx(
5536
- "input",
5537
- {
5538
- type: "text",
5539
- "aria-label": `Search ${placeholder}`,
5540
- value: searchTerm,
5541
- onChange: handleSearchChange,
5542
- placeholder: "Cari data",
5543
- disabled,
5544
- className: clsx(
5545
- "ina-select-dropdown__search-input",
5546
- disabled && "ina-select-dropdown__search-input--disabled"
5547
- )
5548
- }
5549
- ) }),
5550
5603
  showPreviewValue && renderSelectedPreviewContent() !== null && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__preview", children: renderSelectedPreviewContent() }),
5551
5604
  /* @__PURE__ */ jsxs(
5552
5605
  "div",
@@ -5554,6 +5607,7 @@ function SelectDropdown({
5554
5607
  ref: scrollContainerRef,
5555
5608
  className: "ina-select-dropdown__options",
5556
5609
  children: [
5610
+ selectionTitle && /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__selection-title", children: selectionTitle }),
5557
5611
  filteredOptions.map((option, index) => {
5558
5612
  const isSelected = multiple ? selectedArray.includes(option.value) : option.value === singleSelected;
5559
5613
  const labelContent = renderOptionLabel ? renderOptionLabel(option) : /* @__PURE__ */ jsx("span", { className: "ina-select-dropdown__option-label", children: option.label });
@@ -5589,8 +5643,11 @@ function SelectDropdown({
5589
5643
  }
5590
5644
  );
5591
5645
  }
5592
- const handleOptionClick = () => {
5593
- if (disabled) return;
5646
+ const handleOptionClick = (e) => {
5647
+ var _a;
5648
+ e.preventDefault();
5649
+ e.stopPropagation();
5650
+ if (disabled || option.disabled) return;
5594
5651
  if (multiple) {
5595
5652
  const prev = Array.isArray(selected) ? [...selected] : [];
5596
5653
  const newSelected = prev.includes(option.value) ? prev.filter((v) => v !== option.value) : [...prev, option.value];
@@ -5603,6 +5660,8 @@ function SelectDropdown({
5603
5660
  );
5604
5661
  }
5605
5662
  onSelect(newSelected);
5663
+ const input = (_a = containerRef.current) == null ? void 0 : _a.querySelector("input");
5664
+ if (input) input.focus();
5606
5665
  } else {
5607
5666
  if (isSelected) {
5608
5667
  selectedLabelsCacheRef.current.delete(option.value);
@@ -5628,12 +5687,12 @@ function SelectDropdown({
5628
5687
  {
5629
5688
  type: "button",
5630
5689
  onClick: handleOptionClick,
5631
- disabled,
5690
+ disabled: disabled || option.disabled,
5632
5691
  className: clsx(
5633
5692
  "ina-select-dropdown__option",
5634
5693
  !multiple && isSelected && "ina-select-dropdown__option--selected-single",
5635
5694
  multiple && isSelected && "ina-select-dropdown__option--selected-multiple",
5636
- disabled && "ina-select-dropdown__option--disabled"
5695
+ (disabled || option.disabled) && "ina-select-dropdown__option--disabled"
5637
5696
  ),
5638
5697
  children: [
5639
5698
  /* @__PURE__ */ jsx("div", { className: "ina-select-dropdown__option-content", children: labelContent }),
@@ -5666,7 +5725,7 @@ function SelectDropdown({
5666
5725
  ]
5667
5726
  }
5668
5727
  );
5669
- }
5728
+ };
5670
5729
  function Drawer({
5671
5730
  isOpen,
5672
5731
  onClose,