-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin' into feat/multilingualization
- Loading branch information
Showing
80 changed files
with
4,206 additions
and
335 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import smarthr from 'eslint-config-smarthr' | ||
import storybook from 'eslint-plugin-storybook' | ||
|
||
/** | ||
* @type {import('eslint').Linter.Config[]} | ||
*/ | ||
export default [ | ||
...smarthr, | ||
...storybook.configs['flat/recommended'], | ||
{ | ||
rules: { | ||
'jsx-a11y/anchor-is-valid': 'warn', | ||
'jsx-a11y/click-events-have-key-events': 'warn', | ||
'jsx-a11y/no-static-element-interactions': 'warn', | ||
'jsx-a11y/label-has-associated-control': [ | ||
'error', | ||
{ | ||
controlComponents: ['Input', 'InputWithTooltip'], | ||
}, | ||
], | ||
'@typescript-eslint/consistent-type-definitions': [ | ||
'error', | ||
'type', | ||
], | ||
'smarthr/require-barrel-import': 'off', | ||
'smarthr/a11y-anchor-has-href-attribute': [ | ||
'error', | ||
{ | ||
checkType: 'allow-spread-attributes', | ||
} | ||
], | ||
'smarthr/a11y-input-has-name-attribute': [ | ||
'error', | ||
{ | ||
checkType: 'allow-spread-attributes', | ||
} | ||
], | ||
}, | ||
}, | ||
{ | ||
ignores: [ | ||
'**/*.{mjs,js}', | ||
'sandbox/', | ||
'storybook-static/', | ||
'packages/smarthr-ui/esm/', | ||
'packages/smarthr-ui/lib/', | ||
'packages/smarthr-ui/.storybook', | ||
] | ||
}, | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
24 changes: 24 additions & 0 deletions
24
packages/smarthr-ui/src/components/AppHeader/AppHeader.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
'use client' | ||
|
||
import React, { FC } from 'react' | ||
|
||
import { DesktopHeader } from './components/desktop/DesktopHeader' | ||
import { MobileHeader } from './components/mobile/MobileHeader' | ||
import { LocaleContextProvider } from './hooks/useLocale' | ||
import { mediaQuery, useMediaQuery } from './hooks/useMediaQuery' | ||
import { HeaderProps } from './types' | ||
|
||
export const AppHeader: FC<HeaderProps> = ({ locale, children, ...props }) => { | ||
// NOTE: ヘッダーの出し分けは CSS によって行われているので、useMediaQuery による children の出し分けは本来不要ですが、 | ||
// wovn の言語切替カスタム UI の挿入対象となる DOM ("wovn-embedded-widget-anchor" クラスを持った div) が複数描画されていると、 | ||
// wovn のスクリプトの仕様上1つ目の DOM にしか UI が挿入されないため、やむを得ず children のみ React のレンダリングレベルでの出し分けをしています。 | ||
const isDesktop = useMediaQuery(mediaQuery.desktop) | ||
const isMobile = useMediaQuery(mediaQuery.mobile) | ||
|
||
return ( | ||
<LocaleContextProvider locale={locale}> | ||
<DesktopHeader {...props}>{isDesktop && children}</DesktopHeader> | ||
<MobileHeader {...props}>{isMobile && children}</MobileHeader> | ||
</LocaleContextProvider> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
## このコンポーネントについて | ||
|
||
props を埋めていくだけで良い感じに共通のヘッダー/ナビゲーションの UI が組み立てられるコンポーネントです。 | ||
|
||
## どのように使うのか | ||
|
||
`types.ts` にある HeaderProps というのが最終的な props なのであり、これらを穴埋めしていくことになります。 | ||
`xxxAdditionalContent` 以外の props は積極的に埋めてください。 | ||
|
||
```ts | ||
export type HeaderProps = ComponentProps<typeof Header> & { | ||
locale?: LocaleProps | null | ||
enableNew?: boolean | ||
appName?: ReactNode | ||
schoolUrl?: string | null | ||
helpPageUrl?: string | null | ||
userInfo?: UserInfoProps | null | ||
desktopAdditionalContent?: ReactNode | ||
navigations?: Navigation[] | null | ||
desktopNavigationAdditionalContent?: ReactNode | ||
releaseNote?: ReleaseNoteProps | null | ||
features?: Array<Launcher['feature']> | ||
mobileAdditionalContent?: ReactNode | ||
} | ||
``` | ||
下記に、少し特殊な動きをするものやパッと見分かりづらいであろうと思われる props だけ補足説明を書きます。 | ||
- `locale` | ||
- 多言語対応に wovn を使っている場合はこの props は不要です。 | ||
- `tenants` | ||
- デスクトップ表示時 | ||
- Header コンポーネントと同じです。 | ||
- モバイル表示時 | ||
- ハンバーガーメニューが表示されている場合はメニューの中に、そうでない場合はデスクトップ表示時と同じ箇所 (ロゴの横) に表示されます。 | ||
- もし既存の独自実装ハンバーガーメニュー内にテナント選択の UI があるなどの理由で「ハンバーガーメニューは表示しないがモバイル表示時にヘッダーにテナント選択の UI を表示したくない」という場合は、ウィンドウサイズが 751px 以下のときに tenants props に undefined を渡すようにしてください。 | ||
- `navigations` | ||
- ヘッダーの下にナビゲーションが表示されるようになります。 | ||
- AppNavi コンポーネントの buttons props とほぼ同じ型のデータを取ります。 | ||
- AppNavi コンポーネントの buttons にはなかった、ドロップダウン内でのナビゲーションのグルーピングができるようになっています。 | ||
- storybook の「VRT Navigation Dropdown Group」を参考にしてください。 | ||
- **navigations props に値が渡されているときのみ、モバイル表示時にハンバーガーメニューが表示されます。独自実装の ハンバーガーメニューが存在する場合は、navigations props を利用するタイミングで移行してください。** | ||
- `desktopAdditionalContent` | ||
- ユーザー名をクリックしたときのドロップダウンの、「個人設定」の下に入れたいものがある場合に使います。 | ||
- 見た目の共通化のため、乱用は避けてください | ||
- `desktopNavigationAdditionalContent` | ||
- ナビゲーション内で右寄せ、かつリリースノートの左側に入れたい物がある場合に使います。 | ||
- 見た目の共通化のため、乱用は避けてください | ||
- `mobileAdditionalContent` | ||
- モバイル表示時に、メニュー内に何か追加で起きたいものがある場合に使います。 | ||
- 見た目の共通化のため、乱用は避けてほしいですが、もし何かしらのパーツを配置する必要がある場合は、デザイナーと相談しながら実装してください。 | ||
## 多言語対応について | ||
- wovn を使っているアプリの場合 | ||
- 内部で表示されているテキストに関しては、すべて `woven-enabled="true"` がついています。 | ||
- 外部から渡すテキストは全て `ReactNode` 型で受け取るようになっているので、`<span woven-enabled="true">ほげ</span>` みたいなものを渡すようにしてください。 | ||
- 辞書を持っているアプリの場合 | ||
- コンポーネント側で辞書を持っているので、`locale` の props を埋めると内部的に持っているテキストは翻訳されます。 | ||
- 外部から渡すテキストはアプリケーション側で翻訳されたものを渡すようにしてください。 |
71 changes: 71 additions & 0 deletions
71
packages/smarthr-ui/src/components/AppHeader/components/common/AppLauncherFeatures.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React, { FC } from 'react' | ||
import { tv } from 'tailwind-variants' | ||
|
||
import { AnchorButton } from '../../../Button' | ||
import { FaArrowRightIcon, FaStarIcon } from '../../../Icon' | ||
import { LineClamp } from '../../../LineClamp' | ||
import { Text } from '../../../Text' | ||
import { mediaQuery, useMediaQuery } from '../../hooks/useMediaQuery' | ||
import { useTranslate } from '../../hooks/useTranslate' | ||
import { Launcher } from '../../types' | ||
|
||
import { Translate } from './Translate' | ||
|
||
const appLauncherFeatures = tv({ | ||
slots: { | ||
empty: ['shr-p-1 shr-text-center'], | ||
list: ['shr-list-none', '[&>li]:shr-px-0.5 [&>li]:shr-py-0.25'], | ||
listItem: [ | ||
'smarthr-ui-AppLauncher-listItem', | ||
'shr-grid shr-grid-cols-[1rem_1fr_1rem] shr-gap-0.75 shr-min-h-[2.5rem] shr-px-1 shr-py-0 shr-leading-tight shr-text-left shr-whitespace-normal', | ||
], | ||
}, | ||
variants: { | ||
favorite: { | ||
false: { | ||
listItem: ['shr-grid-cols-[1fr_1rem]'], | ||
}, | ||
}, | ||
}, | ||
}) | ||
|
||
type Props = { | ||
features: Array<Launcher['feature']> | ||
page: Launcher['page'] | ||
} | ||
|
||
export const AppLauncherFeatures: FC<Props> = ({ features, page }) => { | ||
const isDesktop = useMediaQuery(mediaQuery.desktop) | ||
const translate = useTranslate() | ||
const { empty, list, listItem } = appLauncherFeatures() | ||
|
||
if (features.length === 0) { | ||
return ( | ||
<div className={empty()}> | ||
<Text size="S"> | ||
<Translate>{translate('Launcher/emptyText')}</Translate> | ||
</Text> | ||
</div> | ||
) | ||
} | ||
|
||
return ( | ||
<ul className={list()}> | ||
{features.map((feature) => ( | ||
<li key={feature.id}> | ||
<AnchorButton | ||
className={listItem({ favorite: page === 'favorite' })} | ||
variant="text" | ||
href={feature.url} | ||
prefix={page === 'favorite' && <FaStarIcon />} | ||
suffix={<FaArrowRightIcon />} | ||
wide | ||
target="_blank" | ||
> | ||
{isDesktop ? <LineClamp maxLines={2}>{feature.name}</LineClamp> : feature.name} | ||
</AnchorButton> | ||
</li> | ||
))} | ||
</ul> | ||
) | ||
} |
Oops, something went wrong.