smarthr-ui 90.0.0 → 90.0.1

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.
@@ -125,7 +125,7 @@ const AppLauncher = ({ features: baseFeatures }) => {
125
125
  defaultText: '検索結果',
126
126
  }) })),
127
127
  }), [localize]);
128
- return (jsxRuntime.jsxs("div", { className: classNames.wrapper, children: [jsxRuntime.jsx("div", { className: classNames.searchArea, children: jsxRuntime.jsx(components_Input_SearchInput_SearchInput.SearchInput, { name: "search", title: translated.searchInputTitle, tooltipMessage: jsxRuntime.jsx(components_AppHeader_components_common_Translate.Translate, { children: translated.searchInputTitle }), width: "100%", value: searchQuery, suffix: mode === 'search' && jsxRuntime.jsx(ClearSearchButton, { onClick: onClickClearSearchQuery }), onChange: onChangeSearchQuery }) }), jsxRuntime.jsxs("div", { className: classNames.inner, children: [jsxRuntime.jsx(SideNavs, { mode: mode, page: page, changePage: changePage, translated: translated, classNames: classNames }), jsxRuntime.jsx("main", { className: classNames.main, children: jsxRuntime.jsxs(components_SectioningContent_SectioningContent.Section, { className: classNames.mainInner, children: [jsxRuntime.jsxs(components_Layout_Cluster_Cluster.Cluster, { className: classNames.contentHead, align: "center", justify: "space-between", children: [jsxRuntime.jsx(MemoizedSubSubBlockHeading, { children: mode === 'search' ? translated.searchResultText : translated[page] }), (mode === 'search' || page === 'all') && (jsxRuntime.jsx(components_AppHeader_components_common_AppLauncherSortDropdown.AppLauncherSortDropdown, { sortType: sortType, onSelectSortType: setSortType }))] }), jsxRuntime.jsx("div", { className: classNames.scrollArea, children: jsxRuntime.jsx(components_AppHeader_components_common_AppLauncherFeatures.AppLauncherFeatures, { features: features, page: page }) })] }) })] })] }));
128
+ return (jsxRuntime.jsxs("div", { className: classNames.wrapper, children: [jsxRuntime.jsx("div", { className: classNames.searchArea, children: jsxRuntime.jsx(components_Input_SearchInput_SearchInput.SearchInput, { name: "search", title: translated.searchInputTitle, tooltipMessage: jsxRuntime.jsx(components_AppHeader_components_common_Translate.Translate, { children: translated.searchInputTitle }), width: "100%", value: searchQuery, suffix: mode === 'search' && jsxRuntime.jsx(ClearSearchButton, { onClick: onClickClearSearchQuery }), onChange: onChangeSearchQuery }) }), jsxRuntime.jsxs("div", { className: classNames.inner, children: [jsxRuntime.jsx(SideNavs, { mode: mode, page: page, changePage: changePage, translated: translated, classNames: classNames }), jsxRuntime.jsx("div", { className: classNames.main, children: jsxRuntime.jsxs(components_SectioningContent_SectioningContent.Section, { className: classNames.mainInner, children: [jsxRuntime.jsxs(components_Layout_Cluster_Cluster.Cluster, { className: classNames.contentHead, align: "center", justify: "space-between", children: [jsxRuntime.jsx(MemoizedSubSubBlockHeading, { children: mode === 'search' ? translated.searchResultText : translated[page] }), (mode === 'search' || page === 'all') && (jsxRuntime.jsx(components_AppHeader_components_common_AppLauncherSortDropdown.AppLauncherSortDropdown, { sortType: sortType, onSelectSortType: setSortType }))] }), jsxRuntime.jsx("div", { className: classNames.scrollArea, children: jsxRuntime.jsx(components_AppHeader_components_common_AppLauncherFeatures.AppLauncherFeatures, { features: features, page: page }) })] }) })] })] }));
129
129
  };
130
130
  const ClearSearchButton = React.memo(({ onClick }) => (jsxRuntime.jsx(components_Button_UnstyledButton.UnstyledButton, { onClick: onClick, children: jsxRuntime.jsx(components_Icon_FaIcon.FaCircleXmarkIcon, {}) })));
131
131
  const SideNavs = React.memo(({ mode, page, changePage, translated, classNames }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"AppLauncher.cjs","sources":["../../../../../src/components/AppHeader/components/desktop/AppLauncher.tsx"],"sourcesContent":["import { type FC, type PropsWithChildren, type ReactNode, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useIntl } from '../../../../intl'\nimport { textColor } from '../../../../themes'\nimport { UnstyledButton } from '../../../Button'\nimport { Heading } from '../../../Heading'\nimport { FaCircleXmarkIcon, FaStarIcon } from '../../../Icon'\nimport { SearchInput } from '../../../Input'\nimport { Cluster } from '../../../Layout'\nimport { Section } from '../../../SectioningContent'\nimport { SideNav } from '../../../SideNav'\nimport { HelpLink } from '../../../TextLink'\nimport { useAppLauncher } from '../../hooks/useAppLauncher'\nimport { AppLauncherFeatures } from '../common/AppLauncherFeatures'\nimport { AppLauncherSortDropdown } from '../common/AppLauncherSortDropdown'\nimport { Translate } from '../common/Translate'\n\nimport type { Launcher } from '../../types'\n\ntype Props = {\n features: Array<Launcher['feature']>\n}\n\nconst appLauncher = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-AppLauncher',\n 'shr-grid shr-h-[40rem] shr-w-[38rem] shr-grid-rows-[auto_1fr]',\n ],\n searchArea: [\n 'smarthr-ui-AppLauncher-searchArea',\n 'shr-border-b-shorthand shr-p-1',\n '[&_.smarthr-ui-Input]:shr-h-[42px]',\n ],\n inner: ['smarthr-ui-AppLauncher-inner', 'shr-grid shr-min-h-0 shr-grid-cols-[11rem_1fr]'],\n side: [\n 'smarthr-ui-AppLauncher-side',\n 'shr-border-r-shorthand shr-flex shr-flex-col shr-bg-column shr-pb-1 shr-pt-0.5',\n '[&_hr]:shr-m-0.5 [&_hr]:shr-h-[1px] [&_hr]:shr-border-none [&_hr]:shr-bg-border',\n ],\n sideNav: [\n '[&_.smarthr-ui-SideNav-item>button]:shr-px-1 [&_.smarthr-ui-SideNav-item>button]:shr-py-0.75',\n '[&_.smarthr-ui-SideNav-item>button>span]:shr-flex-nowrap',\n '[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-shrink-0 [&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-align-bottom',\n ],\n sideNavHeading: ['shr-px-1 shr-py-0.75 shr-text-xs shr-text-black'],\n help: ['smarthr-ui-AppLauncher-help', 'shr-mt-auto shr-px-1 shr-text-xs'],\n main: ['smarthr-ui-AppLauncher-main', 'shr-grid shr-min-h-0'],\n mainInner: ['shr-grid shr-min-h-0 shr-grid-rows-[auto_1fr]'],\n contentHead: [\n 'shr-min-h-[2rem] shr-px-1 shr-py-0.75',\n '[&_.smarthr-ui-Heading]:shr-text-black',\n ],\n scrollArea: ['shr-h-[509px] shr-overflow-y-scroll'],\n },\n variants: {\n noIcon: {\n true: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button]:shr-pl-1.5'],\n },\n },\n selected: {\n false: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-text-grey'],\n },\n },\n },\n})\n\nexport const AppLauncher: FC<Props> = ({ features: baseFeatures }) => {\n const {\n features,\n page,\n mode,\n sortType,\n searchQuery,\n changePage,\n setSortType,\n onChangeSearchQuery,\n onClickClearSearchQuery,\n } = useAppLauncher(baseFeatures)\n\n const classNames = useMemo(() => {\n const {\n wrapper,\n searchArea,\n inner,\n side,\n sideNav,\n sideNavHeading,\n help,\n main,\n mainInner,\n contentHead,\n scrollArea,\n } = appLauncher()\n\n return {\n wrapper: wrapper(),\n searchArea: searchArea(),\n inner: inner(),\n side: side(),\n unselectedSideNav: sideNav({ selected: false }),\n selectedSideNav: sideNav({ noIcon: true, selected: true }),\n sideNavHeading: sideNavHeading(),\n help: help(),\n main: main(),\n mainInner: mainInner(),\n contentHead: contentHead(),\n scrollArea: scrollArea(),\n }\n }, [])\n\n const { localize } = useIntl()\n const translated = useMemo<\n Record<\n Launcher['page'] | 'listText' | 'searchInputTitle' | 'helpText' | 'searchResultText',\n ReactNode\n >\n >(\n () => ({\n favorite: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/favoriteModeText',\n defaultText: 'よく使うアプリ',\n })}\n </Translate>\n ),\n all: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/allModeText',\n defaultText: 'すべてのアプリ',\n })}\n </Translate>\n ),\n listText: (\n <Translate>\n {localize({ id: 'smarthr-ui/AppHeader/Launcher/listText', defaultText: 'アプリ一覧' })}\n </Translate>\n ),\n searchInputTitle: localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchInputTitle',\n defaultText: 'アプリ名を入力してください。',\n }),\n helpText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/helpText',\n defaultText: 'よく使うアプリとは',\n })}\n </Translate>\n ),\n searchResultText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchResultText',\n defaultText: '検索結果',\n })}\n </Translate>\n ),\n }),\n [localize],\n )\n\n return (\n <div className={classNames.wrapper}>\n <div className={classNames.searchArea}>\n <SearchInput\n name=\"search\"\n title={translated.searchInputTitle as string}\n tooltipMessage={<Translate>{translated.searchInputTitle}</Translate>}\n width=\"100%\"\n value={searchQuery}\n suffix={mode === 'search' && <ClearSearchButton onClick={onClickClearSearchQuery} />}\n onChange={onChangeSearchQuery}\n />\n </div>\n\n <div className={classNames.inner}>\n <SideNavs\n mode={mode}\n page={page}\n changePage={changePage}\n translated={translated}\n classNames={classNames}\n />\n <main className={classNames.main}>\n <Section className={classNames.mainInner}>\n <Cluster className={classNames.contentHead} align=\"center\" justify=\"space-between\">\n <MemoizedSubSubBlockHeading>\n {mode === 'search' ? translated.searchResultText : translated[page]}\n </MemoizedSubSubBlockHeading>\n\n {(mode === 'search' || page === 'all') && (\n <AppLauncherSortDropdown sortType={sortType} onSelectSortType={setSortType} />\n )}\n </Cluster>\n\n <div className={classNames.scrollArea}>\n <AppLauncherFeatures features={features} page={page} />\n </div>\n </Section>\n </main>\n </div>\n </div>\n )\n}\n\nconst ClearSearchButton = memo<{ onClick: () => void }>(({ onClick }) => (\n <UnstyledButton onClick={onClick}>\n <FaCircleXmarkIcon />\n </UnstyledButton>\n))\n\nconst SideNavs = memo<\n Pick<ReturnType<typeof useAppLauncher>, 'mode' | 'page' | 'changePage'> & {\n translated: { favorite: ReactNode; listText: ReactNode; all: ReactNode; helpText: ReactNode }\n classNames: {\n side: string\n unselectedSideNav: string\n sideNavHeading: string\n selectedSideNav: string\n help: string\n }\n }\n>(({ mode, page, changePage, translated, classNames }) => {\n const isNotSearch = mode !== 'search'\n const isFavorite = isNotSearch && page === 'favorite'\n const isAll = isNotSearch && page === 'all'\n\n const unselectedItems = useMemo(\n () => [\n {\n id: 'favorite',\n title: translated.favorite,\n prefix: <FaStarIcon color={isFavorite ? textColor.white : undefined} />,\n current: isFavorite,\n },\n ],\n [isFavorite, translated],\n )\n const selectedItems = useMemo(\n () => [\n {\n id: 'all',\n title: translated.all,\n current: isAll,\n },\n ],\n [isAll, translated],\n )\n\n const onClick = useCallback(\n (_: any, id: string) => {\n changePage(id as Launcher['page'])\n },\n [changePage],\n )\n\n return (\n <div className={classNames.side}>\n <SideNav\n className={classNames.unselectedSideNav}\n size=\"s\"\n items={unselectedItems}\n onClick={onClick}\n />\n\n <hr />\n\n <Section>\n <MemoizedSubSubBlockHeading className={classNames.sideNavHeading}>\n {translated.listText}\n </MemoizedSubSubBlockHeading>\n <SideNav\n className={classNames.selectedSideNav}\n size=\"s\"\n items={selectedItems}\n onClick={onClick}\n />\n </Section>\n\n <HelpLinkArea className={classNames.help}>{translated.helpText}</HelpLinkArea>\n </div>\n )\n})\n\nconst HelpLinkArea = memo<PropsWithChildren<{ className: string }>>(({ children, className }) => (\n <div className={className}>\n <HelpLink\n href=\"https://support.smarthr.jp/ja/help/articles/2bfd350d-8e8b-4bbd-a209-426d2eb302cc/\"\n target=\"_blank\"\n >\n {children}\n </HelpLink>\n </div>\n))\n\nconst MemoizedSubSubBlockHeading = memo<PropsWithChildren<{ className?: string }>>(\n ({ children, className }) => (\n <Heading type=\"subSubBlockTitle\" className={className}>\n {children}\n </Heading>\n ),\n)\n"],"names":["tv","useAppLauncher","useMemo","useIntl","_jsx","Translate","_jsxs","SearchInput","Section","Cluster","AppLauncherSortDropdown","AppLauncherFeatures","memo","UnstyledButton","FaCircleXmarkIcon","FaStarIcon","textColor","useCallback","SideNav","HelpLink","Heading"],"mappings":"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"}
1
+ {"version":3,"file":"AppLauncher.cjs","sources":["../../../../../src/components/AppHeader/components/desktop/AppLauncher.tsx"],"sourcesContent":["import { type FC, type PropsWithChildren, type ReactNode, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useIntl } from '../../../../intl'\nimport { textColor } from '../../../../themes'\nimport { UnstyledButton } from '../../../Button'\nimport { Heading } from '../../../Heading'\nimport { FaCircleXmarkIcon, FaStarIcon } from '../../../Icon'\nimport { SearchInput } from '../../../Input'\nimport { Cluster } from '../../../Layout'\nimport { Section } from '../../../SectioningContent'\nimport { SideNav } from '../../../SideNav'\nimport { HelpLink } from '../../../TextLink'\nimport { useAppLauncher } from '../../hooks/useAppLauncher'\nimport { AppLauncherFeatures } from '../common/AppLauncherFeatures'\nimport { AppLauncherSortDropdown } from '../common/AppLauncherSortDropdown'\nimport { Translate } from '../common/Translate'\n\nimport type { Launcher } from '../../types'\n\ntype Props = {\n features: Array<Launcher['feature']>\n}\n\nconst appLauncher = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-AppLauncher',\n 'shr-grid shr-h-[40rem] shr-w-[38rem] shr-grid-rows-[auto_1fr]',\n ],\n searchArea: [\n 'smarthr-ui-AppLauncher-searchArea',\n 'shr-border-b-shorthand shr-p-1',\n '[&_.smarthr-ui-Input]:shr-h-[42px]',\n ],\n inner: ['smarthr-ui-AppLauncher-inner', 'shr-grid shr-min-h-0 shr-grid-cols-[11rem_1fr]'],\n side: [\n 'smarthr-ui-AppLauncher-side',\n 'shr-border-r-shorthand shr-flex shr-flex-col shr-bg-column shr-pb-1 shr-pt-0.5',\n '[&_hr]:shr-m-0.5 [&_hr]:shr-h-[1px] [&_hr]:shr-border-none [&_hr]:shr-bg-border',\n ],\n sideNav: [\n '[&_.smarthr-ui-SideNav-item>button]:shr-px-1 [&_.smarthr-ui-SideNav-item>button]:shr-py-0.75',\n '[&_.smarthr-ui-SideNav-item>button>span]:shr-flex-nowrap',\n '[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-shrink-0 [&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-align-bottom',\n ],\n sideNavHeading: ['shr-px-1 shr-py-0.75 shr-text-xs shr-text-black'],\n help: ['smarthr-ui-AppLauncher-help', 'shr-mt-auto shr-px-1 shr-text-xs'],\n main: ['smarthr-ui-AppLauncher-main', 'shr-grid shr-min-h-0'],\n mainInner: ['shr-grid shr-min-h-0 shr-grid-rows-[auto_1fr]'],\n contentHead: [\n 'shr-min-h-[2rem] shr-px-1 shr-py-0.75',\n '[&_.smarthr-ui-Heading]:shr-text-black',\n ],\n scrollArea: ['shr-h-[509px] shr-overflow-y-scroll'],\n },\n variants: {\n noIcon: {\n true: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button]:shr-pl-1.5'],\n },\n },\n selected: {\n false: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-text-grey'],\n },\n },\n },\n})\n\nexport const AppLauncher: FC<Props> = ({ features: baseFeatures }) => {\n const {\n features,\n page,\n mode,\n sortType,\n searchQuery,\n changePage,\n setSortType,\n onChangeSearchQuery,\n onClickClearSearchQuery,\n } = useAppLauncher(baseFeatures)\n\n const classNames = useMemo(() => {\n const {\n wrapper,\n searchArea,\n inner,\n side,\n sideNav,\n sideNavHeading,\n help,\n main,\n mainInner,\n contentHead,\n scrollArea,\n } = appLauncher()\n\n return {\n wrapper: wrapper(),\n searchArea: searchArea(),\n inner: inner(),\n side: side(),\n unselectedSideNav: sideNav({ selected: false }),\n selectedSideNav: sideNav({ noIcon: true, selected: true }),\n sideNavHeading: sideNavHeading(),\n help: help(),\n main: main(),\n mainInner: mainInner(),\n contentHead: contentHead(),\n scrollArea: scrollArea(),\n }\n }, [])\n\n const { localize } = useIntl()\n const translated = useMemo<\n Record<\n Launcher['page'] | 'listText' | 'searchInputTitle' | 'helpText' | 'searchResultText',\n ReactNode\n >\n >(\n () => ({\n favorite: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/favoriteModeText',\n defaultText: 'よく使うアプリ',\n })}\n </Translate>\n ),\n all: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/allModeText',\n defaultText: 'すべてのアプリ',\n })}\n </Translate>\n ),\n listText: (\n <Translate>\n {localize({ id: 'smarthr-ui/AppHeader/Launcher/listText', defaultText: 'アプリ一覧' })}\n </Translate>\n ),\n searchInputTitle: localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchInputTitle',\n defaultText: 'アプリ名を入力してください。',\n }),\n helpText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/helpText',\n defaultText: 'よく使うアプリとは',\n })}\n </Translate>\n ),\n searchResultText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchResultText',\n defaultText: '検索結果',\n })}\n </Translate>\n ),\n }),\n [localize],\n )\n\n return (\n <div className={classNames.wrapper}>\n <div className={classNames.searchArea}>\n <SearchInput\n name=\"search\"\n title={translated.searchInputTitle as string}\n tooltipMessage={<Translate>{translated.searchInputTitle}</Translate>}\n width=\"100%\"\n value={searchQuery}\n suffix={mode === 'search' && <ClearSearchButton onClick={onClickClearSearchQuery} />}\n onChange={onChangeSearchQuery}\n />\n </div>\n\n <div className={classNames.inner}>\n <SideNavs\n mode={mode}\n page={page}\n changePage={changePage}\n translated={translated}\n classNames={classNames}\n />\n <div className={classNames.main}>\n <Section className={classNames.mainInner}>\n <Cluster className={classNames.contentHead} align=\"center\" justify=\"space-between\">\n <MemoizedSubSubBlockHeading>\n {mode === 'search' ? translated.searchResultText : translated[page]}\n </MemoizedSubSubBlockHeading>\n\n {(mode === 'search' || page === 'all') && (\n <AppLauncherSortDropdown sortType={sortType} onSelectSortType={setSortType} />\n )}\n </Cluster>\n\n <div className={classNames.scrollArea}>\n <AppLauncherFeatures features={features} page={page} />\n </div>\n </Section>\n </div>\n </div>\n </div>\n )\n}\n\nconst ClearSearchButton = memo<{ onClick: () => void }>(({ onClick }) => (\n <UnstyledButton onClick={onClick}>\n <FaCircleXmarkIcon />\n </UnstyledButton>\n))\n\nconst SideNavs = memo<\n Pick<ReturnType<typeof useAppLauncher>, 'mode' | 'page' | 'changePage'> & {\n translated: { favorite: ReactNode; listText: ReactNode; all: ReactNode; helpText: ReactNode }\n classNames: {\n side: string\n unselectedSideNav: string\n sideNavHeading: string\n selectedSideNav: string\n help: string\n }\n }\n>(({ mode, page, changePage, translated, classNames }) => {\n const isNotSearch = mode !== 'search'\n const isFavorite = isNotSearch && page === 'favorite'\n const isAll = isNotSearch && page === 'all'\n\n const unselectedItems = useMemo(\n () => [\n {\n id: 'favorite',\n title: translated.favorite,\n prefix: <FaStarIcon color={isFavorite ? textColor.white : undefined} />,\n current: isFavorite,\n },\n ],\n [isFavorite, translated],\n )\n const selectedItems = useMemo(\n () => [\n {\n id: 'all',\n title: translated.all,\n current: isAll,\n },\n ],\n [isAll, translated],\n )\n\n const onClick = useCallback(\n (_: any, id: string) => {\n changePage(id as Launcher['page'])\n },\n [changePage],\n )\n\n return (\n <div className={classNames.side}>\n <SideNav\n className={classNames.unselectedSideNav}\n size=\"s\"\n items={unselectedItems}\n onClick={onClick}\n />\n\n <hr />\n\n <Section>\n <MemoizedSubSubBlockHeading className={classNames.sideNavHeading}>\n {translated.listText}\n </MemoizedSubSubBlockHeading>\n <SideNav\n className={classNames.selectedSideNav}\n size=\"s\"\n items={selectedItems}\n onClick={onClick}\n />\n </Section>\n\n <HelpLinkArea className={classNames.help}>{translated.helpText}</HelpLinkArea>\n </div>\n )\n})\n\nconst HelpLinkArea = memo<PropsWithChildren<{ className: string }>>(({ children, className }) => (\n <div className={className}>\n <HelpLink\n href=\"https://support.smarthr.jp/ja/help/articles/2bfd350d-8e8b-4bbd-a209-426d2eb302cc/\"\n target=\"_blank\"\n >\n {children}\n </HelpLink>\n </div>\n))\n\nconst MemoizedSubSubBlockHeading = memo<PropsWithChildren<{ className?: string }>>(\n ({ children, className }) => (\n <Heading type=\"subSubBlockTitle\" className={className}>\n {children}\n </Heading>\n ),\n)\n"],"names":["tv","useAppLauncher","useMemo","useIntl","_jsx","Translate","_jsxs","SearchInput","Section","Cluster","AppLauncherSortDropdown","AppLauncherFeatures","memo","UnstyledButton","FaCircleXmarkIcon","FaStarIcon","textColor","useCallback","SideNav","HelpLink","Heading"],"mappings":"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"}
@@ -123,7 +123,7 @@ const AppLauncher = ({ features: baseFeatures }) => {
123
123
  defaultText: '検索結果',
124
124
  }) })),
