{"version":3,"file":"AppLauncher.cjs","sources":["../../../../src/components/Header/AppLauncher/AppLauncher.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, type HTMLAttributes, type ReactNode, memo, useMemo } from 'react'\nimport { type VariantProps, tv } from 'tailwind-variants'\n\nimport { type DecoratorsType, useDecorators } from '../../../hooks/useDecorators'\nimport { useIntl } from '../../../intl'\nimport { Button } from '../../Button'\nimport { Dropdown, DropdownContent, DropdownTrigger } from '../../Dropdown'\nimport { Heading } from '../../Heading'\nimport { FaCaretDownIcon, FaToolboxIcon } from '../../Icon'\nimport { Cluster, Stack } from '../../Layout'\nimport { TextLink } from '../../TextLink'\n\ntype Category = {\n  type?: string\n  heading: ReactNode\n  items: AppItem[]\n}\ntype AppItem = {\n  label: ReactNode\n  url: string\n  target?: string\n}\ntype AbstractProps = {\n  apps: Category[]\n  urlToShowAll?: string | null\n  /** コンポーネント内の文言を変更するための関数を設定 */\n  decorators?: DecoratorsType<DecoratorKeyTypes>\n} & VariantProps<typeof classNameGenerator>\ntype Props = AbstractProps & Omit<HTMLAttributes<HTMLElement>, keyof AbstractProps>\n\ntype DecoratorKeyTypes = 'triggerLabel'\n\nconst classNameGenerator = tv({\n  slots: {\n    appsButton: [\n      'shr-border-none shr-bg-transparent shr-px-0.25 shr-font-normal shr-text-white',\n      'hover:shr-border-transparent hover:shr-bg-transparent',\n      'focus-visible:shr-border-transparent focus-visible:shr-bg-transparent',\n      'forced-colors:shr-border-shorthand',\n    ],\n    contentWrapper: ['smarthr-ui-AppLauncher', 'shr-p-1.5 shr-leading-normal'],\n    category: 'smarthr-ui-AppLauncher-category',\n    appList: 'shr-list-none',\n    link: 'smarthr-ui-AppLauncher-link',\n    footer: [\n      'smarthr-ui-AppLauncher-footer',\n      'shr-border-t-shorthand -shr-mx-0.75 -shr-mb-0.25 shr-px-0.75 shr-pt-1',\n    ],\n  },\n  variants: {\n    enableNew: {\n      true: {\n        appsButton: [\n          'shr-px-0.5 shr-font-bold shr-text-black',\n          '[&_.smarthr-ui-Icon]:aria-expanded:shr-rotate-180',\n          'hover:shr-bg-white-darken',\n          'focus-visible:shr-bg-white-darken',\n        ],\n      },\n    },\n  },\n})\n\nexport const AppLauncher: FC<Props> = ({ apps, urlToShowAll, decorators, enableNew, ...rest }) => {\n  const calculatedApps = useMemo(() => {\n    const result: {\n      base: Props['apps'][number] | undefined\n      others: Props['apps']\n    } = { base: undefined, others: [] }\n\n    apps.forEach((app) => {\n      if (app.type === 'base') {\n        result.base = app\n      } else {\n        result.others.push(app)\n      }\n    })\n\n    return result\n  }, [apps])\n\n  const classNames = useMemo(() => {\n    const { appsButton, contentWrapper, category, appList, link, footer } = classNameGenerator({\n      enableNew,\n    })\n\n    return {\n      appsButton: appsButton(),\n      contentWrapper: contentWrapper(),\n      category: category(),\n      appList: appList(),\n      link: link(),\n      footer: footer(),\n    }\n  }, [enableNew])\n\n  return (\n    <Dropdown {...rest}>\n      <MemoizedDropdownTrigger\n        enableNew={enableNew}\n        decorators={decorators}\n        className={classNames.appsButton}\n      />\n      <DropdownContent controllable>\n        {/* eslint-disable-next-line smarthr/a11y-heading-in-sectioning-content */}\n        <Stack as=\"nav\" gap={1.5} className={classNames.contentWrapper}>\n          <Stack gap={1.5}>\n            {calculatedApps.base && (\n              <Stack gap={0.5} className={classNames.category} as=\"section\">\n                <Heading type=\"subSubBlockTitle\">{calculatedApps.base.heading}</Heading>\n                <Cluster as=\"ul\" gap={1} className={classNames.appList}>\n                  {calculatedApps.base.items.map((item, index) => (\n                    <LinkListItem\n                      key={index}\n                      href={item.url}\n                      target={item.target}\n                      className={classNames.link}\n                    >\n                      {item.label}\n                    </LinkListItem>\n                  ))}\n                </Cluster>\n              </Stack>\n            )}\n            <Cluster gap={1.5}>\n              {calculatedApps.others.map(({ heading, items }, i) => (\n                <Stack key={i} gap={0.5} className={classNames.category} as=\"section\">\n                  <Heading type=\"subSubBlockTitle\">{heading}</Heading>\n                  <Stack gap={0.5} as=\"ul\" className={classNames.appList}>\n                    {items.map((item, index) => (\n                      <LinkListItem\n                        key={index}\n                        href={item.url}\n                        target={item.target}\n                        className={classNames.link}\n                      >\n                        {item.label}\n                      </LinkListItem>\n                    ))}\n                  </Stack>\n                </Stack>\n              ))}\n            </Cluster>\n          </Stack>\n          <TextLinkToShowAll href={urlToShowAll} className={classNames.footer} />\n        </Stack>\n      </DropdownContent>\n    </Dropdown>\n  )\n}\n\nconst MemoizedDropdownTrigger = memo<\n  Pick<Props, 'enableNew' | 'decorators'> & { className: string }\n>(({ enableNew, className, decorators }) => {\n  const { localize } = useIntl()\n\n  const decoratorDefaultTexts = useMemo(\n    () => ({\n      triggerLabel: localize({\n        id: 'smarthr-ui/AppLauncher/triggerLabel',\n        defaultText: 'アプリ',\n      }),\n    }),\n    [localize],\n  )\n\n  const decorated = useDecorators<DecoratorKeyTypes>(decoratorDefaultTexts, decorators)\n\n  return (\n    <DropdownTrigger>\n      <Button\n        prefix={enableNew ?? <FaToolboxIcon />}\n        suffix={enableNew ? <FaCaretDownIcon /> : undefined}\n        className={className}\n      >\n        {decorated.triggerLabel}\n      </Button>\n    </DropdownTrigger>\n  )\n})\n\nconst TextLinkToShowAll = memo<{ href: Props['urlToShowAll']; className: string }>(\n  ({ href, className }) => {\n    const { localize } = useIntl()\n\n    if (!href) return null\n\n    return (\n      <div className={className}>\n        <TextLink href={href} style={{ width: 'fit-content' }}>\n          {localize({\n            id: 'smarthr-ui/AppLauncher/showAllText',\n            defaultText: 'すべて見る',\n          })}\n        </TextLink>\n      </div>\n    )\n  },\n)\n\nconst LinkListItem = memo<{\n  href: AppItem['url']\n  target: AppItem['target']\n  children: AppItem['label']\n  className: string\n}>(({ href, target, children, className }) => (\n  <li>\n    <TextLink href={href} target={target} className={className}>\n      {children}\n    </TextLink>\n  </li>\n))\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA;AACE;AACE;;;;;AAKC;AACD;AACA;AACA;AACA;AACA;;;AAGC;AACF;AACD;AACE;AACE;AACE;;;;;AAKC;AACF;AACF;AACF;AACF;AAEM;AACL;;AAME;AACE;AACE;;;AAEA;;AAEJ;AAEA;AACF;AAEA;AACE;;AAEC;;;;;;;;;AAUH;AAEA;AAqDF;AAEA;AAGE;AAEA;;AAGM;AACA;;AAEH;;AAMH;AAWF;AAEA;AAEI;AAEA;AAAW;;AAMH;AACA;;AAKV;AAGF;;"}