diff --git a/src/components/Common/AppsPromo/index.module.css b/src/components/Common/AppsPromo/index.module.css index 70f69a9a..d8ac87c3 100644 --- a/src/components/Common/AppsPromo/index.module.css +++ b/src/components/Common/AppsPromo/index.module.css @@ -3,8 +3,8 @@ overflow: hidden; border-top: 1px solid #d6d6d6; border-bottom: 1px solid #eeeeee; - background: rgb(107 114 128); - color: #ffffff; + background: var(--color-theme-light-muted); + color: var(--color-theme-light-text); } .inner { @@ -135,8 +135,8 @@ :global(body.DarkTheme) .appsPromo { border-top-color: #3f3f46; border-bottom-color: #27272a; - background: rgb(107 114 128); - color: #ffffff; + background: var(--color-theme-dark-muted); + color: var(--color-theme-dark-text); } @media (max-width: 720px) { diff --git a/src/components/Common/Layouts/Container/FixedContentContainer/index.module.css b/src/components/Common/Layouts/Container/FixedContentContainer/index.module.css index d77be1eb..5b6f8db9 100644 --- a/src/components/Common/Layouts/Container/FixedContentContainer/index.module.css +++ b/src/components/Common/Layouts/Container/FixedContentContainer/index.module.css @@ -6,13 +6,6 @@ margin-top: 0; } -.content > h1 { - font-size: var(--font-size-content-heading-1); - font-weight: var(--font-weight-content-heading); - border-bottom: 1px solid var(--color-border); - margin: 2.8rem 0 1rem; -} - .content > h2 { font-size: var(--font-size-content-heading-2); font-weight: var(--font-weight-content-heading); @@ -126,16 +119,10 @@ font-weight: bold; } -.content > blockquote { - border-left: 4px solid var(--color-border); - padding-left: 1rem; - margin: 2rem 0; -} - .content > hr { margin: 4rem 0; height: 1px; - background-color: var(--color-border); + background-color: var(--color-theme-border); border: none; } diff --git a/src/components/Features/Article/Elements/Plugins/CustomHtml/index.module.css b/src/components/Features/Article/Elements/Plugins/CustomHtml/index.module.css index be4f18a5..e80ebace 100644 --- a/src/components/Features/Article/Elements/Plugins/CustomHtml/index.module.css +++ b/src/components/Features/Article/Elements/Plugins/CustomHtml/index.module.css @@ -10,13 +10,6 @@ margin-top: 0; } -.content > h1 { - font-size: var(--font-size-content-heading-1); - font-weight: var(--font-weight-content-heading); - border-bottom: 1px solid var(--color-border); - margin: 2.8rem 0 1rem; -} - .content > h2 { font-size: var(--font-size-content-heading-2); font-weight: var(--font-weight-content-heading); @@ -148,16 +141,10 @@ font-weight: bold; } -.content > blockquote { - border-left: 4px solid var(--color-border); - padding-left: 1rem; - margin: 2rem 0; -} - .content > hr { margin: 4rem 0; height: 1px; - background-color: var(--color-border); + background-color: var(--color-theme-border); border: none; } diff --git a/src/components/Features/Article/Elements/Plugins/CustomHtml/index.stories.tsx b/src/components/Features/Article/Elements/Plugins/CustomHtml/index.stories.tsx index 67eebf2c..811d0182 100644 --- a/src/components/Features/Article/Elements/Plugins/CustomHtml/index.stories.tsx +++ b/src/components/Features/Article/Elements/Plugins/CustomHtml/index.stories.tsx @@ -1,34 +1,23 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'; -import { expect, userEvent, waitFor, within } from 'storybook/test'; +import { expect, within } from 'storybook/test'; import CustomHtml from '.'; import '@/styles/plugin.css'; -const articleHtml = ` -

カスタムHTMLで挿入される記事本文の表示例です。強調外部リンクを含みます。

-

カスタムHTMLの見出し

-

本文の余白、行間、リンク色などが本番の記事画面と同じことを確認します。