125
125
  }), [localize]);
126
- return (jsxs("div", { className: classNames.wrapper, children: [jsx("div", { className: classNames.searchArea, children: jsx(SearchInput, { name: "search", title: translated.searchInputTitle, tooltipMessage: jsx(Translate, { children: translated.searchInputTitle }), width: "100%", value: searchQuery, suffix: mode === 'search' && jsx(ClearSearchButton, { onClick: onClickClearSearchQuery }), onChange: onChangeSearchQuery }) }), jsxs("div", { className: classNames.inner, children: [jsx(SideNavs, { mode: mode, page: page, changePage: changePage, translated: translated, classNames: classNames }), jsx("main", { className: classNames.main, children: jsxs(Section, { className: classNames.mainInner, children: [jsxs(Cluster, { className: classNames.contentHead, align: "center", justify: "space-between", children: [jsx(MemoizedSubSubBlockHeading, { children: mode === 'search' ? translated.searchResultText : translated[page] }), (mode === 'search' || page === 'all') && (jsx(AppLauncherSortDropdown, { sortType: sortType, onSelectSortType: setSortType }))] }), jsx("div", { className: classNames.scrollArea, children: jsx(AppLauncherFeatures, { features: features, page: page }) })] }) })] })] }));
126
+ return (jsxs("div", { className: classNames.wrapper, children: [jsx("div", { className: classNames.searchArea, children: jsx(SearchInput, { name: "search", title: translated.searchInputTitle, tooltipMessage: jsx(Translate, { children: translated.searchInputTitle }), width: "100%", value: searchQuery, suffix: mode === 'search' && jsx(ClearSearchButton, { onClick: onClickClearSearchQuery }), onChange: onChangeSearchQuery }) }), jsxs("div", { className: classNames.inner, children: [jsx(SideNavs, { mode: mode, page: page, changePage: changePage, translated: translated, classNames: classNames }), jsx("div", { className: classNames.main, children: jsxs(Section, { className: classNames.mainInner, children: [jsxs(Cluster, { className: classNames.contentHead, align: "center", justify: "space-between", children: [jsx(MemoizedSubSubBlockHeading, { children: mode === 'search' ? translated.searchResultText : translated[page] }), (mode === 'search' || page === 'all') && (jsx(AppLauncherSortDropdown, { sortType: sortType, onSelectSortType: setSortType }))] }), jsx("div", { className: classNames.scrollArea, children: jsx(AppLauncherFeatures, { features: features, page: page }) })] }) })] })] }));
127
127
  };
128
128
  const ClearSearchButton = memo(({ onClick }) => (jsx(UnstyledButton, { onClick: onClick, children: jsx(FaCircleXmarkIcon, {}) })));
