{"version":3,"file":"renderItems.mjs","names":[],"sources":["../../../src/base-ui/DropdownMenu/renderItems.tsx"],"sourcesContent":["import { Check, ChevronRight } from 'lucide-react';\nimport { type MenuInfo } from 'rc-menu/es/interface';\nimport {\n  type KeyboardEvent as ReactKeyboardEvent,\n  type MouseEvent as ReactMouseEvent,\n  type ReactNode,\n} from 'react';\n\nimport {\n  getItemKey,\n  getItemLabel,\n  hasAnyIcon,\n  hasCheckboxAndIcon,\n  type MenuDividerType,\n  type MenuItemGroupType,\n  type MenuItemType,\n  renderIcon,\n  type RenderItemContentOptions,\n  type RenderOptions,\n  type SubMenuType,\n} from '@/Menu';\nimport { styles } from '@/Menu/sharedStyle';\n\nimport {\n  DropdownMenuCheckboxItemIndicator,\n  DropdownMenuCheckboxItemPrimitive,\n  DropdownMenuGroup,\n  DropdownMenuGroupLabel,\n  DropdownMenuItem,\n  DropdownMenuItemContent,\n  DropdownMenuItemDesc,\n  DropdownMenuItemExtra,\n  DropdownMenuItemIcon,\n  DropdownMenuItemLabel,\n  DropdownMenuItemLabelGroup,\n  DropdownMenuPopup,\n  DropdownMenuPortal,\n  DropdownMenuPositioner,\n  DropdownMenuSeparator,\n  DropdownMenuSubmenuArrow,\n  DropdownMenuSubmenuRoot,\n  DropdownMenuSubmenuTrigger,\n  DropdownMenuSwitchItem,\n} from './atoms';\nimport {\n  type DropdownItem,\n  type DropdownMenuCheckboxItem as DropdownMenuCheckboxItemType,\n  type DropdownMenuSwitchItem as DropdownMenuSwitchItemType,\n} from './type';\n\nexport type { IconAlign, IconSpaceMode } from '@/Menu';\n\nconst renderItemContent = (\n  item: MenuItemType | SubMenuType | DropdownMenuCheckboxItemType | DropdownMenuSwitchItemType,\n  options?: RenderItemContentOptions,\n  iconNode?: ReactNode,\n) => {\n  const label = getItemLabel(item);\n  const desc = 'desc' in item ? item.desc : undefined;\n  const extra = 'extra' in item ? item.extra : undefined;\n  const indicatorOnRight = options?.indicatorOnRight;\n  const alignStart = Boolean(desc) && options?.iconAlign === 'start';\n\n  const hasCustomIcon = iconNode !== undefined && !indicatorOnRight;\n  const hasIcon = hasCustomIcon ? Boolean(iconNode) : Boolean(item.icon);\n  const shouldRenderIcon = hasCustomIcon\n    ? Boolean(options?.reserveIconSpace || iconNode)\n    : Boolean(hasIcon || options?.reserveIconSpace);\n\n  const labelNode = desc ? (\n    <DropdownMenuItemLabelGroup>\n      <DropdownMenuItemLabel>{label}</DropdownMenuItemLabel>\n      <DropdownMenuItemDesc>{desc}</DropdownMenuItemDesc>\n    </DropdownMenuItemLabelGroup>\n  ) : (\n    <DropdownMenuItemLabel>{label}</DropdownMenuItemLabel>\n  );\n\n  return (\n    <DropdownMenuItemContent className={alignStart ? styles.itemContentAlignStart : undefined}>\n      {shouldRenderIcon ? (\n        <DropdownMenuItemIcon\n          aria-hidden={!hasIcon}\n          className={alignStart ? styles.iconAlignStart : undefined}\n        >\n          {hasCustomIcon ? iconNode : hasIcon ? renderIcon(item.icon) : null}\n        </DropdownMenuItemIcon>\n      ) : null}\n      {labelNode}\n      {extra ? <DropdownMenuItemExtra>{extra}</DropdownMenuItemExtra> : null}\n      {indicatorOnRight && iconNode ? iconNode : null}\n      {options?.submenu ? (\n        <DropdownMenuSubmenuArrow>\n          <ChevronRight size={16} />\n        </DropdownMenuSubmenuArrow>\n      ) : null}\n    </DropdownMenuItemContent>\n  );\n};\n\nconst invokeItemClick = (\n  item: MenuItemType,\n  keyPath: string[],\n  event: ReactMouseEvent<HTMLElement> | ReactKeyboardEvent<HTMLElement>,\n) => {\n  if (!item.onClick) return;\n  const key = item.key ?? keyPath.at(-1) ?? '';\n  const info: MenuInfo = {\n    domEvent: event,\n    item: event.currentTarget as MenuInfo['item'],\n    key: String(key),\n    keyPath,\n  };\n  item.onClick(info);\n};\n\nexport const renderDropdownMenuItems = (\n  items: DropdownItem[],\n  keyPath: string[] = [],\n  options?: RenderOptions,\n): ReactNode[] => {\n  const iconAlign = options?.iconAlign;\n  const iconSpaceMode = options?.iconSpaceMode ?? 'global';\n  const reserveIconSpace =\n    options?.reserveIconSpace ?? hasAnyIcon(items, iconSpaceMode === 'global');\n  const indicatorOnRight = options?.indicatorOnRight ?? hasCheckboxAndIcon(items);\n\n  return items.map((item, index) => {\n    if (!item) return null;\n\n    const fallbackKey = `${keyPath.join('-') || 'root'}-${index}`;\n    const itemKey = getItemKey(item, fallbackKey);\n    const nextKeyPath = [...keyPath, String(itemKey)];\n\n    if ((item as DropdownMenuCheckboxItemType).type === 'checkbox') {\n      const checkboxItem = item as DropdownMenuCheckboxItemType;\n      const label = getItemLabel(checkboxItem);\n      const labelText = typeof label === 'string' ? label : undefined;\n      const isDanger = Boolean(checkboxItem.danger);\n      const indicator = (\n        <DropdownMenuCheckboxItemIndicator>{renderIcon(Check)}</DropdownMenuCheckboxItemIndicator>\n      );\n\n      return (\n        <DropdownMenuCheckboxItemPrimitive\n          checked={checkboxItem.checked}\n          closeOnClick={checkboxItem.closeOnClick}\n          danger={isDanger}\n          defaultChecked={checkboxItem.defaultChecked}\n          disabled={checkboxItem.disabled}\n          key={itemKey}\n          label={labelText}\n          onCheckedChange={(checked) => checkboxItem.onCheckedChange?.(checked)}\n        >\n          {renderItemContent(\n            checkboxItem,\n            { iconAlign, indicatorOnRight, reserveIconSpace },\n            indicator,\n          )}\n        </DropdownMenuCheckboxItemPrimitive>\n      );\n    }\n\n    if ((item as DropdownMenuSwitchItemType).type === 'switch') {\n      const switchItem = item as DropdownMenuSwitchItemType;\n      const label = getItemLabel(switchItem);\n      const labelText = typeof label === 'string' ? label : undefined;\n      const isDanger = Boolean(switchItem.danger);\n\n      return (\n        <DropdownMenuSwitchItem\n          checked={switchItem.checked}\n          closeOnClick={switchItem.closeOnClick}\n          danger={isDanger}\n          defaultChecked={switchItem.defaultChecked}\n          disabled={switchItem.disabled}\n          key={itemKey}\n          label={labelText}\n          onCheckedChange={(checked) => switchItem.onCheckedChange?.(checked)}\n        >\n          {renderItemContent(switchItem, { iconAlign, reserveIconSpace })}\n        </DropdownMenuSwitchItem>\n      );\n    }\n\n    if ((item as MenuDividerType).type === 'divider') {\n      return <DropdownMenuSeparator key={itemKey} />;\n    }\n\n    if ((item as MenuItemGroupType).type === 'group') {\n      const group = item as MenuItemGroupType;\n      const groupReserveIconSpace =\n        iconSpaceMode === 'group'\n          ? group.children\n            ? hasAnyIcon(group.children)\n            : false\n          : reserveIconSpace;\n      const groupIndicatorOnRight = group.children ? hasCheckboxAndIcon(group.children) : false;\n      return (\n        <DropdownMenuGroup key={itemKey}>\n          {group.label ? <DropdownMenuGroupLabel>{group.label}</DropdownMenuGroupLabel> : null}\n          {group.children\n            ? renderDropdownMenuItems(group.children, nextKeyPath, {\n                iconAlign,\n                iconSpaceMode,\n                indicatorOnRight: groupIndicatorOnRight,\n                reserveIconSpace: groupReserveIconSpace,\n              })\n            : null}\n        </DropdownMenuGroup>\n      );\n    }\n\n    if ((item as SubMenuType).type === 'submenu' || 'children' in item) {\n      const submenu = item as SubMenuType;\n      const label = getItemLabel(submenu);\n      const labelText = typeof label === 'string' ? label : undefined;\n      const isDanger = 'danger' in submenu && Boolean(submenu.danger);\n\n      return (\n        <DropdownMenuSubmenuRoot key={itemKey}>\n          <DropdownMenuSubmenuTrigger\n            danger={isDanger}\n            disabled={submenu.disabled}\n            label={labelText}\n          >\n            {renderItemContent(submenu, {\n              iconAlign,\n              reserveIconSpace,\n              submenu: true,\n            })}\n          </DropdownMenuSubmenuTrigger>\n          <DropdownMenuPortal>\n            <DropdownMenuPositioner alignOffset={-4} data-submenu=\"\" sideOffset={-1}>\n              <DropdownMenuPopup>\n                {submenu.children\n                  ? renderDropdownMenuItems(submenu.children, nextKeyPath, {\n                      iconAlign,\n                      iconSpaceMode,\n                    })\n                  : null}\n              </DropdownMenuPopup>\n            </DropdownMenuPositioner>\n          </DropdownMenuPortal>\n        </DropdownMenuSubmenuRoot>\n      );\n    }\n\n    const menuItem = item as MenuItemType;\n    const label = getItemLabel(menuItem);\n    const labelText = typeof label === 'string' ? label : undefined;\n    const isDanger = 'danger' in menuItem && Boolean(menuItem.danger);\n\n    return (\n      <DropdownMenuItem\n        closeOnClick={menuItem.closeOnClick}\n        danger={isDanger}\n        disabled={menuItem.disabled}\n        key={itemKey}\n        label={labelText}\n        onClick={(event) => invokeItemClick(menuItem, nextKeyPath, event)}\n      >\n        {renderItemContent(menuItem, { iconAlign, reserveIconSpace })}\n      </DropdownMenuItem>\n    );\n  });\n};\n"],"mappings":"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"}