-
-
export function greeting(name: string) {
-  return \`こんにちは、\${name}さん\`;
-}
-
-

表示できる要素

- -

引用文の背景、余白、アイコンを確認します。

- - - -
項目内容
表示元カスタムHTML
+const googleMapHtml = ` + `; const meta = { title: 'Content/Article Plugins/Custom HTML', component: CustomHtml, - args: { html: articleHtml }, decorators: [ (Story) => (
@@ -39,7 +28,7 @@ const meta = { parameters: { docs: { description: { - component: '記事本文へ挿入される、サニタイズ済みカスタムHTMLの本番相当表示を確認します。', + component: '記事へ埋め込むGoogle Mapのレスポンシブ表示を確認します。', }, }, }, @@ -49,22 +38,23 @@ const meta = { export default meta; type Story = StoryObj; -export const ArticleContent: Story = { +export const GoogleMap: Story = { + args: { html: googleMapHtml }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); - const externalLink = canvas.getByRole('link', { name: '外部リンク' }); - const wrapButton = await canvas.findByRole('button', { name: 'コードを折り返す' }); + const map = canvas.getByTitle('東京周辺のGoogle Map'); + const container = map.parentElement; - await waitFor(() => { - expect(externalLink).toHaveAttribute('target', '_blank'); - expect(externalLink).toHaveAttribute('rel', 'noopener noreferrer'); - }); + await expect(map).toHaveAttribute('loading', 'lazy'); + await expect(container).not.toBeNull(); - await userEvent.click(wrapButton); - await expect(wrapButton).toHaveAttribute('aria-pressed', 'true'); - }, -}; + if (!container) { + throw new Error('Google Map container was not rendered'); + } -export const Mobile: Story = { - globals: { viewport: { value: 'mobile1', isRotated: false } }, + await expect(map.getBoundingClientRect().width).toBeCloseTo( + container.getBoundingClientRect().width, + 0, + ); + }, }; diff --git a/src/components/Features/Article/Elements/Plugins/ImageSlider/index.module.css b/src/components/Features/Article/Elements/Plugins/ImageSlider/index.module.css index 08866646..9e225717 100644 --- a/src/components/Features/Article/Elements/Plugins/ImageSlider/index.module.css +++ b/src/components/Features/Article/Elements/Plugins/ImageSlider/index.module.css @@ -63,7 +63,7 @@ width: 40px !important; height: 40px !important; padding: 0 !important; - border: 1px solid var(--color-theme-light-border) !important; + border: 1px solid var(--color-theme-light-muted) !important; border-radius: 9999px !important; color: var(--color-theme-light-text) !important; background: rgb(255 255 255 / 92%) !important; diff --git a/src/components/Features/Article/Elements/Plugins/RichText/index.module.css b/src/components/Features/Article/Elements/Plugins/RichText/index.module.css index b42f78c5..473c809a 100644 --- a/src/components/Features/Article/Elements/Plugins/RichText/index.module.css +++ b/src/components/Features/Article/Elements/Plugins/RichText/index.module.css @@ -10,15 +10,8 @@ margin-top: 0; } -.content > h1 { - font-size: var(--font-size-content-heading-1); - font-weight: var(--font-weight-content-heading); - border-bottom: 1px solid var(--color-border); - margin: 2.8rem 0 1rem; -} - .content > h2 { - background-color: var(--color-theme-light-border); + background-color: var(--color-theme-muted); color: var(--color-theme-light-text); font-size: var(--font-size-content-heading-2); font-weight: var(--font-weight-content-heading); @@ -27,7 +20,7 @@ } .content > h3 { - border-color: var(--color-theme-light-border); + border-color: var(--color-theme-border); color: var(--color-theme-light-text); font-size: var(--font-size-content-heading-3); font-weight: var(--font-weight-content-heading); @@ -36,7 +29,7 @@ } .content > h4 { - border-color: var(--color-theme-light-border); + border-color: var(--color-theme-border); color: var(--color-theme-light-text); font-size: var(--font-size-content-heading-4); font-weight: var(--font-weight-content-heading); @@ -141,16 +134,10 @@ font-weight: bold; } -.content > blockquote { - border-left: 4px solid var(--color-border); - padding-left: 1rem; - margin: 2rem 0; -} - .content > hr { margin: 4rem 0; height: 1px; - background-color: var(--color-border); + background-color: var(--color-theme-border); border: none; } @@ -171,13 +158,11 @@ } :global(body.DarkTheme) .content > h2 { - background-color: var(--color-theme-dark-border); color: var(--color-theme-dark-text); } :global(body.DarkTheme) .content > h3, :global(body.DarkTheme) .content > h4 { - border-color: var(--color-theme-dark-border); color: var(--color-theme-dark-text); } diff --git a/src/components/Features/Article/Elements/Plugins/RichText/index.stories.tsx b/src/components/Features/Article/Elements/Plugins/RichText/index.stories.tsx index d488061a..f0ec8ddd 100644 --- a/src/components/Features/Article/Elements/Plugins/RichText/index.stories.tsx +++ b/src/components/Features/Article/Elements/Plugins/RichText/index.stories.tsx @@ -24,12 +24,12 @@ const tableHtml = ` `; const articleHtml = ` -

記事本文の見出し1

本文には強調リンクが含まれます。

見出し2

段落の余白と行間を確認するための文章です。

見出し3

+

見出し4

  1. 番号付きの項目
  2. 次の手順

引用として表示される文章です。

記事本文のサンプル画像
画像のキャプション
diff --git a/src/components/Features/Article/index.module.css b/src/components/Features/Article/index.module.css index 24e558a5..74cecb41 100644 --- a/src/components/Features/Article/index.module.css +++ b/src/components/Features/Article/index.module.css @@ -1,5 +1,5 @@ .title { - font-size: 1.8rem; + font-size: var(--font-size-article-title); font-weight: bold; margin-bottom: 24px; text-align: left; @@ -8,7 +8,7 @@ @media (max-width: 640px) { .title { - font-size: 1.5rem; + font-size: var(--font-size-article-title-mobile); margin-bottom: 20px; } } diff --git a/src/components/Features/Article/index.tsx b/src/components/Features/Article/index.tsx index 2c6b0199..bcd019e7 100644 --- a/src/components/Features/Article/index.tsx +++ b/src/components/Features/Article/index.tsx @@ -82,7 +82,7 @@ export default function ArticleFeature({ data, relatedArticles }: Props) { return ( <> -

+

{data.title}

{data.isSponsored && } diff --git a/src/stories/Foundations.stories.tsx b/src/stories/Foundations.stories.tsx index cb8b23bd..a65a5785 100644 --- a/src/stories/Foundations.stories.tsx +++ b/src/stories/Foundations.stories.tsx @@ -19,18 +19,15 @@ type TypographyToken = { const themeColors: ColorToken[] = [ { name: 'Light background', variable: '--color-theme-light-background', value: '#fff' }, { name: 'Light text', variable: '--color-theme-light-text', value: '#374151' }, - { name: 'Light border', variable: '--color-theme-light-border', value: '#d1d5db' }, + { name: 'Light muted', variable: '--color-theme-light-muted', value: '#d1d5db' }, { name: 'Dark background', variable: '--color-theme-dark-background', value: '#262626' }, { name: 'Dark text', variable: '--color-theme-dark-text', value: '#fff' }, - { name: 'Dark border', variable: '--color-theme-dark-border', value: '#6b7280' }, + { name: 'Dark muted', variable: '--color-theme-dark-muted', value: '#6b7280' }, ]; const contentColors: ColorToken[] = [ - { name: 'Main text', variable: '--color-text-main', value: '#333' }, { name: 'Secondary text', variable: '--color-text-sub', value: '#767676' }, { name: 'Subtle background', variable: '--color-bg-sub', value: '#f3f3f3' }, - { name: 'Border', variable: '--color-border', value: '#ddd' }, - { name: 'Dark border', variable: '--color-border-dark', value: '#ccc' }, { name: 'Soft accent background', variable: '--color-accent-soft-bg', value: '#eaf4fc' }, { name: 'Soft accent text', variable: '--color-accent-soft-text', value: '#111827' }, { name: 'Link', variable: '--color-link', value: '#1d4ed8' }, @@ -44,9 +41,15 @@ const contentColors: ColorToken[] = [ const typography: TypographyToken[] = [ { - name: 'Heading 1', - variable: '--font-size-content-heading-1', - value: '2rem', + name: 'Article title', + variable: '--font-size-article-title', + value: '1.8rem', + sample: '記事タイトル', + }, + { + name: 'Article title (mobile)', + variable: '--font-size-article-title-mobile', + value: '1.5rem', sample: '記事タイトル', }, { @@ -160,7 +163,10 @@ function TypographyScale() { {typography.map(({ name, variable, value, sample }) => { const style = { fontSize: `var(${variable})`, - fontWeight: name.startsWith('Heading') ? 'var(--font-weight-content-heading)' : undefined, + fontWeight: + name.startsWith('Heading') || name.startsWith('Article title') + ? 'var(--font-weight-content-heading)' + : undefined, lineHeight: name === 'Body' ? 'var(--line-height-content-body)' : undefined, } satisfies CSSProperties; diff --git a/src/styles/globals.css b/src/styles/globals.css index cecc8d32..8803397a 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -27,7 +27,7 @@ layer(base); :where([data-app-root]) { font-family: 'Geist', sans-serif; - color: var(--color-text-main); + color: var(--color-theme-light-text); line-height: 1.8; } @@ -35,8 +35,10 @@ layer(base); :where([data-app-root]) .LightTheme { background-color: var(--color-theme-light-background); color: var(--color-theme-light-text); - border-color: var(--color-theme-light-border); - --tw-ring-color: var(--color-theme-light-border); + border-color: var(--color-theme-light-muted); + --tw-ring-color: var(--color-theme-light-muted); + --color-theme-border: var(--color-theme-light-muted); + --color-theme-muted: var(--color-theme-light-muted); --color-text-sub: #767676; } @@ -44,8 +46,10 @@ layer(base); :where([data-app-root]) .DarkTheme { background-color: var(--color-theme-dark-background); color: var(--color-theme-dark-text); - border-color: var(--color-theme-dark-border); - --tw-ring-color: var(--color-theme-dark-border); + border-color: var(--color-theme-dark-muted); + --tw-ring-color: var(--color-theme-dark-muted); + --color-theme-border: var(--color-theme-dark-muted); + --color-theme-muted: var(--color-theme-dark-muted); --color-text-sub: #999; } @@ -74,13 +78,10 @@ layer(base); ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; - --color-text-main: #333; --color-text-sub: #767676; --color-bg-sub: #f3f3f3; --color-bg-code: #0d1117; --color-text-code: #c9d1d9; - --color-border-dark: #ccc; - --color-border: #ddd; --color-focus-ring: #2563eb; --color-accent-soft-bg: #eaf4fc; --color-accent-soft-text: #111827; @@ -90,13 +91,16 @@ layer(base); --color-link-dark-hover: #bfdbfe; --color-theme-light-background: #fff; --color-theme-light-text: #374151; - --color-theme-light-border: #d1d5db; + --color-theme-light-muted: #d1d5db; --color-theme-dark-background: #262626; --color-theme-dark-text: #fff; - --color-theme-dark-border: #6b7280; + --color-theme-dark-muted: #6b7280; + --color-theme-border: var(--color-theme-light-muted); + --color-theme-muted: var(--color-theme-light-muted); --font-family-content-code: menlo, inconsolata, monospace; --font-size-content-body: 18px; - --font-size-content-heading-1: 2rem; + --font-size-article-title: 1.8rem; + --font-size-article-title-mobile: 1.5rem; --font-size-content-heading-2: 1.6rem; --font-size-content-heading-3: 1.4rem; --font-size-content-heading-4: 1.2rem; diff --git a/src/styles/plugin.css b/src/styles/plugin.css index 4c78438f..e75be01f 100644 --- a/src/styles/plugin.css +++ b/src/styles/plugin.css @@ -13,7 +13,7 @@ .underline_code { background-color: #f7f7fc; - border: 1px solid var(--color-border); + border: 1px solid var(--color-theme-border); border-radius: 3px; color: #2b2c30; margin: 0 2px; @@ -34,7 +34,7 @@ table { } table tr th { - border: 1px solid var(--color-border-dark); + border: 1px solid var(--color-theme-border); background-color: var(--color-accent-soft-bg) !important; word-wrap: break-word; overflow-wrap: break-word; @@ -42,7 +42,7 @@ table tr th { } table tr td { - border: 1px solid var(--color-border-dark); + border: 1px solid var(--color-theme-border); word-wrap: break-word; overflow-wrap: break-word; white-space: normal;