129
129
  const SideNavs = memo(({ mode, page, changePage, translated, classNames }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"AppLauncher.js","sources":["../../../../../src/components/AppHeader/components/desktop/AppLauncher.tsx"],"sourcesContent":["import { type FC, type PropsWithChildren, type ReactNode, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useIntl } from '../../../../intl'\nimport { textColor } from '../../../../themes'\nimport { UnstyledButton } from '../../../Button'\nimport { Heading } from '../../../Heading'\nimport { FaCircleXmarkIcon, FaStarIcon } from '../../../Icon'\nimport { SearchInput } from '../../../Input'\nimport { Cluster } from '../../../Layout'\nimport { Section } from '../../../SectioningContent'\nimport { SideNav } from '../../../SideNav'\nimport { HelpLink } from '../../../TextLink'\nimport { useAppLauncher } from '../../hooks/useAppLauncher'\nimport { AppLauncherFeatures } from '../common/AppLauncherFeatures'\nimport { AppLauncherSortDropdown } from '../common/AppLauncherSortDropdown'\nimport { Translate } from '../common/Translate'\n\nimport type { Launcher } from '../../types'\n\ntype Props = {\n features: Array<Launcher['feature']>\n}\n\nconst appLauncher = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-AppLauncher',\n 'shr-grid shr-h-[40rem] shr-w-[38rem] shr-grid-rows-[auto_1fr]',\n ],\n searchArea: [\n 'smarthr-ui-AppLauncher-searchArea',\n 'shr-border-b-shorthand shr-p-1',\n '[&_.smarthr-ui-Input]:shr-h-[42px]',\n ],\n inner: ['smarthr-ui-AppLauncher-inner', 'shr-grid shr-min-h-0 shr-grid-cols-[11rem_1fr]'],\n side: [\n 'smarthr-ui-AppLauncher-side',\n 'shr-border-r-shorthand shr-flex shr-flex-col shr-bg-column shr-pb-1 shr-pt-0.5',\n '[&_hr]:shr-m-0.5 [&_hr]:shr-h-[1px] [&_hr]:shr-border-none [&_hr]:shr-bg-border',\n ],\n sideNav: [\n '[&_.smarthr-ui-SideNav-item>button]:shr-px-1 [&_.smarthr-ui-SideNav-item>button]:shr-py-0.75',\n '[&_.smarthr-ui-SideNav-item>button>span]:shr-flex-nowrap',\n '[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-shrink-0 [&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-align-bottom',\n ],\n sideNavHeading: ['shr-px-1 shr-py-0.75 shr-text-xs shr-text-black'],\n help: ['smarthr-ui-AppLauncher-help', 'shr-mt-auto shr-px-1 shr-text-xs'],\n main: ['smarthr-ui-AppLauncher-main', 'shr-grid shr-min-h-0'],\n mainInner: ['shr-grid shr-min-h-0 shr-grid-rows-[auto_1fr]'],\n contentHead: [\n 'shr-min-h-[2rem] shr-px-1 shr-py-0.75',\n '[&_.smarthr-ui-Heading]:shr-text-black',\n ],\n scrollArea: ['shr-h-[509px] shr-overflow-y-scroll'],\n },\n variants: {\n noIcon: {\n true: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button]:shr-pl-1.5'],\n },\n },\n selected: {\n false: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-text-grey'],\n },\n },\n },\n})\n\nexport const AppLauncher: FC<Props> = ({ features: baseFeatures }) => {\n const {\n features,\n page,\n mode,\n sortType,\n searchQuery,\n changePage,\n setSortType,\n onChangeSearchQuery,\n onClickClearSearchQuery,\n } = useAppLauncher(baseFeatures)\n\n const classNames = useMemo(() => {\n const {\n wrapper,\n searchArea,\n inner,\n side,\n sideNav,\n sideNavHeading,\n help,\n main,\n mainInner,\n contentHead,\n scrollArea,\n } = appLauncher()\n\n return {\n wrapper: wrapper(),\n searchArea: searchArea(),\n inner: inner(),\n side: side(),\n unselectedSideNav: sideNav({ selected: false }),\n selectedSideNav: sideNav({ noIcon: true, selected: true }),\n sideNavHeading: sideNavHeading(),\n help: help(),\n main: main(),\n mainInner: mainInner(),\n contentHead: contentHead(),\n scrollArea: scrollArea(),\n }\n }, [])\n\n const { localize } = useIntl()\n const translated = useMemo<\n Record<\n Launcher['page'] | 'listText' | 'searchInputTitle' | 'helpText' | 'searchResultText',\n ReactNode\n >\n >(\n () => ({\n favorite: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/favoriteModeText',\n defaultText: 'よく使うアプリ',\n })}\n </Translate>\n ),\n all: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/allModeText',\n defaultText: 'すべてのアプリ',\n })}\n </Translate>\n ),\n listText: (\n <Translate>\n {localize({ id: 'smarthr-ui/AppHeader/Launcher/listText', defaultText: 'アプリ一覧' })}\n </Translate>\n ),\n searchInputTitle: localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchInputTitle',\n defaultText: 'アプリ名を入力してください。',\n }),\n helpText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/helpText',\n defaultText: 'よく使うアプリとは',\n })}\n </Translate>\n ),\n searchResultText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchResultText',\n defaultText: '検索結果',\n })}\n </Translate>\n ),\n }),\n [localize],\n )\n\n return (\n <div className={classNames.wrapper}>\n <div className={classNames.searchArea}>\n <SearchInput\n name=\"search\"\n title={translated.searchInputTitle as string}\n tooltipMessage={<Translate>{translated.searchInputTitle}</Translate>}\n width=\"100%\"\n value={searchQuery}\n suffix={mode === 'search' && <ClearSearchButton onClick={onClickClearSearchQuery} />}\n onChange={onChangeSearchQuery}\n />\n </div>\n\n <div className={classNames.inner}>\n <SideNavs\n mode={mode}\n page={page}\n changePage={changePage}\n translated={translated}\n classNames={classNames}\n />\n <main className={classNames.main}>\n <Section className={classNames.mainInner}>\n <Cluster className={classNames.contentHead} align=\"center\" justify=\"space-between\">\n <MemoizedSubSubBlockHeading>\n {mode === 'search' ? translated.searchResultText : translated[page]}\n </MemoizedSubSubBlockHeading>\n\n {(mode === 'search' || page === 'all') && (\n <AppLauncherSortDropdown sortType={sortType} onSelectSortType={setSortType} />\n )}\n </Cluster>\n\n <div className={classNames.scrollArea}>\n <AppLauncherFeatures features={features} page={page} />\n </div>\n </Section>\n </main>\n </div>\n </div>\n )\n}\n\nconst ClearSearchButton = memo<{ onClick: () => void }>(({ onClick }) => (\n <UnstyledButton onClick={onClick}>\n <FaCircleXmarkIcon />\n </UnstyledButton>\n))\n\nconst SideNavs = memo<\n Pick<ReturnType<typeof useAppLauncher>, 'mode' | 'page' | 'changePage'> & {\n translated: { favorite: ReactNode; listText: ReactNode; all: ReactNode; helpText: ReactNode }\n classNames: {\n side: string\n unselectedSideNav: string\n sideNavHeading: string\n selectedSideNav: string\n help: string\n }\n }\n>(({ mode, page, changePage, translated, classNames }) => {\n const isNotSearch = mode !== 'search'\n const isFavorite = isNotSearch && page === 'favorite'\n const isAll = isNotSearch && page === 'all'\n\n const unselectedItems = useMemo(\n () => [\n {\n id: 'favorite',\n title: translated.favorite,\n prefix: <FaStarIcon color={isFavorite ? textColor.white : undefined} />,\n current: isFavorite,\n },\n ],\n [isFavorite, translated],\n )\n const selectedItems = useMemo(\n () => [\n {\n id: 'all',\n title: translated.all,\n current: isAll,\n },\n ],\n [isAll, translated],\n )\n\n const onClick = useCallback(\n (_: any, id: string) => {\n changePage(id as Launcher['page'])\n },\n [changePage],\n )\n\n return (\n <div className={classNames.side}>\n <SideNav\n className={classNames.unselectedSideNav}\n size=\"s\"\n items={unselectedItems}\n onClick={onClick}\n />\n\n <hr />\n\n <Section>\n <MemoizedSubSubBlockHeading className={classNames.sideNavHeading}>\n {translated.listText}\n </MemoizedSubSubBlockHeading>\n <SideNav\n className={classNames.selectedSideNav}\n size=\"s\"\n items={selectedItems}\n onClick={onClick}\n />\n </Section>\n\n <HelpLinkArea className={classNames.help}>{translated.helpText}</HelpLinkArea>\n </div>\n )\n})\n\nconst HelpLinkArea = memo<PropsWithChildren<{ className: string }>>(({ children, className }) => (\n <div className={className}>\n <HelpLink\n href=\"https://support.smarthr.jp/ja/help/articles/2bfd350d-8e8b-4bbd-a209-426d2eb302cc/\"\n target=\"_blank\"\n >\n {children}\n </HelpLink>\n </div>\n))\n\nconst MemoizedSubSubBlockHeading = memo<PropsWithChildren<{ className?: string }>>(\n ({ children, className }) => (\n <Heading type=\"subSubBlockTitle\" className={className}>\n {children}\n </Heading>\n ),\n)\n"],"names":["tv","_jsx","_jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"AppLauncher.js","sources":["../../../../../src/components/AppHeader/components/desktop/AppLauncher.tsx"],"sourcesContent":["import { type FC, type PropsWithChildren, type ReactNode, memo, useCallback, useMemo } from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useIntl } from '../../../../intl'\nimport { textColor } from '../../../../themes'\nimport { UnstyledButton } from '../../../Button'\nimport { Heading } from '../../../Heading'\nimport { FaCircleXmarkIcon, FaStarIcon } from '../../../Icon'\nimport { SearchInput } from '../../../Input'\nimport { Cluster } from '../../../Layout'\nimport { Section } from '../../../SectioningContent'\nimport { SideNav } from '../../../SideNav'\nimport { HelpLink } from '../../../TextLink'\nimport { useAppLauncher } from '../../hooks/useAppLauncher'\nimport { AppLauncherFeatures } from '../common/AppLauncherFeatures'\nimport { AppLauncherSortDropdown } from '../common/AppLauncherSortDropdown'\nimport { Translate } from '../common/Translate'\n\nimport type { Launcher } from '../../types'\n\ntype Props = {\n features: Array<Launcher['feature']>\n}\n\nconst appLauncher = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-AppLauncher',\n 'shr-grid shr-h-[40rem] shr-w-[38rem] shr-grid-rows-[auto_1fr]',\n ],\n searchArea: [\n 'smarthr-ui-AppLauncher-searchArea',\n 'shr-border-b-shorthand shr-p-1',\n '[&_.smarthr-ui-Input]:shr-h-[42px]',\n ],\n inner: ['smarthr-ui-AppLauncher-inner', 'shr-grid shr-min-h-0 shr-grid-cols-[11rem_1fr]'],\n side: [\n 'smarthr-ui-AppLauncher-side',\n 'shr-border-r-shorthand shr-flex shr-flex-col shr-bg-column shr-pb-1 shr-pt-0.5',\n '[&_hr]:shr-m-0.5 [&_hr]:shr-h-[1px] [&_hr]:shr-border-none [&_hr]:shr-bg-border',\n ],\n sideNav: [\n '[&_.smarthr-ui-SideNav-item>button]:shr-px-1 [&_.smarthr-ui-SideNav-item>button]:shr-py-0.75',\n '[&_.smarthr-ui-SideNav-item>button>span]:shr-flex-nowrap',\n '[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-shrink-0 [&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-align-bottom',\n ],\n sideNavHeading: ['shr-px-1 shr-py-0.75 shr-text-xs shr-text-black'],\n help: ['smarthr-ui-AppLauncher-help', 'shr-mt-auto shr-px-1 shr-text-xs'],\n main: ['smarthr-ui-AppLauncher-main', 'shr-grid shr-min-h-0'],\n mainInner: ['shr-grid shr-min-h-0 shr-grid-rows-[auto_1fr]'],\n contentHead: [\n 'shr-min-h-[2rem] shr-px-1 shr-py-0.75',\n '[&_.smarthr-ui-Heading]:shr-text-black',\n ],\n scrollArea: ['shr-h-[509px] shr-overflow-y-scroll'],\n },\n variants: {\n noIcon: {\n true: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button]:shr-pl-1.5'],\n },\n },\n selected: {\n false: {\n sideNav: ['[&_.smarthr-ui-SideNav-item>button_.smarthr-ui-Icon]:shr-text-grey'],\n },\n },\n },\n})\n\nexport const AppLauncher: FC<Props> = ({ features: baseFeatures }) => {\n const {\n features,\n page,\n mode,\n sortType,\n searchQuery,\n changePage,\n setSortType,\n onChangeSearchQuery,\n onClickClearSearchQuery,\n } = useAppLauncher(baseFeatures)\n\n const classNames = useMemo(() => {\n const {\n wrapper,\n searchArea,\n inner,\n side,\n sideNav,\n sideNavHeading,\n help,\n main,\n mainInner,\n contentHead,\n scrollArea,\n } = appLauncher()\n\n return {\n wrapper: wrapper(),\n searchArea: searchArea(),\n inner: inner(),\n side: side(),\n unselectedSideNav: sideNav({ selected: false }),\n selectedSideNav: sideNav({ noIcon: true, selected: true }),\n sideNavHeading: sideNavHeading(),\n help: help(),\n main: main(),\n mainInner: mainInner(),\n contentHead: contentHead(),\n scrollArea: scrollArea(),\n }\n }, [])\n\n const { localize } = useIntl()\n const translated = useMemo<\n Record<\n Launcher['page'] | 'listText' | 'searchInputTitle' | 'helpText' | 'searchResultText',\n ReactNode\n >\n >(\n () => ({\n favorite: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/favoriteModeText',\n defaultText: 'よく使うアプリ',\n })}\n </Translate>\n ),\n all: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/allModeText',\n defaultText: 'すべてのアプリ',\n })}\n </Translate>\n ),\n listText: (\n <Translate>\n {localize({ id: 'smarthr-ui/AppHeader/Launcher/listText', defaultText: 'アプリ一覧' })}\n </Translate>\n ),\n searchInputTitle: localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchInputTitle',\n defaultText: 'アプリ名を入力してください。',\n }),\n helpText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/helpText',\n defaultText: 'よく使うアプリとは',\n })}\n </Translate>\n ),\n searchResultText: (\n <Translate>\n {localize({\n id: 'smarthr-ui/AppHeader/Launcher/searchResultText',\n defaultText: '検索結果',\n })}\n </Translate>\n ),\n }),\n [localize],\n )\n\n return (\n <div className={classNames.wrapper}>\n <div className={classNames.searchArea}>\n <SearchInput\n name=\"search\"\n title={translated.searchInputTitle as string}\n tooltipMessage={<Translate>{translated.searchInputTitle}</Translate>}\n width=\"100%\"\n value={searchQuery}\n suffix={mode === 'search' && <ClearSearchButton onClick={onClickClearSearchQuery} />}\n onChange={onChangeSearchQuery}\n />\n </div>\n\n <div className={classNames.inner}>\n <SideNavs\n mode={mode}\n page={page}\n changePage={changePage}\n translated={translated}\n classNames={classNames}\n />\n <div className={classNames.main}>\n <Section className={classNames.mainInner}>\n <Cluster className={classNames.contentHead} align=\"center\" justify=\"space-between\">\n <MemoizedSubSubBlockHeading>\n {mode === 'search' ? translated.searchResultText : translated[page]}\n </MemoizedSubSubBlockHeading>\n\n {(mode === 'search' || page === 'all') && (\n <AppLauncherSortDropdown sortType={sortType} onSelectSortType={setSortType} />\n )}\n </Cluster>\n\n <div className={classNames.scrollArea}>\n <AppLauncherFeatures features={features} page={page} />\n </div>\n </Section>\n </div>\n </div>\n </div>\n )\n}\n\nconst ClearSearchButton = memo<{ onClick: () => void }>(({ onClick }) => (\n <UnstyledButton onClick={onClick}>\n <FaCircleXmarkIcon />\n </UnstyledButton>\n))\n\nconst SideNavs = memo<\n Pick<ReturnType<typeof useAppLauncher>, 'mode' | 'page' | 'changePage'> & {\n translated: { favorite: ReactNode; listText: ReactNode; all: ReactNode; helpText: ReactNode }\n classNames: {\n side: string\n unselectedSideNav: string\n sideNavHeading: string\n selectedSideNav: string\n help: string\n }\n }\n>(({ mode, page, changePage, translated, classNames }) => {\n const isNotSearch = mode !== 'search'\n const isFavorite = isNotSearch && page === 'favorite'\n const isAll = isNotSearch && page === 'all'\n\n const unselectedItems = useMemo(\n () => [\n {\n id: 'favorite',\n title: translated.favorite,\n prefix: <FaStarIcon color={isFavorite ? textColor.white : undefined} />,\n current: isFavorite,\n },\n ],\n [isFavorite, translated],\n )\n const selectedItems = useMemo(\n () => [\n {\n id: 'all',\n title: translated.all,\n current: isAll,\n },\n ],\n [isAll, translated],\n )\n\n const onClick = useCallback(\n (_: any, id: string) => {\n changePage(id as Launcher['page'])\n },\n [changePage],\n )\n\n return (\n <div className={classNames.side}>\n <SideNav\n className={classNames.unselectedSideNav}\n size=\"s\"\n items={unselectedItems}\n onClick={onClick}\n />\n\n <hr />\n\n <Section>\n <MemoizedSubSubBlockHeading className={classNames.sideNavHeading}>\n {translated.listText}\n </MemoizedSubSubBlockHeading>\n <SideNav\n className={classNames.selectedSideNav}\n size=\"s\"\n items={selectedItems}\n onClick={onClick}\n />\n </Section>\n\n <HelpLinkArea className={classNames.help}>{translated.helpText}</HelpLinkArea>\n </div>\n )\n})\n\nconst HelpLinkArea = memo<PropsWithChildren<{ className: string }>>(({ children, className }) => (\n <div className={className}>\n <HelpLink\n href=\"https://support.smarthr.jp/ja/help/articles/2bfd350d-8e8b-4bbd-a209-426d2eb302cc/\"\n target=\"_blank\"\n >\n {children}\n </HelpLink>\n </div>\n))\n\nconst MemoizedSubSubBlockHeading = memo<PropsWithChildren<{ className?: string }>>(\n ({ children, className }) => (\n <Heading type=\"subSubBlockTitle\" className={className}>\n {children}\n </Heading>\n ),\n)\n"],"names":["tv","_jsx","_jsxs"],"mappings":"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"}
@@ -38,7 +38,7 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
38
38
  const ref = React.useRef(null);
39
39
  const [scale, setScale] = React.useState(1);
40
40
  const [loaded, setLoaded] = React.useState(false);
41
- const [rotation, setRotation] = React.useState(0);
41
+ const [rotation, setRotation] = React.useState(undefined);
42
42
  const [width, setWidth] = React.useState(fixedWidth ?? 0);
43
43
  const internalScaleStep = React.useMemo(() => (scaleStep ? new decimal.Decimal(scaleStep) : defaultScaleStep), [scaleStep]);
44
44
  const scaleUp = React.useCallback(() => {
@@ -49,12 +49,16 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
49
49
  }, [internalScaleStep]);
50
50
  const rotate = React.useCallback(() => {
51
51
  // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う
52
- const newRotation = rotation === 0 ? 270 : rotation - 90;
52
+ const currentRotation = rotation ?? 0;
53
+ const newRotation = currentRotation === 0 ? 270 : currentRotation - 90;
53
54
  setRotation(newRotation);
54
55
  }, [rotation]);
55
56
  const handleLoaded = React.useCallback(() => {
56
57
  setLoaded(true);
57
58
  }, []);
59
+ const handlePDFLoaded = React.useCallback((defaultRotation) => {
60
+ setRotation(defaultRotation);
61
+ }, []);
58
62
  React.useEffect(() => {
59
63
  if (!ref.current || fixedWidth !== undefined) {
60
64
  return;
@@ -67,7 +71,7 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
67
71
  resizeObserver.disconnect();
68
72
  };
69
73
  }, [fixedWidth]);
70
- return (jsxRuntime.jsxs("div", { className: "shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]", ref: ref, children: [jsxRuntime.jsx("div", { className: "shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5", children: jsxRuntime.jsx(Controller, { scale: scale, setScale: setScale, scaleSteps: scaleSteps || defaultScaleSteps, onClickScaleUpButton: scaleUp, onClickScaleDownButton: scaleDown, onClickRotateButton: rotate }) }), jsxRuntime.jsxs("div", { className: "shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2", children: [!loaded && (jsxRuntime.jsx("div", { className: "shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center", children: jsxRuntime.jsx(components_Loader_Loader.Loader, { type: "light", size: "m" }) })), jsxRuntime.jsx("div", { className: !loaded ? 'shr-invisible' : '', children: file.contentType === 'application/pdf' ? (jsxRuntime.jsx(components_FileViewer_PDFViewer.PDFViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onPassword: onPassword, onLoadError: onLoadError })) : file.contentType.startsWith('image/') ? (jsxRuntime.jsx(components_FileViewer_ImageViewer.ImageViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onLoadError: onLoadError })) : (jsxRuntime.jsx(components_Text_Text.Text, { children: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/unsupportedFileText", defaultText: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u5F62\u5F0F\u306E\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002" }) })) })] })] }));
74
+ return (jsxRuntime.jsxs("div", { className: "shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]", ref: ref, children: [jsxRuntime.jsx("div", { className: "shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5", children: jsxRuntime.jsx(Controller, { scale: scale, setScale: setScale, scaleSteps: scaleSteps || defaultScaleSteps, onClickScaleUpButton: scaleUp, onClickScaleDownButton: scaleDown, onClickRotateButton: rotate }) }), jsxRuntime.jsxs("div", { className: "shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2", children: [!loaded && (jsxRuntime.jsx("div", { className: "shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center", children: jsxRuntime.jsx(components_Loader_Loader.Loader, { type: "light", size: "m" }) })), jsxRuntime.jsx("div", { className: !loaded ? 'shr-invisible' : '', children: file.contentType === 'application/pdf' ? (jsxRuntime.jsx(components_FileViewer_PDFViewer.PDFViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onPDFLoaded: handlePDFLoaded, onPassword: onPassword, onLoadError: onLoadError })) : file.contentType.startsWith('image/') ? (jsxRuntime.jsx(components_FileViewer_ImageViewer.ImageViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onLoadError: onLoadError })) : (jsxRuntime.jsx(components_Text_Text.Text, { children: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/unsupportedFileText", defaultText: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u5F62\u5F0F\u306E\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002" }) })) })] })] }));
71
75
  };
72
76
  const Controller = React.memo(({ scale, setScale, scaleSteps, onClickScaleUpButton, onClickScaleDownButton, onClickRotateButton, }) => (jsxRuntime.jsx("div", { className: "shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1", children: jsxRuntime.jsxs(components_Layout_Cluster_Cluster.Cluster, { gap: 0.5, children: [jsxRuntime.jsxs("div", { className: "shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m", children: [jsxRuntime.jsx(components_Button_Button.Button, { onClick: onClickScaleDownButton, disabled: scale <= scaleSteps[0], className: "shr-rounded-r-none shr-border-none", children: jsxRuntime.jsx(components_Icon_FaIcon.FaMagnifyingGlassMinusIcon, { alt: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/scaleDownAlt", defaultText: "\u7E2E\u5C0F" }) }) }), jsxRuntime.jsx(components_Dropdown_DropdownMenuButton_DropdownMenuButton.DropdownMenuButton, { trigger: jsxRuntime.jsxs(components_Text_Text.Text, { children: [jsxRuntime.jsx(components_VisuallyHiddenText_VisuallyHiddenText.VisuallyHiddenText, { children: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/scaleRateLabel", defaultText: "\u62E1\u5927\u7387" }) }), `${(scale * 100).toFixed(0)}%`] }), className: "shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]", children: scaleSteps.map((step) => (jsxRuntime.jsx(components_Button_Button.Button, { onClick: () => setScale(step), className: "shr-rounded-none shr-border-0", children: `${(step * 100).toFixed(0)}%` }, step.toString()))) }), jsxRuntime.jsx(components_Button_Button.Button, { onClick: onClickScaleUpButton, className: "shr-rounded-l-none shr-border-0", children: jsxRuntime.jsx(components_Icon_FaIcon.FaMagnifyingGlassPlusIcon, { alt: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/scaleUpAlt", defaultText: "\u62E1\u5927" }) }) })] }), jsxRuntime.jsx(components_Button_Button.Button, { onClick: onClickRotateButton, className: "shr-p-0.75", children: jsxRuntime.jsx(components_Icon_FaIcon.FaArrowRotateLeftIcon, { alt: jsxRuntime.jsx(intl_Localizer.Localizer, { id: "smarthr-ui/FileViewer/rotateAlt", defaultText: "\u5DE6\u56DE\u8EE2" }) }) })] }) })));
73
77
 
@@ -1 +1 @@
1
- {"version":3,"file":"FileViewer.cjs","sources":["../../../src/components/FileViewer/FileViewer.tsx"],"sourcesContent":["'use client'\n\nimport Decimal from 'decimal.js'\nimport {\n type ComponentProps,\n type FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport {\n Button,\n Cluster,\n DropdownMenuButton,\n FaArrowRotateLeftIcon,\n FaMagnifyingGlassMinusIcon,\n FaMagnifyingGlassPlusIcon,\n Loader,\n Text,\n VisuallyHiddenText,\n} from '../..'\nimport { Localizer } from '../../intl'\n\nimport { ImageViewer } from './ImageViewer'\nimport { PDFViewer } from './PDFViewer'\n\nimport type { FileForViewer } from './types'\n\nconst defaultScaleStep = new Decimal(0.2)\nconst defaultScaleSteps = [0.2, 0.6, 1, 1.6, 2, 3]\n\ntype Props = {\n file: FileForViewer\n width?: number\n\n /*\n * 拡大縮小率のステップを、100%を1とした配列で指定します。\n * */\n scaleSteps?: number[]\n\n scaleStep?: number\n onPassword?: ComponentProps<typeof PDFViewer>['onPassword']\n onLoadError?: () => void\n}\n\nexport const FileViewer: FC<Props> = ({\n file,\n scaleStep,\n scaleSteps,\n width: fixedWidth,\n onPassword,\n onLoadError,\n}) => {\n const ref = useRef<HTMLDivElement>(null)\n const [scale, setScale] = useState(1)\n const [loaded, setLoaded] = useState(false)\n const [rotation, setRotation] = useState(0)\n const [width, setWidth] = useState(fixedWidth ?? 0)\n\n const internalScaleStep = useMemo(\n () => (scaleStep ? new Decimal(scaleStep) : defaultScaleStep),\n [scaleStep],\n )\n\n const scaleUp = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).add(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const scaleDown = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).sub(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const rotate = useCallback(() => {\n // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う\n const newRotation = rotation === 0 ? 270 : rotation - 90\n setRotation(newRotation)\n }, [rotation])\n\n const handleLoaded = useCallback(() => {\n setLoaded(true)\n }, [])\n\n useEffect(() => {\n if (!ref.current || fixedWidth !== undefined) {\n return\n }\n\n const resizeObserver = new ResizeObserver(() => {\n setWidth((ref.current?.clientWidth ?? 0) - 64)\n })\n\n resizeObserver.observe(ref.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [fixedWidth])\n\n return (\n <div\n className=\"shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]\"\n ref={ref}\n >\n <div className=\"shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5\">\n <Controller\n scale={scale}\n setScale={setScale}\n scaleSteps={scaleSteps || defaultScaleSteps}\n onClickScaleUpButton={scaleUp}\n onClickScaleDownButton={scaleDown}\n onClickRotateButton={rotate}\n />\n </div>\n <div className=\"shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2\">\n {!loaded && (\n <div className=\"shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center\">\n <Loader type=\"light\" size=\"m\" />\n </div>\n )}\n <div className={!loaded ? 'shr-invisible' : ''}>\n {file.contentType === 'application/pdf' ? (\n <PDFViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onPassword={onPassword}\n onLoadError={onLoadError}\n />\n ) : file.contentType.startsWith('image/') ? (\n <ImageViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onLoadError={onLoadError}\n />\n ) : (\n <Text>\n <Localizer\n id=\"smarthr-ui/FileViewer/unsupportedFileText\"\n defaultText=\"サポートされていない形式のファイルです。\"\n />\n </Text>\n )}\n </div>\n </div>\n </div>\n )\n}\n\ntype ControllerProps = {\n scale: number\n setScale: (scale: number) => void\n scaleSteps: number[]\n onClickScaleUpButton: () => void\n onClickScaleDownButton: () => void\n onClickRotateButton: () => void\n}\n\nconst Controller: FC<ControllerProps> = memo(\n ({\n scale,\n setScale,\n scaleSteps,\n onClickScaleUpButton,\n onClickScaleDownButton,\n onClickRotateButton,\n }) => (\n <div className=\"shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1\">\n <Cluster gap={0.5}>\n <div className=\"shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m\">\n <Button\n onClick={onClickScaleDownButton}\n disabled={scale <= scaleSteps[0]}\n className=\"shr-rounded-r-none shr-border-none\"\n >\n <FaMagnifyingGlassMinusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleDownAlt\" defaultText=\"縮小\" />}\n />\n </Button>\n <DropdownMenuButton\n trigger={\n <Text>\n <VisuallyHiddenText>\n <Localizer id=\"smarthr-ui/FileViewer/scaleRateLabel\" defaultText=\"拡大率\" />\n </VisuallyHiddenText>\n {`${(scale * 100).toFixed(0)}%`}\n </Text>\n }\n className=\"shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]\"\n >\n {scaleSteps.map((step) => (\n <Button\n key={step.toString()}\n onClick={() => setScale(step)}\n className=\"shr-rounded-none shr-border-0\"\n >\n {`${(step * 100).toFixed(0)}%`}\n </Button>\n ))}\n </DropdownMenuButton>\n <Button onClick={onClickScaleUpButton} className=\"shr-rounded-l-none shr-border-0\">\n <FaMagnifyingGlassPlusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleUpAlt\" defaultText=\"拡大\" />}\n />\n </Button>\n </div>\n <Button onClick={onClickRotateButton} className=\"shr-p-0.75\">\n <FaArrowRotateLeftIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/rotateAlt\" defaultText=\"左回転\" />}\n />\n </Button>\n </Cluster>\n </div>\n ),\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA;AACA;;AAwBE;;;;AAIA;;AAOA;;AAEA;AAEA;;AAEA;AAEA;;AAEE;;AAEF;AAEA;;;;;;;AASE;AACE;AACF;AAEA;AAEA;;AAEA;AACF;;AAuDF;AAWA;;"}
1
+ {"version":3,"file":"FileViewer.cjs","sources":["../../../src/components/FileViewer/FileViewer.tsx"],"sourcesContent":["'use client'\n\nimport Decimal from 'decimal.js'\nimport {\n type ComponentProps,\n type FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport {\n Button,\n Cluster,\n DropdownMenuButton,\n FaArrowRotateLeftIcon,\n FaMagnifyingGlassMinusIcon,\n FaMagnifyingGlassPlusIcon,\n Loader,\n Text,\n VisuallyHiddenText,\n} from '../..'\nimport { Localizer } from '../../intl'\n\nimport { ImageViewer } from './ImageViewer'\nimport { PDFViewer } from './PDFViewer'\n\nimport type { FileForViewer } from './types'\n\nconst defaultScaleStep = new Decimal(0.2)\nconst defaultScaleSteps = [0.2, 0.6, 1, 1.6, 2, 3]\n\ntype Props = {\n file: FileForViewer\n width?: number\n\n /*\n * 拡大縮小率のステップを、100%を1とした配列で指定します。\n * */\n scaleSteps?: number[]\n\n scaleStep?: number\n onPassword?: ComponentProps<typeof PDFViewer>['onPassword']\n onLoadError?: () => void\n}\n\nexport const FileViewer: FC<Props> = ({\n file,\n scaleStep,\n scaleSteps,\n width: fixedWidth,\n onPassword,\n onLoadError,\n}) => {\n const ref = useRef<HTMLDivElement>(null)\n const [scale, setScale] = useState(1)\n const [loaded, setLoaded] = useState(false)\n const [rotation, setRotation] = useState<number | undefined>(undefined)\n const [width, setWidth] = useState(fixedWidth ?? 0)\n\n const internalScaleStep = useMemo(\n () => (scaleStep ? new Decimal(scaleStep) : defaultScaleStep),\n [scaleStep],\n )\n\n const scaleUp = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).add(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const scaleDown = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).sub(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const rotate = useCallback(() => {\n // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う\n const currentRotation = rotation ?? 0\n const newRotation = currentRotation === 0 ? 270 : currentRotation - 90\n setRotation(newRotation)\n }, [rotation])\n\n const handleLoaded = useCallback(() => {\n setLoaded(true)\n }, [])\n\n const handlePDFLoaded = useCallback((defaultRotation: number) => {\n setRotation(defaultRotation)\n }, [])\n\n useEffect(() => {\n if (!ref.current || fixedWidth !== undefined) {\n return\n }\n\n const resizeObserver = new ResizeObserver(() => {\n setWidth((ref.current?.clientWidth ?? 0) - 64)\n })\n\n resizeObserver.observe(ref.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [fixedWidth])\n\n return (\n <div\n className=\"shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]\"\n ref={ref}\n >\n <div className=\"shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5\">\n <Controller\n scale={scale}\n setScale={setScale}\n scaleSteps={scaleSteps || defaultScaleSteps}\n onClickScaleUpButton={scaleUp}\n onClickScaleDownButton={scaleDown}\n onClickRotateButton={rotate}\n />\n </div>\n <div className=\"shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2\">\n {!loaded && (\n <div className=\"shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center\">\n <Loader type=\"light\" size=\"m\" />\n </div>\n )}\n <div className={!loaded ? 'shr-invisible' : ''}>\n {file.contentType === 'application/pdf' ? (\n <PDFViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onPDFLoaded={handlePDFLoaded}\n onPassword={onPassword}\n onLoadError={onLoadError}\n />\n ) : file.contentType.startsWith('image/') ? (\n <ImageViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onLoadError={onLoadError}\n />\n ) : (\n <Text>\n <Localizer\n id=\"smarthr-ui/FileViewer/unsupportedFileText\"\n defaultText=\"サポートされていない形式のファイルです。\"\n />\n </Text>\n )}\n </div>\n </div>\n </div>\n )\n}\n\ntype ControllerProps = {\n scale: number\n setScale: (scale: number) => void\n scaleSteps: number[]\n onClickScaleUpButton: () => void\n onClickScaleDownButton: () => void\n onClickRotateButton: () => void\n}\n\nconst Controller: FC<ControllerProps> = memo(\n ({\n scale,\n setScale,\n scaleSteps,\n onClickScaleUpButton,\n onClickScaleDownButton,\n onClickRotateButton,\n }) => (\n <div className=\"shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1\">\n <Cluster gap={0.5}>\n <div className=\"shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m\">\n <Button\n onClick={onClickScaleDownButton}\n disabled={scale <= scaleSteps[0]}\n className=\"shr-rounded-r-none shr-border-none\"\n >\n <FaMagnifyingGlassMinusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleDownAlt\" defaultText=\"縮小\" />}\n />\n </Button>\n <DropdownMenuButton\n trigger={\n <Text>\n <VisuallyHiddenText>\n <Localizer id=\"smarthr-ui/FileViewer/scaleRateLabel\" defaultText=\"拡大率\" />\n </VisuallyHiddenText>\n {`${(scale * 100).toFixed(0)}%`}\n </Text>\n }\n className=\"shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]\"\n >\n {scaleSteps.map((step) => (\n <Button\n key={step.toString()}\n onClick={() => setScale(step)}\n className=\"shr-rounded-none shr-border-0\"\n >\n {`${(step * 100).toFixed(0)}%`}\n </Button>\n ))}\n </DropdownMenuButton>\n <Button onClick={onClickScaleUpButton} className=\"shr-rounded-l-none shr-border-0\">\n <FaMagnifyingGlassPlusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleUpAlt\" defaultText=\"拡大\" />}\n />\n </Button>\n </div>\n <Button onClick={onClickRotateButton} className=\"shr-p-0.75\">\n <FaArrowRotateLeftIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/rotateAlt\" defaultText=\"左回転\" />}\n />\n </Button>\n </Cluster>\n </div>\n ),\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA;AACA;;AAwBE;;;;AAIA;;AAOA;;AAEA;AAEA;;AAEA;AAEA;;AAEE;AACA;;AAEF;AAEA;;;AAIA;;;;;;;AASE;AACE;AACF;AAEA;AAEA;;AAEA;AACF;;AAwDF;AAWA;;"}
@@ -36,7 +36,7 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
36
36
  const ref = useRef(null);
37
37
  const [scale, setScale] = useState(1);
38
38
  const [loaded, setLoaded] = useState(false);
39
- const [rotation, setRotation] = useState(0);
39
+ const [rotation, setRotation] = useState(undefined);
40
40
  const [width, setWidth] = useState(fixedWidth ?? 0);
41
41
  const internalScaleStep = useMemo(() => (scaleStep ? new Decimal(scaleStep) : defaultScaleStep), [scaleStep]);
42
42
  const scaleUp = useCallback(() => {
@@ -47,12 +47,16 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
47
47
  }, [internalScaleStep]);
48
48
  const rotate = useCallback(() => {
49
49
  // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う
50
- const newRotation = rotation === 0 ? 270 : rotation - 90;
50
+ const currentRotation = rotation ?? 0;
51
+ const newRotation = currentRotation === 0 ? 270 : currentRotation - 90;
51
52
  setRotation(newRotation);
52
53
  }, [rotation]);
53
54
  const handleLoaded = useCallback(() => {
54
55
  setLoaded(true);
55
56
  }, []);
57
+ const handlePDFLoaded = useCallback((defaultRotation) => {
58
+ setRotation(defaultRotation);
59
+ }, []);
56
60
  useEffect(() => {
57
61
  if (!ref.current || fixedWidth !== undefined) {
58
62
  return;
@@ -65,7 +69,7 @@ const FileViewer = ({ file, scaleStep, scaleSteps, width: fixedWidth, onPassword
65
69
  resizeObserver.disconnect();
66
70
  };
67
71
  }, [fixedWidth]);
68
- return (jsxs("div", { className: "shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]", ref: ref, children: [jsx("div", { className: "shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5", children: jsx(Controller, { scale: scale, setScale: setScale, scaleSteps: scaleSteps || defaultScaleSteps, onClickScaleUpButton: scaleUp, onClickScaleDownButton: scaleDown, onClickRotateButton: rotate }) }), jsxs("div", { className: "shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2", children: [!loaded && (jsx("div", { className: "shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center", children: jsx(Loader, { type: "light", size: "m" }) })), jsx("div", { className: !loaded ? 'shr-invisible' : '', children: file.contentType === 'application/pdf' ? (jsx(PDFViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onPassword: onPassword, onLoadError: onLoadError })) : file.contentType.startsWith('image/') ? (jsx(ImageViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onLoadError: onLoadError })) : (jsx(Text, { children: jsx(Localizer, { id: "smarthr-ui/FileViewer/unsupportedFileText", defaultText: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u5F62\u5F0F\u306E\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002" }) })) })] })] }));
72
+ return (jsxs("div", { className: "shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]", ref: ref, children: [jsx("div", { className: "shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5", children: jsx(Controller, { scale: scale, setScale: setScale, scaleSteps: scaleSteps || defaultScaleSteps, onClickScaleUpButton: scaleUp, onClickScaleDownButton: scaleDown, onClickRotateButton: rotate }) }), jsxs("div", { className: "shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2", children: [!loaded && (jsx("div", { className: "shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center", children: jsx(Loader, { type: "light", size: "m" }) })), jsx("div", { className: !loaded ? 'shr-invisible' : '', children: file.contentType === 'application/pdf' ? (jsx(PDFViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onPDFLoaded: handlePDFLoaded, onPassword: onPassword, onLoadError: onLoadError })) : file.contentType.startsWith('image/') ? (jsx(ImageViewer, { scale: scale, rotation: rotation, file: file, width: width, onLoad: handleLoaded, onLoadError: onLoadError })) : (jsx(Text, { children: jsx(Localizer, { id: "smarthr-ui/FileViewer/unsupportedFileText", defaultText: "\u30B5\u30DD\u30FC\u30C8\u3055\u308C\u3066\u3044\u306A\u3044\u5F62\u5F0F\u306E\u30D5\u30A1\u30A4\u30EB\u3067\u3059\u3002" }) })) })] })] }));
69
73
  };
70
74
  const Controller = memo(({ scale, setScale, scaleSteps, onClickScaleUpButton, onClickScaleDownButton, onClickRotateButton, }) => (jsx("div", { className: "shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1", children: jsxs(Cluster, { gap: 0.5, children: [jsxs("div", { className: "shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m", children: [jsx(Button, { onClick: onClickScaleDownButton, disabled: scale <= scaleSteps[0], className: "shr-rounded-r-none shr-border-none", children: jsx(FaMagnifyingGlassMinusIcon, { alt: jsx(Localizer, { id: "smarthr-ui/FileViewer/scaleDownAlt", defaultText: "\u7E2E\u5C0F" }) }) }), jsx(DropdownMenuButton, { trigger: jsxs(Text, { children: [jsx(VisuallyHiddenText, { children: jsx(Localizer, { id: "smarthr-ui/FileViewer/scaleRateLabel", defaultText: "\u62E1\u5927\u7387" }) }), `${(scale * 100).toFixed(0)}%`] }), className: "shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]", children: scaleSteps.map((step) => (jsx(Button, { onClick: () => setScale(step), className: "shr-rounded-none shr-border-0", children: `${(step * 100).toFixed(0)}%` }, step.toString()))) }), jsx(Button, { onClick: onClickScaleUpButton, className: "shr-rounded-l-none shr-border-0", children: jsx(FaMagnifyingGlassPlusIcon, { alt: jsx(Localizer, { id: "smarthr-ui/FileViewer/scaleUpAlt", defaultText: "\u62E1\u5927" }) }) })] }), jsx(Button, { onClick: onClickRotateButton, className: "shr-p-0.75", children: jsx(FaArrowRotateLeftIcon, { alt: jsx(Localizer, { id: "smarthr-ui/FileViewer/rotateAlt", defaultText: "\u5DE6\u56DE\u8EE2" }) }) })] }) })));
71
75
 
@@ -1 +1 @@
1
- {"version":3,"file":"FileViewer.js","sources":["../../../src/components/FileViewer/FileViewer.tsx"],"sourcesContent":["'use client'\n\nimport Decimal from 'decimal.js'\nimport {\n type ComponentProps,\n type FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport {\n Button,\n Cluster,\n DropdownMenuButton,\n FaArrowRotateLeftIcon,\n FaMagnifyingGlassMinusIcon,\n FaMagnifyingGlassPlusIcon,\n Loader,\n Text,\n VisuallyHiddenText,\n} from '../..'\nimport { Localizer } from '../../intl'\n\nimport { ImageViewer } from './ImageViewer'\nimport { PDFViewer } from './PDFViewer'\n\nimport type { FileForViewer } from './types'\n\nconst defaultScaleStep = new Decimal(0.2)\nconst defaultScaleSteps = [0.2, 0.6, 1, 1.6, 2, 3]\n\ntype Props = {\n file: FileForViewer\n width?: number\n\n /*\n * 拡大縮小率のステップを、100%を1とした配列で指定します。\n * */\n scaleSteps?: number[]\n\n scaleStep?: number\n onPassword?: ComponentProps<typeof PDFViewer>['onPassword']\n onLoadError?: () => void\n}\n\nexport const FileViewer: FC<Props> = ({\n file,\n scaleStep,\n scaleSteps,\n width: fixedWidth,\n onPassword,\n onLoadError,\n}) => {\n const ref = useRef<HTMLDivElement>(null)\n const [scale, setScale] = useState(1)\n const [loaded, setLoaded] = useState(false)\n const [rotation, setRotation] = useState(0)\n const [width, setWidth] = useState(fixedWidth ?? 0)\n\n const internalScaleStep = useMemo(\n () => (scaleStep ? new Decimal(scaleStep) : defaultScaleStep),\n [scaleStep],\n )\n\n const scaleUp = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).add(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const scaleDown = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).sub(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const rotate = useCallback(() => {\n // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う\n const newRotation = rotation === 0 ? 270 : rotation - 90\n setRotation(newRotation)\n }, [rotation])\n\n const handleLoaded = useCallback(() => {\n setLoaded(true)\n }, [])\n\n useEffect(() => {\n if (!ref.current || fixedWidth !== undefined) {\n return\n }\n\n const resizeObserver = new ResizeObserver(() => {\n setWidth((ref.current?.clientWidth ?? 0) - 64)\n })\n\n resizeObserver.observe(ref.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [fixedWidth])\n\n return (\n <div\n className=\"shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]\"\n ref={ref}\n >\n <div className=\"shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5\">\n <Controller\n scale={scale}\n setScale={setScale}\n scaleSteps={scaleSteps || defaultScaleSteps}\n onClickScaleUpButton={scaleUp}\n onClickScaleDownButton={scaleDown}\n onClickRotateButton={rotate}\n />\n </div>\n <div className=\"shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2\">\n {!loaded && (\n <div className=\"shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center\">\n <Loader type=\"light\" size=\"m\" />\n </div>\n )}\n <div className={!loaded ? 'shr-invisible' : ''}>\n {file.contentType === 'application/pdf' ? (\n <PDFViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onPassword={onPassword}\n onLoadError={onLoadError}\n />\n ) : file.contentType.startsWith('image/') ? (\n <ImageViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onLoadError={onLoadError}\n />\n ) : (\n <Text>\n <Localizer\n id=\"smarthr-ui/FileViewer/unsupportedFileText\"\n defaultText=\"サポートされていない形式のファイルです。\"\n />\n </Text>\n )}\n </div>\n </div>\n </div>\n )\n}\n\ntype ControllerProps = {\n scale: number\n setScale: (scale: number) => void\n scaleSteps: number[]\n onClickScaleUpButton: () => void\n onClickScaleDownButton: () => void\n onClickRotateButton: () => void\n}\n\nconst Controller: FC<ControllerProps> = memo(\n ({\n scale,\n setScale,\n scaleSteps,\n onClickScaleUpButton,\n onClickScaleDownButton,\n onClickRotateButton,\n }) => (\n <div className=\"shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1\">\n <Cluster gap={0.5}>\n <div className=\"shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m\">\n <Button\n onClick={onClickScaleDownButton}\n disabled={scale <= scaleSteps[0]}\n className=\"shr-rounded-r-none shr-border-none\"\n >\n <FaMagnifyingGlassMinusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleDownAlt\" defaultText=\"縮小\" />}\n />\n </Button>\n <DropdownMenuButton\n trigger={\n <Text>\n <VisuallyHiddenText>\n <Localizer id=\"smarthr-ui/FileViewer/scaleRateLabel\" defaultText=\"拡大率\" />\n </VisuallyHiddenText>\n {`${(scale * 100).toFixed(0)}%`}\n </Text>\n }\n className=\"shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]\"\n >\n {scaleSteps.map((step) => (\n <Button\n key={step.toString()}\n onClick={() => setScale(step)}\n className=\"shr-rounded-none shr-border-0\"\n >\n {`${(step * 100).toFixed(0)}%`}\n </Button>\n ))}\n </DropdownMenuButton>\n <Button onClick={onClickScaleUpButton} className=\"shr-rounded-l-none shr-border-0\">\n <FaMagnifyingGlassPlusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleUpAlt\" defaultText=\"拡大\" />}\n />\n </Button>\n </div>\n <Button onClick={onClickRotateButton} className=\"shr-p-0.75\">\n <FaArrowRotateLeftIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/rotateAlt\" defaultText=\"左回転\" />}\n />\n </Button>\n </Cluster>\n </div>\n ),\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA;AACA;;AAwBE;;;;AAIA;;AAOA;;AAEA;AAEA;;AAEA;AAEA;;AAEE;;AAEF;AAEA;;;;;;;AASE;AACE;AACF;AAEA;AAEA;;AAEA;AACF;;AAuDF;AAWA;;"}
1
+ {"version":3,"file":"FileViewer.js","sources":["../../../src/components/FileViewer/FileViewer.tsx"],"sourcesContent":["'use client'\n\nimport Decimal from 'decimal.js'\nimport {\n type ComponentProps,\n type FC,\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport {\n Button,\n Cluster,\n DropdownMenuButton,\n FaArrowRotateLeftIcon,\n FaMagnifyingGlassMinusIcon,\n FaMagnifyingGlassPlusIcon,\n Loader,\n Text,\n VisuallyHiddenText,\n} from '../..'\nimport { Localizer } from '../../intl'\n\nimport { ImageViewer } from './ImageViewer'\nimport { PDFViewer } from './PDFViewer'\n\nimport type { FileForViewer } from './types'\n\nconst defaultScaleStep = new Decimal(0.2)\nconst defaultScaleSteps = [0.2, 0.6, 1, 1.6, 2, 3]\n\ntype Props = {\n file: FileForViewer\n width?: number\n\n /*\n * 拡大縮小率のステップを、100%を1とした配列で指定します。\n * */\n scaleSteps?: number[]\n\n scaleStep?: number\n onPassword?: ComponentProps<typeof PDFViewer>['onPassword']\n onLoadError?: () => void\n}\n\nexport const FileViewer: FC<Props> = ({\n file,\n scaleStep,\n scaleSteps,\n width: fixedWidth,\n onPassword,\n onLoadError,\n}) => {\n const ref = useRef<HTMLDivElement>(null)\n const [scale, setScale] = useState(1)\n const [loaded, setLoaded] = useState(false)\n const [rotation, setRotation] = useState<number | undefined>(undefined)\n const [width, setWidth] = useState(fixedWidth ?? 0)\n\n const internalScaleStep = useMemo(\n () => (scaleStep ? new Decimal(scaleStep) : defaultScaleStep),\n [scaleStep],\n )\n\n const scaleUp = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).add(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const scaleDown = useCallback(() => {\n setScale((currentScale) => new Decimal(currentScale).sub(internalScaleStep).toNumber())\n }, [internalScaleStep])\n\n const rotate = useCallback(() => {\n // HINT: react-pdf側のAnnotationLayer.cssではマイナスの回転に対応しておらず、また0, 90, 180, 270度のみ対応しているため、-90度の場合は+270度として扱う\n const currentRotation = rotation ?? 0\n const newRotation = currentRotation === 0 ? 270 : currentRotation - 90\n setRotation(newRotation)\n }, [rotation])\n\n const handleLoaded = useCallback(() => {\n setLoaded(true)\n }, [])\n\n const handlePDFLoaded = useCallback((defaultRotation: number) => {\n setRotation(defaultRotation)\n }, [])\n\n useEffect(() => {\n if (!ref.current || fixedWidth !== undefined) {\n return\n }\n\n const resizeObserver = new ResizeObserver(() => {\n setWidth((ref.current?.clientWidth ?? 0) - 64)\n })\n\n resizeObserver.observe(ref.current)\n\n return () => {\n resizeObserver.disconnect()\n }\n }, [fixedWidth])\n\n return (\n <div\n className=\"shr-flex shr-h-full shr-w-full shr-flex-col shr-gap-2 shr-overflow-auto shr-bg-scrim shr-bg-[radial-gradient(theme(textColor.black)_1px,_transparent_0)] shr-bg-[length:16px_16px]\"\n ref={ref}\n >\n <div className=\"shr-sticky shr-start-0 shr-top-0 shr-z-[1] shr-flex shr-w-full shr-flex-shrink-0 shr-gap-0.5\">\n <Controller\n scale={scale}\n setScale={setScale}\n scaleSteps={scaleSteps || defaultScaleSteps}\n onClickScaleUpButton={scaleUp}\n onClickScaleDownButton={scaleDown}\n onClickRotateButton={rotate}\n />\n </div>\n <div className=\"shr-z-[0] shr-mx-auto shr-my-0 shr-box-border shr-flex shr-w-fit shr-flex-shrink-0 shr-grow shr-items-center shr-justify-center shr-px-2 shr-pb-2\">\n {!loaded && (\n <div className=\"shr-pointer-events-none shr-fixed shr-inset-0 shr-flex shr-h-full shr-w-full shr-items-center shr-justify-center\">\n <Loader type=\"light\" size=\"m\" />\n </div>\n )}\n <div className={!loaded ? 'shr-invisible' : ''}>\n {file.contentType === 'application/pdf' ? (\n <PDFViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onPDFLoaded={handlePDFLoaded}\n onPassword={onPassword}\n onLoadError={onLoadError}\n />\n ) : file.contentType.startsWith('image/') ? (\n <ImageViewer\n scale={scale}\n rotation={rotation}\n file={file}\n width={width}\n onLoad={handleLoaded}\n onLoadError={onLoadError}\n />\n ) : (\n <Text>\n <Localizer\n id=\"smarthr-ui/FileViewer/unsupportedFileText\"\n defaultText=\"サポートされていない形式のファイルです。\"\n />\n </Text>\n )}\n </div>\n </div>\n </div>\n )\n}\n\ntype ControllerProps = {\n scale: number\n setScale: (scale: number) => void\n scaleSteps: number[]\n onClickScaleUpButton: () => void\n onClickScaleDownButton: () => void\n onClickRotateButton: () => void\n}\n\nconst Controller: FC<ControllerProps> = memo(\n ({\n scale,\n setScale,\n scaleSteps,\n onClickScaleUpButton,\n onClickScaleDownButton,\n onClickRotateButton,\n }) => (\n <div className=\"shr-sticky shr-flex shr-w-full shr-items-center shr-justify-center shr-justify-items-center shr-gap-0.5 shr-bg-scrim shr-p-0.5 shr-shadow-layer-1\">\n <Cluster gap={0.5}>\n <div className=\"shr-border-shorthand shr-flex shr-divide-x shr-divide-solid shr-overflow-hidden shr-rounded-m\">\n <Button\n onClick={onClickScaleDownButton}\n disabled={scale <= scaleSteps[0]}\n className=\"shr-rounded-r-none shr-border-none\"\n >\n <FaMagnifyingGlassMinusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleDownAlt\" defaultText=\"縮小\" />}\n />\n </Button>\n <DropdownMenuButton\n trigger={\n <Text>\n <VisuallyHiddenText>\n <Localizer id=\"smarthr-ui/FileViewer/scaleRateLabel\" defaultText=\"拡大率\" />\n </VisuallyHiddenText>\n {`${(scale * 100).toFixed(0)}%`}\n </Text>\n }\n className=\"shr-border-y-0 shr-border-[theme(borderColor.default)] [&_.smarthr-ui-Button]:shr-rounded-none [&_.smarthr-ui-Button]:shr-border-[transparent]\"\n >\n {scaleSteps.map((step) => (\n <Button\n key={step.toString()}\n onClick={() => setScale(step)}\n className=\"shr-rounded-none shr-border-0\"\n >\n {`${(step * 100).toFixed(0)}%`}\n </Button>\n ))}\n </DropdownMenuButton>\n <Button onClick={onClickScaleUpButton} className=\"shr-rounded-l-none shr-border-0\">\n <FaMagnifyingGlassPlusIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/scaleUpAlt\" defaultText=\"拡大\" />}\n />\n </Button>\n </div>\n <Button onClick={onClickRotateButton} className=\"shr-p-0.75\">\n <FaArrowRotateLeftIcon\n alt={<Localizer id=\"smarthr-ui/FileViewer/rotateAlt\" defaultText=\"左回転\" />}\n />\n </Button>\n </Cluster>\n </div>\n ),\n)\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA;AACA;;AAwBE;;;;AAIA;;AAOA;;AAEA;AAEA;;AAEA;AAEA;;AAEE;AACA;;AAEF;AAEA;;;AAIA;;;;;;;AASE;AACE;AACF;AAEA;AAEA;;AAEA;AACF;;AAwDF;AAWA;;"}
@@ -19,7 +19,7 @@ const ImageViewer = React.memo(({ scale, rotation, file, width, onLoad, onLoadEr
19
19
  const img = imageRef.current;
20
20
  // 与えられたwidthに対する適切なscaleを算出
21
21
  const viewportScale = (width / img.naturalWidth) * scale;
22
- const rad = (rotation * Math.PI) / 180;
22
+ const rad = ((rotation ?? 0) * Math.PI) / 180;
23
23
  const sin = Math.abs(Math.sin(rad));
24
24
  const cos = Math.abs(Math.cos(rad));
25
25
  // imgをwidth: 100%で表示したときと同等の値を算出
@@ -42,7 +42,7 @@ const ImageViewer = React.memo(({ scale, rotation, file, width, onLoad, onLoadEr
42
42
  width: viewConfig.wrapperWidth,
43
43
  height: viewConfig.wrapperHeight,
44
44
  }, className: "shr-relative shr-h-full shr-w-full", children: jsxRuntime.jsx("img", { className: "shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2", ref: imageRef, src: file.url, alt: file.alt, style: {
45
- rotate: `${rotation}deg`,
45
+ rotate: `${rotation ?? 0}deg`,
46
46
  scale: `${viewConfig.imgScale}`,
47
47
  }, onLoad: handleLoad, onError: onLoadError }) }));
48
48
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ImageViewer.cjs","sources":["../../../src/components/FileViewer/ImageViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, memo, useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { ViewerProps } from './types'\n\nexport const ImageViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onLoadError }) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [viewConfig, setViewConfig] = useState({\n wrapperWidth: 0,\n wrapperHeight: 0,\n imgScale: 1,\n })\n\n // CSSのみではscale, transformの値を親に適用してスクロールするようにできないため、計算している\n const updateViewConfig = useCallback(() => {\n if (!imageRef.current?.complete) {\n return\n }\n\n const img = imageRef.current\n // 与えられたwidthに対する適切なscaleを算出\n const viewportScale = (width / img.naturalWidth) * scale\n\n const rad = (rotation * Math.PI) / 180\n const sin = Math.abs(Math.sin(rad))\n const cos = Math.abs(Math.cos(rad))\n\n // imgをwidth: 100%で表示したときと同等の値を算出\n const scaledWidth = img.naturalWidth * viewportScale\n const scaledHeight = img.naturalHeight * viewportScale\n\n setViewConfig({\n wrapperWidth: scaledWidth * cos + scaledHeight * sin,\n wrapperHeight: scaledWidth * sin + scaledHeight * cos,\n imgScale: viewportScale,\n })\n }, [scale, rotation, width])\n\n const handleLoad = useCallback(() => {\n updateViewConfig()\n onLoad?.()\n }, [updateViewConfig, onLoad])\n\n useEffect(() => {\n updateViewConfig()\n }, [updateViewConfig])\n\n return (\n <div\n style={{\n width: viewConfig.wrapperWidth,\n height: viewConfig.wrapperHeight,\n }}\n className=\"shr-relative shr-h-full shr-w-full\"\n >\n {/* imgのload完了時にupdateViewConfigを呼び出さないと適切なサイズが取得できないため */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <img\n className=\"shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2\"\n ref={imageRef}\n src={file.url}\n alt={file.alt}\n style={{\n rotate: `${rotation}deg`,\n scale: `${viewConfig.imgScale}`,\n }}\n onLoad={handleLoad}\n onError={onLoadError}\n />\n </div>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;AAQI;AACA;AACE;AACA;AACA;AACD;;AAGD;AACE;;;AAIA;;;;AAKA;AACA;;AAGA;AACA;AAEA;AACE;AACA;AACA;AACD;;AAGH;AACE;;AAEF;;AAGE;AACF;;;;;;AAmBQ;;AAOV;;"}
1
+ {"version":3,"file":"ImageViewer.cjs","sources":["../../../src/components/FileViewer/ImageViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, memo, useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { ViewerProps } from './types'\n\nexport const ImageViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onLoadError }) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [viewConfig, setViewConfig] = useState({\n wrapperWidth: 0,\n wrapperHeight: 0,\n imgScale: 1,\n })\n\n // CSSのみではscale, transformの値を親に適用してスクロールするようにできないため、計算している\n const updateViewConfig = useCallback(() => {\n if (!imageRef.current?.complete) {\n return\n }\n\n const img = imageRef.current\n // 与えられたwidthに対する適切なscaleを算出\n const viewportScale = (width / img.naturalWidth) * scale\n\n const rad = ((rotation ?? 0) * Math.PI) / 180\n const sin = Math.abs(Math.sin(rad))\n const cos = Math.abs(Math.cos(rad))\n\n // imgをwidth: 100%で表示したときと同等の値を算出\n const scaledWidth = img.naturalWidth * viewportScale\n const scaledHeight = img.naturalHeight * viewportScale\n\n setViewConfig({\n wrapperWidth: scaledWidth * cos + scaledHeight * sin,\n wrapperHeight: scaledWidth * sin + scaledHeight * cos,\n imgScale: viewportScale,\n })\n }, [scale, rotation, width])\n\n const handleLoad = useCallback(() => {\n updateViewConfig()\n onLoad?.()\n }, [updateViewConfig, onLoad])\n\n useEffect(() => {\n updateViewConfig()\n }, [updateViewConfig])\n\n return (\n <div\n style={{\n width: viewConfig.wrapperWidth,\n height: viewConfig.wrapperHeight,\n }}\n className=\"shr-relative shr-h-full shr-w-full\"\n >\n {/* imgのload完了時にupdateViewConfigを呼び出さないと適切なサイズが取得できないため */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <img\n className=\"shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2\"\n ref={imageRef}\n src={file.url}\n alt={file.alt}\n style={{\n rotate: `${rotation ?? 0}deg`,\n scale: `${viewConfig.imgScale}`,\n }}\n onLoad={handleLoad}\n onError={onLoadError}\n />\n </div>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;AAQI;AACA;AACE;AACA;AACA;AACD;;AAGD;AACE;;;AAIA;;;AAIA;AACA;AACA;;AAGA;AACA;AAEA;AACE;AACA;AACA;AACD;;AAGH;AACE;;AAEF;;AAGE;AACF;;;;;AAkBQ;AACA;;AAOV;;"}
@@ -17,7 +17,7 @@ const ImageViewer = memo(({ scale, rotation, file, width, onLoad, onLoadError })
17
17
  const img = imageRef.current;
18
18
  // 与えられたwidthに対する適切なscaleを算出
19
19
  const viewportScale = (width / img.naturalWidth) * scale;
20
- const rad = (rotation * Math.PI) / 180;
20
+ const rad = ((rotation ?? 0) * Math.PI) / 180;
21
21
  const sin = Math.abs(Math.sin(rad));
22
22
  const cos = Math.abs(Math.cos(rad));
23
23
  // imgをwidth: 100%で表示したときと同等の値を算出
@@ -40,7 +40,7 @@ const ImageViewer = memo(({ scale, rotation, file, width, onLoad, onLoadError })
40
40
  width: viewConfig.wrapperWidth,
41
41
  height: viewConfig.wrapperHeight,
42
42
  }, className: "shr-relative shr-h-full shr-w-full", children: jsx("img", { className: "shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2", ref: imageRef, src: file.url, alt: file.alt, style: {
43
- rotate: `${rotation}deg`,
43
+ rotate: `${rotation ?? 0}deg`,
44
44
  scale: `${viewConfig.imgScale}`,
45
45
  }, onLoad: handleLoad, onError: onLoadError }) }));
46
46
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ImageViewer.js","sources":["../../../src/components/FileViewer/ImageViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, memo, useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { ViewerProps } from './types'\n\nexport const ImageViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onLoadError }) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [viewConfig, setViewConfig] = useState({\n wrapperWidth: 0,\n wrapperHeight: 0,\n imgScale: 1,\n })\n\n // CSSのみではscale, transformの値を親に適用してスクロールするようにできないため、計算している\n const updateViewConfig = useCallback(() => {\n if (!imageRef.current?.complete) {\n return\n }\n\n const img = imageRef.current\n // 与えられたwidthに対する適切なscaleを算出\n const viewportScale = (width / img.naturalWidth) * scale\n\n const rad = (rotation * Math.PI) / 180\n const sin = Math.abs(Math.sin(rad))\n const cos = Math.abs(Math.cos(rad))\n\n // imgをwidth: 100%で表示したときと同等の値を算出\n const scaledWidth = img.naturalWidth * viewportScale\n const scaledHeight = img.naturalHeight * viewportScale\n\n setViewConfig({\n wrapperWidth: scaledWidth * cos + scaledHeight * sin,\n wrapperHeight: scaledWidth * sin + scaledHeight * cos,\n imgScale: viewportScale,\n })\n }, [scale, rotation, width])\n\n const handleLoad = useCallback(() => {\n updateViewConfig()\n onLoad?.()\n }, [updateViewConfig, onLoad])\n\n useEffect(() => {\n updateViewConfig()\n }, [updateViewConfig])\n\n return (\n <div\n style={{\n width: viewConfig.wrapperWidth,\n height: viewConfig.wrapperHeight,\n }}\n className=\"shr-relative shr-h-full shr-w-full\"\n >\n {/* imgのload完了時にupdateViewConfigを呼び出さないと適切なサイズが取得できないため */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <img\n className=\"shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2\"\n ref={imageRef}\n src={file.url}\n alt={file.alt}\n style={{\n rotate: `${rotation}deg`,\n scale: `${viewConfig.imgScale}`,\n }}\n onLoad={handleLoad}\n onError={onLoadError}\n />\n </div>\n )\n },\n)\n"],"names":[],"mappings":";;;;;AAQI;AACA;AACE;AACA;AACA;AACD;;AAGD;AACE;;;AAIA;;;;AAKA;AACA;;AAGA;AACA;AAEA;AACE;AACA;AACA;AACD;;AAGH;AACE;;AAEF;;AAGE;AACF;;;;;;AAmBQ;;AAOV;;"}
1
+ {"version":3,"file":"ImageViewer.js","sources":["../../../src/components/FileViewer/ImageViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type FC, memo, useCallback, useEffect, useRef, useState } from 'react'\n\nimport type { ViewerProps } from './types'\n\nexport const ImageViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onLoadError }) => {\n const imageRef = useRef<HTMLImageElement>(null)\n const [viewConfig, setViewConfig] = useState({\n wrapperWidth: 0,\n wrapperHeight: 0,\n imgScale: 1,\n })\n\n // CSSのみではscale, transformの値を親に適用してスクロールするようにできないため、計算している\n const updateViewConfig = useCallback(() => {\n if (!imageRef.current?.complete) {\n return\n }\n\n const img = imageRef.current\n // 与えられたwidthに対する適切なscaleを算出\n const viewportScale = (width / img.naturalWidth) * scale\n\n const rad = ((rotation ?? 0) * Math.PI) / 180\n const sin = Math.abs(Math.sin(rad))\n const cos = Math.abs(Math.cos(rad))\n\n // imgをwidth: 100%で表示したときと同等の値を算出\n const scaledWidth = img.naturalWidth * viewportScale\n const scaledHeight = img.naturalHeight * viewportScale\n\n setViewConfig({\n wrapperWidth: scaledWidth * cos + scaledHeight * sin,\n wrapperHeight: scaledWidth * sin + scaledHeight * cos,\n imgScale: viewportScale,\n })\n }, [scale, rotation, width])\n\n const handleLoad = useCallback(() => {\n updateViewConfig()\n onLoad?.()\n }, [updateViewConfig, onLoad])\n\n useEffect(() => {\n updateViewConfig()\n }, [updateViewConfig])\n\n return (\n <div\n style={{\n width: viewConfig.wrapperWidth,\n height: viewConfig.wrapperHeight,\n }}\n className=\"shr-relative shr-h-full shr-w-full\"\n >\n {/* imgのload完了時にupdateViewConfigを呼び出さないと適切なサイズが取得できないため */}\n {/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}\n <img\n className=\"shr-absolute shr-left-[50%] shr-top-[50%] shr-origin-top-left -shr-translate-x-1/2 -shr-translate-y-1/2\"\n ref={imageRef}\n src={file.url}\n alt={file.alt}\n style={{\n rotate: `${rotation ?? 0}deg`,\n scale: `${viewConfig.imgScale}`,\n }}\n onLoad={handleLoad}\n onError={onLoadError}\n />\n </div>\n )\n },\n)\n"],"names":[],"mappings":";;;;;AAQI;AACA;AACE;AACA;AACA;AACD;;AAGD;AACE;;;AAIA;;;AAIA;AACA;AACA;;AAGA;AACA;AAEA;AACE;AACA;AACA;AACD;;AAGH;AACE;;AAEF;;AAGE;AACF;;;;;AAkBQ;AACA;;AAOV;;"}
@@ -41,22 +41,25 @@ const options = {
41
41
  // cMapUrl: '/cmaps/',
42
42
  cMapUrl: `//unpkg.com/pdfjs-dist@${pdf.version}/cmaps/`,
43
43
  };
44
- const PDFViewer = React.memo(({ scale, rotation, file, width, onLoad, onPassword, onLoadError }) => {
44
+ const PDFViewer = React.memo(({ scale, rotation, file, width, onLoad, onPDFLoaded, onPassword, onLoadError }) => {
45
45
  const [pdfNumPages, setPdfNumPages] = React.useState(1);
46
46
  const onDocumentLoadSuccess = React.useCallback(({ numPages }) => {
47
47
  setPdfNumPages(numPages);
48
48
  }, []);
49
49
  const onPageLoad = React.useMemo(() => {
50
- if (!onLoad) {
50
+ if (!onLoad && !onPDFLoaded) {
51
51
  return undefined;
52
52
  }
53
53
  return (page) => {
54
+ if (onPDFLoaded && rotation === undefined) {
55
+ onPDFLoaded(page.rotate);
56
+ }
54
57
  // DocumentのLoadだとページごとの読み込みが考慮されないため
55
- if (page.pageNumber === pdfNumPages) {
58
+ if (onLoad && page.pageNumber === pdfNumPages) {
56
59
  onLoad();
57
60
  }
58
61
  };
59
- }, [pdfNumPages, onLoad]);
62
+ }, [onLoad, onPDFLoaded, pdfNumPages, rotation]);
60
63
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(components_FileViewer_generatedReactPDFStyle.ReactPDFStyle, {}), jsxRuntime.jsx(Document, { options: options, file: file.url, onLoadSuccess: onDocumentLoadSuccess, onLoadError: onLoadError, rotate: rotation, className: "shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto", externalLinkTarget: "_blank", loading: null, onPassword: onPassword, children: Array.from({ length: pdfNumPages }).map((_, i) => (jsxRuntime.jsx(Page, { pageNumber: i + 1, width: width, scale: scale, className: "shr-w-full", onLoadSuccess: onPageLoad, loading: null }, `page_${i}`))) })] }));
61
64
  });
62
65
 
@@ -1 +1 @@
1
- {"version":3,"file":"PDFViewer.cjs","sources":["../../../src/components/FileViewer/PDFViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, memo, useCallback, useMemo, useState } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\n\nimport { ReactPDFStyle } from './generatedReactPDFStyle'\n\nimport type { ViewerProps } from './types'\n\nif (typeof window !== 'undefined') {\n // iOS 17.3以下ではPromise.withResolversが未定義のため、polyfillを適用する\n // @ts-expect-error\n if (typeof window.Promise.withResolvers === 'undefined') {\n // @ts-expect-error\n window.Promise.withResolvers = function () {\n let resolve, reject\n const promise = new Promise((res, rej) => {\n resolve = res\n reject = rej\n })\n return { promise, resolve, reject }\n }\n // web workerもpolyfillされたものを読み込む\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`\n } else {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // pdfjs.GlobalWorkerOptions.workerSrc = new URL(\n // 'pdfjs-dist/build/pdf.worker.min.mjs',\n // import.meta.url,\n // ).toString()\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n }\n}\n\nconst options = {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // 非latin文字を読み込むためのオプション\n // 参考: https://github.com/wojtekmaj/react-pdf?tab=readme-ov-file#support-for-non-latin-characters\n // cMapUrl: '/cmaps/',\n cMapUrl: `//unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,\n} satisfies ComponentProps<typeof Document>['options']\n\nexport const PDFViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onPassword, onLoadError }) => {\n const [pdfNumPages, setPdfNumPages] = useState(1)\n\n const onDocumentLoadSuccess = useCallback<\n NonNullable<ComponentProps<typeof Document>['onLoadSuccess']>\n >(({ numPages }) => {\n setPdfNumPages(numPages)\n }, [])\n\n const onPageLoad: ComponentProps<typeof Page>['onLoadSuccess'] = useMemo(() => {\n if (!onLoad) {\n return undefined\n }\n\n return (page) => {\n // DocumentのLoadだとページごとの読み込みが考慮されないため\n if (page.pageNumber === pdfNumPages) {\n onLoad()\n }\n }\n }, [pdfNumPages, onLoad])\n\n return (\n <>\n {/* TODO: 外部CSSをsmarthr-uiから読み込んでもらえるようにする機構ができたら消す */}\n <ReactPDFStyle />\n <Document\n options={options}\n file={file.url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onLoadError}\n rotate={rotation}\n className=\"shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto\"\n externalLinkTarget=\"_blank\"\n loading={null}\n onPassword={onPassword}\n >\n {Array.from({ length: pdfNumPages }).map((_, i) => (\n <Page\n key={`page_${i}`}\n pageNumber={i + 1}\n width={width}\n scale={scale}\n className=\"shr-w-full\"\n onLoadSuccess={onPageLoad}\n loading={null}\n />\n ))}\n </Document>\n </>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;AASA;;;;;AAKI;;;;;AAKE;AACA;AACF;;;;;;;;;;;;AAWJ;AAEA;;;;;AAKE;;;;;;;AAaE;;AAEI;;;;AAKA;AACE;;AAEJ;AACF;;AA+BF;;"}
1
+ {"version":3,"file":"PDFViewer.cjs","sources":["../../../src/components/FileViewer/PDFViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, memo, useCallback, useMemo, useState } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\n\nimport { ReactPDFStyle } from './generatedReactPDFStyle'\n\nimport type { ViewerProps } from './types'\n\nif (typeof window !== 'undefined') {\n // iOS 17.3以下ではPromise.withResolversが未定義のため、polyfillを適用する\n // @ts-expect-error\n if (typeof window.Promise.withResolvers === 'undefined') {\n // @ts-expect-error\n window.Promise.withResolvers = function () {\n let resolve, reject\n const promise = new Promise((res, rej) => {\n resolve = res\n reject = rej\n })\n return { promise, resolve, reject }\n }\n // web workerもpolyfillされたものを読み込む\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`\n } else {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // pdfjs.GlobalWorkerOptions.workerSrc = new URL(\n // 'pdfjs-dist/build/pdf.worker.min.mjs',\n // import.meta.url,\n // ).toString()\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n }\n}\n\nconst options = {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // 非latin文字を読み込むためのオプション\n // 参考: https://github.com/wojtekmaj/react-pdf?tab=readme-ov-file#support-for-non-latin-characters\n // cMapUrl: '/cmaps/',\n cMapUrl: `//unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,\n} satisfies ComponentProps<typeof Document>['options']\n\nexport const PDFViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onPDFLoaded, onPassword, onLoadError }) => {\n const [pdfNumPages, setPdfNumPages] = useState(1)\n\n const onDocumentLoadSuccess = useCallback<\n NonNullable<ComponentProps<typeof Document>['onLoadSuccess']>\n >(({ numPages }) => {\n setPdfNumPages(numPages)\n }, [])\n\n const onPageLoad: ComponentProps<typeof Page>['onLoadSuccess'] = useMemo(() => {\n if (!onLoad && !onPDFLoaded) {\n return undefined\n }\n\n return (page) => {\n if (onPDFLoaded && rotation === undefined) {\n onPDFLoaded(page.rotate)\n }\n // DocumentのLoadだとページごとの読み込みが考慮されないため\n if (onLoad && page.pageNumber === pdfNumPages) {\n onLoad()\n }\n }\n }, [onLoad, onPDFLoaded, pdfNumPages, rotation])\n\n return (\n <>\n {/* TODO: 外部CSSをsmarthr-uiから読み込んでもらえるようにする機構ができたら消す */}\n <ReactPDFStyle />\n <Document\n options={options}\n file={file.url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onLoadError}\n rotate={rotation}\n className=\"shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto\"\n externalLinkTarget=\"_blank\"\n loading={null}\n onPassword={onPassword}\n >\n {Array.from({ length: pdfNumPages }).map((_, i) => (\n <Page\n key={`page_${i}`}\n pageNumber={i + 1}\n width={width}\n scale={scale}\n className=\"shr-w-full\"\n onLoadSuccess={onPageLoad}\n loading={null}\n />\n ))}\n </Document>\n </>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;;;AASA;;;;;AAKI;;;;;AAKE;AACA;AACF;;;;;;;;;;;;AAWJ;AAEA;;;;;AAKE;;AAGK;;;;;AAUH;AACE;AACE;;;AAIA;AACE;;;;AAIA;;AAEJ;;;AAgCJ;;"}
@@ -39,22 +39,25 @@ const options = {
39
39
  // cMapUrl: '/cmaps/',
40
40
  cMapUrl: `//unpkg.com/pdfjs-dist@${__webpack_exports__version}/cmaps/`,
41
41
  };
42
- const PDFViewer = memo(({ scale, rotation, file, width, onLoad, onPassword, onLoadError }) => {
42
+ const PDFViewer = memo(({ scale, rotation, file, width, onLoad, onPDFLoaded, onPassword, onLoadError }) => {
43
43
  const [pdfNumPages, setPdfNumPages] = useState(1);
44
44
  const onDocumentLoadSuccess = useCallback(({ numPages }) => {
45
45
  setPdfNumPages(numPages);
46
46
  }, []);
47
47
  const onPageLoad = useMemo(() => {
48
- if (!onLoad) {
48
+ if (!onLoad && !onPDFLoaded) {
49
49
  return undefined;
50
50
  }
51
51
  return (page) => {
52
+ if (onPDFLoaded && rotation === undefined) {
53
+ onPDFLoaded(page.rotate);
54
+ }
52
55
  // DocumentのLoadだとページごとの読み込みが考慮されないため
53
- if (page.pageNumber === pdfNumPages) {
56
+ if (onLoad && page.pageNumber === pdfNumPages) {
54
57
  onLoad();
55
58
  }
56
59
  };
57
- }, [pdfNumPages, onLoad]);
60
+ }, [onLoad, onPDFLoaded, pdfNumPages, rotation]);
58
61
  return (jsxs(Fragment, { children: [jsx(ReactPDFStyle, {}), jsx(Document, { options: options, file: file.url, onLoadSuccess: onDocumentLoadSuccess, onLoadError: onLoadError, rotate: rotation, className: "shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto", externalLinkTarget: "_blank", loading: null, onPassword: onPassword, children: Array.from({ length: pdfNumPages }).map((_, i) => (jsx(Page, { pageNumber: i + 1, width: width, scale: scale, className: "shr-w-full", onLoadSuccess: onPageLoad, loading: null }, `page_${i}`))) })] }));
59
62
  });
60
63
 
@@ -1 +1 @@
1
- {"version":3,"file":"PDFViewer.js","sources":["../../../src/components/FileViewer/PDFViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, memo, useCallback, useMemo, useState } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\n\nimport { ReactPDFStyle } from './generatedReactPDFStyle'\n\nimport type { ViewerProps } from './types'\n\nif (typeof window !== 'undefined') {\n // iOS 17.3以下ではPromise.withResolversが未定義のため、polyfillを適用する\n // @ts-expect-error\n if (typeof window.Promise.withResolvers === 'undefined') {\n // @ts-expect-error\n window.Promise.withResolvers = function () {\n let resolve, reject\n const promise = new Promise((res, rej) => {\n resolve = res\n reject = rej\n })\n return { promise, resolve, reject }\n }\n // web workerもpolyfillされたものを読み込む\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`\n } else {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // pdfjs.GlobalWorkerOptions.workerSrc = new URL(\n // 'pdfjs-dist/build/pdf.worker.min.mjs',\n // import.meta.url,\n // ).toString()\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n }\n}\n\nconst options = {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // 非latin文字を読み込むためのオプション\n // 参考: https://github.com/wojtekmaj/react-pdf?tab=readme-ov-file#support-for-non-latin-characters\n // cMapUrl: '/cmaps/',\n cMapUrl: `//unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,\n} satisfies ComponentProps<typeof Document>['options']\n\nexport const PDFViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onPassword, onLoadError }) => {\n const [pdfNumPages, setPdfNumPages] = useState(1)\n\n const onDocumentLoadSuccess = useCallback<\n NonNullable<ComponentProps<typeof Document>['onLoadSuccess']>\n >(({ numPages }) => {\n setPdfNumPages(numPages)\n }, [])\n\n const onPageLoad: ComponentProps<typeof Page>['onLoadSuccess'] = useMemo(() => {\n if (!onLoad) {\n return undefined\n }\n\n return (page) => {\n // DocumentのLoadだとページごとの読み込みが考慮されないため\n if (page.pageNumber === pdfNumPages) {\n onLoad()\n }\n }\n }, [pdfNumPages, onLoad])\n\n return (\n <>\n {/* TODO: 外部CSSをsmarthr-uiから読み込んでもらえるようにする機構ができたら消す */}\n <ReactPDFStyle />\n <Document\n options={options}\n file={file.url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onLoadError}\n rotate={rotation}\n className=\"shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto\"\n externalLinkTarget=\"_blank\"\n loading={null}\n onPassword={onPassword}\n >\n {Array.from({ length: pdfNumPages }).map((_, i) => (\n <Page\n key={`page_${i}`}\n pageNumber={i + 1}\n width={width}\n scale={scale}\n className=\"shr-w-full\"\n onLoadSuccess={onPageLoad}\n loading={null}\n />\n ))}\n </Document>\n </>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;AASA;;;;;AAKI;;;;;AAKE;AACA;AACF;;;;;;;;;;;;AAWJ;AAEA;;;;;AAKE;;;;;;;AAaE;;AAEI;;;;AAKA;AACE;;AAEJ;AACF;;AA+BF;;"}
1
+ {"version":3,"file":"PDFViewer.js","sources":["../../../src/components/FileViewer/PDFViewer.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, type FC, memo, useCallback, useMemo, useState } from 'react'\nimport { Document, Page, pdfjs } from 'react-pdf'\n\nimport { ReactPDFStyle } from './generatedReactPDFStyle'\n\nimport type { ViewerProps } from './types'\n\nif (typeof window !== 'undefined') {\n // iOS 17.3以下ではPromise.withResolversが未定義のため、polyfillを適用する\n // @ts-expect-error\n if (typeof window.Promise.withResolvers === 'undefined') {\n // @ts-expect-error\n window.Promise.withResolvers = function () {\n let resolve, reject\n const promise = new Promise((res, rej) => {\n resolve = res\n reject = rej\n })\n return { promise, resolve, reject }\n }\n // web workerもpolyfillされたものを読み込む\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.mjs`\n } else {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // pdfjs.GlobalWorkerOptions.workerSrc = new URL(\n // 'pdfjs-dist/build/pdf.worker.min.mjs',\n // import.meta.url,\n // ).toString()\n pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`\n }\n}\n\nconst options = {\n // TODO: バンドラの関係でCDNから読み込んでいるが、smarthr-uiから配信するようにしたい\n // 非latin文字を読み込むためのオプション\n // 参考: https://github.com/wojtekmaj/react-pdf?tab=readme-ov-file#support-for-non-latin-characters\n // cMapUrl: '/cmaps/',\n cMapUrl: `//unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,\n} satisfies ComponentProps<typeof Document>['options']\n\nexport const PDFViewer: FC<ViewerProps> = memo(\n ({ scale, rotation, file, width, onLoad, onPDFLoaded, onPassword, onLoadError }) => {\n const [pdfNumPages, setPdfNumPages] = useState(1)\n\n const onDocumentLoadSuccess = useCallback<\n NonNullable<ComponentProps<typeof Document>['onLoadSuccess']>\n >(({ numPages }) => {\n setPdfNumPages(numPages)\n }, [])\n\n const onPageLoad: ComponentProps<typeof Page>['onLoadSuccess'] = useMemo(() => {\n if (!onLoad && !onPDFLoaded) {\n return undefined\n }\n\n return (page) => {\n if (onPDFLoaded && rotation === undefined) {\n onPDFLoaded(page.rotate)\n }\n // DocumentのLoadだとページごとの読み込みが考慮されないため\n if (onLoad && page.pageNumber === pdfNumPages) {\n onLoad()\n }\n }\n }, [onLoad, onPDFLoaded, pdfNumPages, rotation])\n\n return (\n <>\n {/* TODO: 外部CSSをsmarthr-uiから読み込んでもらえるようにする機構ができたら消す */}\n <ReactPDFStyle />\n <Document\n options={options}\n file={file.url}\n onLoadSuccess={onDocumentLoadSuccess}\n onLoadError={onLoadError}\n rotate={rotation}\n className=\"shr-flex shr-h-full shr-w-fit shr-flex-col shr-items-center shr-gap-1 shr-overflow-auto\"\n externalLinkTarget=\"_blank\"\n loading={null}\n onPassword={onPassword}\n >\n {Array.from({ length: pdfNumPages }).map((_, i) => (\n <Page\n key={`page_${i}`}\n pageNumber={i + 1}\n width={width}\n scale={scale}\n className=\"shr-w-full\"\n onLoadSuccess={onPageLoad}\n loading={null}\n />\n ))}\n </Document>\n </>\n )\n },\n)\n"],"names":[],"mappings":";;;;;;;;;AASA;;;;;AAKI;;;;;AAKE;AACA;AACF;;;;;;;;;;;;AAWJ;AAEA;;;;;AAKE;;AAGK;;;;;AAUH;AACE;AACE;;;AAIA;AACE;;;;AAIA;;AAEJ;;;AAgCJ;;"}
@@ -8,9 +8,10 @@ export type FileForViewer = {
8
8
  export type ViewerProps = {
9
9
  file: FileForViewer;
10
10
  scale: number;
11
- rotation: number;
11
+ rotation: number | undefined;
12
12
  width: number;
13
13
  onLoad: () => void;
14
+ onPDFLoaded?: (defaultRotation: number) => void;
14
15
  /**
15
16
  * PDFファイルのパスワード入力を要求されたときに呼ばれるコールバック関数。PdfViewerでのみ使用されます。
16
17
  */
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
3
4
  var jsxRuntime = require('react/jsx-runtime');