diff --git a/.storybook/globals.css b/.storybook/globals.css index e5602ab..99af776 100644 --- a/.storybook/globals.css +++ b/.storybook/globals.css @@ -1,6 +1,8 @@ @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+Mono:wght@400;700&display=swap"); +@import "@digital-go-jp/design-tokens"; + @tailwind base; @tailwind components; @tailwind utilities; diff --git a/.storybook/main.ts b/.storybook/main.ts index 38a6556..8a01de9 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,7 @@ import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { - stories: ['../src/docs/*.stories.@(js|jsx|ts|tsx)', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], addons: ['@storybook/addon-links', '@storybook/addon-a11y', '@storybook/addon-docs'], framework: { diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 798fbe7..603aafb 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,5 +1,6 @@ import type { Preview } from '@storybook/react-vite'; import './globals.css'; +import "./prose.css"; const preview: Preview = { parameters: { @@ -15,7 +16,10 @@ const preview: Preview = { options: { storySort: { order: [ - 'Getting Started', + 'Documents', + [ + 'はじめに' + ], 'Component', [ 'アコーディオン', diff --git a/.storybook/prose.css b/.storybook/prose.css new file mode 100644 index 0000000..56ee645 --- /dev/null +++ b/.storybook/prose.css @@ -0,0 +1,533 @@ +@scope (.prose) to (.sbdocs-preview, .docblock-argstable) { + :scope { + color: var(--color-neutral-solid-gray-800); + font-weight: normal; + font-size: calc(16 / 16 * 1rem); + line-height: 1.7; + font-family: var(--font-family-sans); + letter-spacing: 0.02em; + overflow-wrap: anywhere; + line-break: strict; + text-autospace: normal; + text-spacing-trim: trim-start; + } + + @media (min-width: 48rem) { + :scope { + font-size: calc(17 / 16 * 1rem); + } + } + + /* Heading */ + + :scope > h1 { + margin-top: 0; + margin-bottom: calc(32 / 16 * 1rem); + margin-left: calc(-2 / 16 * 1rem); + font-weight: bold; + font-size: calc(28 / 16 * 1rem); + line-height: 1.5; + letter-spacing: 0.01em; + text-wrap: pretty; + } + + @media (min-width: 48rem) { + :scope > h1 { + margin-bottom: calc(48 / 16 * 1rem); + font-size: calc(45 / 16 * 1rem); + line-height: 1.4; + letter-spacing: 0; + } + } + + :scope > h2 { + margin-top: calc(40 / 16 * 1rem); + margin-bottom: calc(24 / 16 * 1rem); + font-weight: bold; + font-size: calc(24 / 16 * 1rem); + line-height: 1.5; + letter-spacing: 0.02em; + text-wrap: pretty; + } + + @media (min-width: 48rem) { + :scope > h2 { + margin-top: calc(64 / 16 * 1rem); + font-size: calc(32 / 16 * 1rem); + } + } + + :scope > h3 { + margin-top: calc(32 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + font-weight: bold; + font-size: calc(22 / 16 * 1rem); + line-height: 1.5; + letter-spacing: 0.02em; + text-wrap: pretty; + } + + @media (min-width: 48rem) { + :scope > h3 { + margin-top: calc(48 / 16 * 1rem); + margin-bottom: calc(24 / 16 * 1rem); + font-size: calc(24 / 16 * 1rem); + } + } + + :scope > h4 { + margin-top: calc(24 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + font-weight: bold; + font-size: calc(18 / 16 * 1rem); + line-height: 1.6; + letter-spacing: 0.02em; + text-wrap: pretty; + } + + @media (min-width: 48rem) { + :scope > h4 { + margin-top: calc(40 / 16 * 1rem); + font-size: calc(20 / 16 * 1rem); + line-height: 1.5; + } + } + + :scope > h5 { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: 0; + font-weight: bold; + font-size: calc(18 / 16 * 1rem); + line-height: 1.6; + letter-spacing: 0.02em; + text-wrap: pretty; + } + + :scope > h6 { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: 0; + font-weight: bold; + font-size: calc(16 / 16 * 1rem); + line-height: 1.7; + letter-spacing: 0.02em; + text-wrap: pretty; + } + + /* Paragraph */ + + :scope > p, + :scope > :is(blockquote, ol, ul, dl, table, details) p { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + } + + @media (min-width: 48rem) { + :scope > p, + :scope > :is(blockquote, ol, ul, dl, table, details) p { + margin-bottom: calc(24 / 16 * 1rem); + } + } + + /* List */ + + :scope > ul, + :scope > ol, + :scope > :is(blockquote, ol, ul, dl, table, details) ul, + :scope > :is(blockquote, ol, ul, dl, table, details) ol { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + padding-left: calc(32 / 16 * 1rem); + } + + @media (min-width: 48rem) { + :scope > ul, + :scope > ol, + :scope > :is(blockquote, ol, dl, table, details) ul, + :scope > :is(blockquote, ul, dl, table, details) ol { + margin-top: calc(24 / 16 * 1rem); + margin-bottom: calc(24 / 16 * 1rem); + } + } + + :scope > :is(blockquote, ol, ul, dl, table, details) ul, + :scope > :is(blockquote, ol, ul, dl, table, details) ol { + margin-top: calc(8 / 16 * 1rem); + margin-bottom: calc(8 / 16 * 1rem); + } + + :scope > ul, + :scope > :is(blockquote, ol, dl, table, details) ul { + list-style-type: disc; + } + + :scope > ul ul, + :scope > :is(blockquote, ol, dl, table, details) ul ul { + list-style-type: circle; + } + + :scope > ul ul ul, + :scope > :is(blockquote, ol, dl, table, details) ul ul ul { + list-style-type: square; + } + + :scope > ol, + :scope > :is(blockquote, ul, dl, table, details) ol { + list-style-type: decimal; + } + + :scope > ol ol, + :scope > :is(blockquote, ul, dl, table, details) ol ol { + list-style-type: lower-latin; + } + + :scope > :is(blockquote, ol, ul, dl, table, details) li + li { + margin-top: calc(8 / 16 * 1rem); + } + + /* Definition list */ + + :scope > dl { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + } + + :scope > dl dt { + font-weight: bold; + margin-top: calc(16 / 16 * 1rem); + } + + :scope > dl dd { + margin-left: calc(32 / 16 * 1rem); + margin-top: calc(8 / 16 * 1rem); + margin-bottom: calc(8 / 16 * 1rem); + } + + /* Blockquote */ + + :scope > blockquote { + margin-top: calc(16 / 16 * 1rem); + margin-right: 0; + margin-bottom: calc(24 / 16 * 1rem); + margin-left: 0; + border-left: calc(8 / 16 * 1rem) solid var(--color-neutral-solid-gray-536); + padding-top: calc(8 / 16 * 1rem); + padding-bottom: calc(8 / 16 * 1rem); + padding-left: calc(24 / 16 * 1rem); + } + + :scope > blockquote > *:first-child { + margin-top: 0; + } + + :scope > blockquote > *:last-child { + margin-bottom: 0; + } + + /* Table */ + + :scope > table { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + box-sizing: border-box; + width: 100%; + border-collapse: collapse; + font-size: calc(14 / 16 * 1rem); + line-height: 1.7; + letter-spacing: 0.02em; + } + + @media (min-width: 48rem) { + :scope > table { + margin-top: calc(24 / 16 * 1rem); + margin-bottom: calc(24 / 16 * 1rem); + font-size: calc(16 / 16 * 1rem); + } + } + + :scope > table thead { + background-color: var(--color-neutral-solid-gray-100); + } + + :scope > table thead th { + border-bottom: 1px solid var(--color-neutral-black); + } + + :scope > table th { + border-bottom: 1px solid black; + background-color: var(--color-neutral-solid-gray-100); + padding: calc(12 / 16 * 1rem) calc(8 / 16 * 1rem); + vertical-align: baseline; + text-align: left; + font-weight: bold; + } + + :scope > table td { + border-bottom: 1px solid var(--color-neutral-solid-gray-420); + padding: calc(12 / 16 * 1rem) calc(8 / 16 * 1rem); + vertical-align: baseline; + text-align: left; + } + + @media (min-width: 48rem) { + :scope > table th { + padding: calc(20 / 16 * 1rem) calc(16 / 16 * 1rem); + } + + :scope > table td { + padding: calc(20 / 16 * 1rem) calc(16 / 16 * 1rem); + } + } + + :scope > table th[align="center"], + :scope > table td[align="center"] { + text-align: center; + } + + :scope > table th[align="right"], + :scope > table td[align="right"] { + text-align: right; + } + + /* Horizontal rule */ + + :scope > hr { + margin-top: calc(32 / 16 * 1rem); + margin-bottom: calc(32 / 16 * 1rem); + border: 0; + border-top: 1px solid var(--color-neutral-solid-gray-420); + opacity: 1; + } + + /* Code block */ + + :scope > pre { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + overflow-x: auto; + background-color: var(--color-neutral-solid-gray-800); + border-radius: 0.5rem; + border: 1px solid transparent; + padding: calc(12 / 16 * 1rem) calc(16 / 16 * 1rem); + color: var(--color-neutral-solid-gray-50); + font-size: calc(14 / 16 * 1rem); + } + + :scope > pre code { + display: block; + } + + @media (min-width: 48rem) { + :scope > pre { + font-size: calc(16 / 16 * 1rem); + } + } + + /* Details and summary */ + + :scope > details { + margin-top: calc(16 / 16 * 1rem); + margin-bottom: calc(16 / 16 * 1rem); + border: 1px solid var(--color-neutral-solid-gray-420); + border-radius: calc(8 / 16 * 1rem); + padding: calc(16 / 16 * 1rem); + } + + :scope > details > summary { + cursor: default; + font-weight: bold; + } + + :scope > details[open] > summary { + margin-bottom: calc(16 / 16 * 1rem); + } + + /* Link */ + + :scope a:any-link { + color: var(--color-primitive-blue-1000); + text-decoration: underline; + text-decoration-thickness: calc(1 / 16 * 1rem); + text-underline-offset: calc(3 / 16 * 1rem); + } + + :scope a:visited { + color: var(--color-primitive-magenta-900); + } + + @media (hover: hover) { + :scope a:hover { + color: var(--color-primitive-blue-900); + text-decoration-thickness: calc(3 / 16 * 1rem); + } + } + + :scope a:active { + color: var(--color-primitive-orange-700); + text-decoration-thickness: calc(1 / 16 * 1rem); + } + + :scope a:focus-visible { + outline: calc(4 / 16 * 1rem) solid var(--color-neutral-black); + outline-offset: calc(2 / 16 * 1rem); + border-radius: calc(4 / 16 * 1rem); + background-color: var(--color-primitive-yellow-300); + box-shadow: 0 0 0 calc(2 / 16 * 1rem) var(--color-primitive-yellow-300); + } + + :scope a[target="_blank"]::after { + --_open-new-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 48 48' role='img'%3E%3Cpath d='M22 6V9H9V39H39V26H42V42H6V6H22ZM42 6V20H39V11.2L21 29L19 27L36.8 9H28V6H42Z'/%3E%3C/svg%3E"); + --_spacer: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); + display: inline-block; + overflow: hidden; + width: calc(16 / 16 * 1rem); + height: calc(16 / 16 * 1rem); + background-color: currentcolor; + -webkit-mask: var(--_open-new-icon) 0 0 / 100%; + mask: var(--_open-new-icon) 0 0 / 100%; + vertical-align: -0.15em; + content: var(--_spacer) / "新規タブで開きます"; + } + + @media (forced-colors: active) { + :scope a[target="_blank"]::after { + background-color: LinkText; + } + } + + /* Image */ + + :scope img, + :scope svg { + display: inline-block; + box-sizing: border-box; + max-width: 100%; + height: auto; + vertical-align: text-bottom; + } + + /* Inline elements */ + + :scope u, + :scope ins { + text-decoration: underline; + text-underline-offset: calc(3 / 16 * 1rem); + } + + :scope abbr[title] { + text-decoration: dotted underline; + text-underline-offset: calc(3 / 16 * 1rem); + } + + :scope strong, + :scope b { + font-weight: bold; + } + + :scope i, + :scope cite, + :scope em, + :scope var, + :scope dfn { + font-style: italic; + } + + :scope code, + :scope kbd, + :scope samp { + color: inherit; + font: inherit; + font-family: var(--font-family-mono), monospace; + letter-spacing: 0; + } + + :scope kbd { + padding: 0; + background-color: transparent; + color: inherit; + } + + :scope mark { + background-color: var(--color-primitive-yellow-300); + padding: 0; + color: var(--color-neutral-solid-gray-900); + } + + @media (forced-colors: active) { + :scope mark { + background-color: Highlight; + color: HighlightText; + } + } + + :scope small { + font-size: smaller; + } + + :scope s, + :scope del { + text-decoration: line-through; + text-decoration-thickness: calc(1 / 16 * 1rem); + } + + :scope sup { + position: static; + vertical-align: super; + font-size: smaller; + line-height: 1; + } + + :scope sub { + position: static; + vertical-align: sub; + font-size: smaller; + line-height: 1; + } + + /* Print styles */ + + @media print { + :scope { + color: CanvasText; + } + + :scope > pre { + background-color: Canvas; + color: CanvasText; + border-color: CanvasText; + } + + :scope a::after { + content: " (" attr(href) ")"; + font-size: calc(14 / 16 * 1rem); + } + } + + /* Storybookドキュメント用のproseの上書き */ + + /* コードブロックのスタイル調整 */ + :scope > pre:has(.docblock-source) { + overflow: visible; + background-color: transparent; + border-radius: 0; + border: 0; + padding: 0; + color: currentcolor; + } + + /* コードブロックとStoryのソースコード表示の文字サイズ調整 */ + :scope .docs-story + div, + :scope .docblock-source { + font-size: calc(16 / 16 * 1rem); + line-height: 1.5; + } + + :scope a { + font-family: inherit; + } + + :scope code { + border: 0; + background-color: transparent; + padding: 0; + } +} diff --git a/README.md b/README.md index 055796b..b9f3d03 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# React サンプルコンポーネント +# デジタル庁デザインシステム コードスニペット(React版) -[デジタル庁デザインシステム](https://design.digital.go.jp/) のコンポーネントの一部をReact / Tailwind CSSベースで実装したサンプル集です。 +[デジタル庁デザインシステム](https://design.digital.go.jp/)をReact/Tailwind CSSで実装したサンプル集です。 -[Storybook](https://digital-go-jp.github.io/design-system-example-components/)で最新版を公開しています。 +[Storybook](https://design.digital.go.jp/dads/react/)で最新版を公開しています。 ## 未実装コンポーネント @@ -39,15 +39,13 @@ npm run storybook - サンプルコードは Google Chrome / Microsoft Edge / Safari / Firefox の最新版で動作を確認しています。 - サンプルコードはプロジェクトの特性に合わせて自由に拡張してください。 -## Issues, Pull Requests +## 不具合報告・機能要望について -ご興味を持って頂きありがとうございます。 -リリース直後のため、現在体制がまだ整っておりません。 -そのため、何かお気づきの点やご要望がございましたら、まずはIssueの作成をお願いします。PRはそのIssueでの議論が終わった後に作成してください。 -また、現時点ではコンポーネントそのものに関するIssueのみを受け付けておりますので、予めご了承ください。 +本コードスニペットに関する不具合や機能要望は、Issueを作成して報告してください。Pull Requestは現時点では受け付けておりません。 ## 求人情報 デジタル庁デザインシステムのチームメンバーを募集しています。行政のデジタル環境を支える基盤づくりに、あなたのスキルや経験を活かしてみませんか? 求人ページからご応募ください。 -- [プロダクトデザイナー(デザインシステム) - デジタル庁](https://herp.careers/v1/digitalsaiyo/IjQ4ovK9BFPl) +- [プロダクトデザイナー](https://herp.careers/v1/digitalsaiyo/IjQ4ovK9BFPl) +- [プロダクトデザイナー(アソシエイト)](https://herp.careers/v1/digitalsaiyo/yzcCCZJ9UY-f) diff --git a/package-lock.json b/package-lock.json index d985b52..a66ab04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { - "name": "@digital-go-jp/design-system-example-components", - "version": "2.5.0", + "name": "@digital-go-jp/design-system-example-components-internal", + "version": "2.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@digital-go-jp/design-system-example-components", - "version": "2.5.0", + "name": "@digital-go-jp/design-system-example-components-internal", + "version": "2.1.2", "license": "MIT", "dependencies": { + "@digital-go-jp/design-tokens": "^1.1.0", "@digital-go-jp/tailwind-theme-plugin": "^0.3.0", "@internationalized/date": "^3.8.0", "react": "^18.3.1", @@ -508,6 +509,12 @@ "node": ">=14.21.3" } }, + "node_modules/@digital-go-jp/design-tokens": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@digital-go-jp/design-tokens/-/design-tokens-1.1.0.tgz", + "integrity": "sha512-gHhJTj8pPPg/6a1ey0PbFWPZxJRCrvSh3y4AQezW+VbaSdIjv9pVmMxDfcyPMVf0fA/OgEC/IE8xzHu3Pt3Ykg==", + "license": "MIT" + }, "node_modules/@digital-go-jp/tailwind-theme-plugin": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@digital-go-jp/tailwind-theme-plugin/-/tailwind-theme-plugin-0.3.1.tgz", diff --git a/package.json b/package.json index 0525aeb..8678dfc 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "storybook:test": "test-storybook" }, "dependencies": { + "@digital-go-jp/design-tokens": "^1.1.0", "@digital-go-jp/tailwind-theme-plugin": "^0.3.0", "@internationalized/date": "^3.8.0", "react": "^18.3.1", diff --git a/src/components/DatePicker/DatePicker.tsx b/src/components/DatePicker/DatePicker.tsx index fec648e..5d5d9bc 100644 --- a/src/components/DatePicker/DatePicker.tsx +++ b/src/components/DatePicker/DatePicker.tsx @@ -1,3 +1,5 @@ +'use client'; + import { type ComponentProps, type KeyboardEvent, type Ref, useRef } from 'react'; export type DatePickerSize = 'lg' | 'md' | 'sm'; diff --git a/src/components/HamburgerMenuButton/HamburgerMenuButton.stories.tsx b/src/components/HamburgerMenuButton/HamburgerMenuButton.stories.tsx index 7afca80..c6e7604 100644 --- a/src/components/HamburgerMenuButton/HamburgerMenuButton.stories.tsx +++ b/src/components/HamburgerMenuButton/HamburgerMenuButton.stories.tsx @@ -1,7 +1,13 @@ import type { Meta, StoryObj } from '@storybook/react-vite'; import React, { useId, useRef, useState } from 'react'; -import { CloseIcon, CloseWithLabelIcon, HamburgerIcon, HamburgerWithLabelIcon } from './'; -import { HamburgerMenuButton } from './HamburgerMenuButton'; +import { + CloseIcon, + CloseWithLabelIcon, + HamburgerIcon, + HamburgerWithLabelIcon, + HamburgerMenuButton, + HamburgerMenuIconButton, +} from './'; const meta = { id: 'Component/DADS v2/HamburgerMenuButton', @@ -20,19 +26,18 @@ export const DesktopAndMobileCommon: Story = { return (
setIsMenuOpen(!isMenuOpen)} > {isMenuOpen ? ( <> - + 閉じる ) : ( <> - + メニュー )} @@ -55,13 +60,12 @@ export const MobileOnly: Story = {

モバイル条件付きコンポーネント

- モバイルデバイスでの表示時にヘッダーの領域が限定され、十分な領域が確保できない場合に限り、アイコンにラベルが内包された - HamburgerWithLabelIcon - によるモバイル条件付きコンポーネントを使用します。 + モバイルデバイスでの表示時にヘッダーの領域が限定され、十分な領域が確保できない場合に限り、アイコンにラベルが内包されたモバイル条件付きコンポーネント( + HamburgerMenuIconButton)を使用します。

- それ以外の場合は、原則として、HamburgerIcon - とテキストラベルの組み合わせから成るデスクトップ・モバイル共通コンポーネントを使用してください。 + それ以外の場合は、原則として、アイコンとテキストラベルの組み合わせから成るデスクトップ・モバイル共通コンポーネント( + HamburgerMenuButton)を使用してください。

@@ -76,14 +80,14 @@ export const MobileOnly: Story = { <>
- setIsMenuJaOpen(!isMenuJaOpen)} > {isMenuJaOpen ? : } - + {isMenuJaOpen && (
- )} - + {isMenuEnOpen && (
- drawerRef.current?.showModal()}> - + drawerRef.current?.showModal()}> + メニュー
@@ -186,7 +190,7 @@ export const WithDrawer: Story = {
drawerRef.current?.close()}> - + 閉じる
diff --git a/src/components/HamburgerMenuButton/HamburgerMenuButton.tsx b/src/components/HamburgerMenuButton/HamburgerMenuButton.tsx index 4fabaa5..58bac4f 100644 --- a/src/components/HamburgerMenuButton/HamburgerMenuButton.tsx +++ b/src/components/HamburgerMenuButton/HamburgerMenuButton.tsx @@ -9,11 +9,11 @@ export const HamburgerMenuButton = forwardRef; + +export const HamburgerMenuIconButton = forwardRef( + (props, ref) => { + const { children, className, ...rest } = props; + + return ( + + ); + }, +); diff --git a/src/components/HamburgerMenuButton/index.ts b/src/components/HamburgerMenuButton/index.ts index 55bb7d8..b12f1ed 100644 --- a/src/components/HamburgerMenuButton/index.ts +++ b/src/components/HamburgerMenuButton/index.ts @@ -1,4 +1,5 @@ export { HamburgerMenuButton } from './HamburgerMenuButton'; +export { HamburgerMenuIconButton } from './HamburgerMenuIconButton'; export { CloseIcon } from './parts/CloseIcon'; export { CloseWithLabelIcon } from './parts/CloseWithLabelIcon'; export { HamburgerIcon } from './parts/HamburgerIcon'; diff --git a/src/components/HamburgerMenuButton/parts/CloseIcon.tsx b/src/components/HamburgerMenuButton/parts/CloseIcon.tsx index 11be57d..6ebef34 100644 --- a/src/components/HamburgerMenuButton/parts/CloseIcon.tsx +++ b/src/components/HamburgerMenuButton/parts/CloseIcon.tsx @@ -10,12 +10,12 @@ export const CloseIcon = (props: CloseIconProps) => { className={className} fill='none' height='24' - viewBox='0 0 24 24' + viewBox='0 0 120 120' width='24' {...rest} > diff --git a/src/components/HamburgerMenuButton/parts/CloseWithLabelIcon.tsx b/src/components/HamburgerMenuButton/parts/CloseWithLabelIcon.tsx index a286c26..e7f9317 100644 --- a/src/components/HamburgerMenuButton/parts/CloseWithLabelIcon.tsx +++ b/src/components/HamburgerMenuButton/parts/CloseWithLabelIcon.tsx @@ -20,27 +20,7 @@ export const CloseWithLabelIcon = (props: CloseWithLabelIconProps) => { {...rest} > - - - - - @@ -55,22 +35,8 @@ export const CloseWithLabelIcon = (props: CloseWithLabelIconProps) => { width='44' {...rest} > - - - - - diff --git a/src/components/HamburgerMenuButton/parts/HamburgerIcon.tsx b/src/components/HamburgerMenuButton/parts/HamburgerIcon.tsx index 35afec4..1b86ead 100644 --- a/src/components/HamburgerMenuButton/parts/HamburgerIcon.tsx +++ b/src/components/HamburgerMenuButton/parts/HamburgerIcon.tsx @@ -15,7 +15,7 @@ export const HamburgerIcon = (props: HamburgerIconProps) => { > diff --git a/src/components/HamburgerMenuButton/parts/HamburgerWithLabelIcon.tsx b/src/components/HamburgerMenuButton/parts/HamburgerWithLabelIcon.tsx index ad8c16e..1eae625 100644 --- a/src/components/HamburgerMenuButton/parts/HamburgerWithLabelIcon.tsx +++ b/src/components/HamburgerMenuButton/parts/HamburgerWithLabelIcon.tsx @@ -20,25 +20,7 @@ export const HamburgerWithLabelIcon = (props: HamburgerWithLabelIconProps) => { {...rest} > - - - - @@ -53,30 +35,10 @@ export const HamburgerWithLabelIcon = (props: HamburgerWithLabelIconProps) => { width='44' {...rest} > - - - - - - - + )} diff --git a/src/components/LanguageSelector/parts/Menu.tsx b/src/components/LanguageSelector/parts/Menu.tsx index e24c3b6..ab47b04 100644 --- a/src/components/LanguageSelector/parts/Menu.tsx +++ b/src/components/LanguageSelector/parts/Menu.tsx @@ -13,7 +13,7 @@ export const LanguageSelectorMenu = forwardRef:nth-child(7)]:rounded-r-none - ${isCondensed ? 'max-h-[calc((32*6.5+16)/16*1rem)]' : 'max-h-[calc((44*6.5+16)/16*1rem)]'} + ${isCondensed ? 'max-h-[calc((36*6.5+16)/16*1rem)]' : 'max-h-[calc((44*6.5+16)/16*1rem)]'} ${className ?? ''} `} ref={ref} diff --git a/src/components/LanguageSelector/parts/MenuItem.stories.tsx b/src/components/LanguageSelector/parts/MenuItem.stories.tsx index 8521cc2..19dcac9 100644 --- a/src/components/LanguageSelector/parts/MenuItem.stories.tsx +++ b/src/components/LanguageSelector/parts/MenuItem.stories.tsx @@ -19,7 +19,7 @@ const meta = { }, isCondensed: { description: - '`true` を指定すると、メニュー項目の高さが32pxに設定されます。(標準は44px)設置領域に制限がある場合に使用してください。\n\n使用の際は`LanguageSelectorMenu`にも`isCondensed`を設定してください。', + '`true` を指定すると、メニュー項目の高さが36pxに設定されます。(標準は44px)設置領域に制限がある場合に使用してください。\n\n使用の際は`LanguageSelectorMenu`にも`isCondensed`を設定してください。', control: { type: 'boolean' }, table: { defaultValue: { summary: 'false' }, diff --git a/src/components/LanguageSelector/parts/MenuItem.tsx b/src/components/LanguageSelector/parts/MenuItem.tsx index 283fb95..676e2e8 100644 --- a/src/components/LanguageSelector/parts/MenuItem.tsx +++ b/src/components/LanguageSelector/parts/MenuItem.tsx @@ -16,30 +16,26 @@ export const LanguageSelectorMenuItem = forwardRef< - - - + {children} diff --git a/src/components/NotificationBanner/NotificationBanner.stories.tsx b/src/components/NotificationBanner/NotificationBanner.stories.tsx index 48147d7..a3172c7 100644 --- a/src/components/NotificationBanner/NotificationBanner.stories.tsx +++ b/src/components/NotificationBanner/NotificationBanner.stories.tsx @@ -6,6 +6,7 @@ import { NotificationBannerBody } from './parts/Body'; import { NotificationBannerClose } from './parts/Close'; import { NotificationBannerHeader } from './parts/Header'; import { NotificationBannerHeading } from './parts/Heading'; +import { NotificationBannerMobileClose } from './parts/MobileClose'; const meta = { id: 'Component/DADS v2/NotificationBanner', @@ -16,7 +17,7 @@ const meta = { bannerStyle: { options: ['standard', 'color-chip'], control: { type: 'radio' }, - description: 'ノティフケーションバナーのスタイルを選択します。', + description: 'ノティフィケーションバナーのスタイルを選択します。', table: { type: { summary: "'standard' | 'color-chip'" }, }, @@ -24,7 +25,7 @@ const meta = { type: { options: ['info1', 'info2', 'warning', 'error', 'success'], control: { type: 'radio' }, - description: 'ノティフケーションバナーで通知する情報属性の種類を選択します。', + description: 'ノティフィケーションバナーで通知する情報属性の種類を選択します。', table: { type: { summary: "'info1' | 'info2' | 'warning' | 'error' | 'success'" }, }, @@ -740,3 +741,18 @@ export const ColorChipWithButtonMobileHoriz = { ); }, }; + +/** 改行が多くなる場合に備えてモバイルでコンパクトタイプの閉じるボタンを使用している例 */ +export const MobileCompact: StoryObj = { + render: () => ( + + + 登録期間が延長されました + console.log('Clicked close')} /> + + + ダミーテキストは、デザインの作成時に使用される仮の文章です。ダミーテキストは、デザインの作成時に使用される仮の文章です。ダミーテキストは、デザインの作成時に使用される仮の文章です。 + + + ), +}; diff --git a/src/components/NotificationBanner/NotificationBanner.tsx b/src/components/NotificationBanner/NotificationBanner.tsx index 8dbb42d..7c826db 100644 --- a/src/components/NotificationBanner/NotificationBanner.tsx +++ b/src/components/NotificationBanner/NotificationBanner.tsx @@ -1,13 +1,13 @@ import type { ReactNode } from 'react'; import { NotificationBannerIcon } from './parts/Icon'; import { bannerStyleClasses, bannerTypeClasses } from './styles'; -import type { NotifiationBannerStyle, NotifiationBannerType } from './types'; +import type { NotificationBannerStyle, NotificationBannerType } from './types'; type Props = { className?: string; children: ReactNode; - bannerStyle: NotifiationBannerStyle; - type: NotifiationBannerType; + bannerStyle: NotificationBannerStyle; + type: NotificationBannerType; }; export const NotificationBanner = (props: Props) => { @@ -16,14 +16,14 @@ export const NotificationBanner = (props: Props) => { return (
-
+
diff --git a/src/components/NotificationBanner/parts/Body.stories.tsx b/src/components/NotificationBanner/parts/Body.stories.tsx index dbe3dab..abd6972 100644 --- a/src/components/NotificationBanner/parts/Body.stories.tsx +++ b/src/components/NotificationBanner/parts/Body.stories.tsx @@ -12,7 +12,7 @@ const meta = { docs: { description: { component: - 'NotificationBannerBody はノティフケーションバナーのコンテンツ領域に使用します。', + 'NotificationBannerBody はノティフィケーションバナーのコンテンツ領域に使用します。', }, }, }, diff --git a/src/components/NotificationBanner/parts/Close.stories.tsx b/src/components/NotificationBanner/parts/Close.stories.tsx index 57bf610..ecd7a97 100644 --- a/src/components/NotificationBanner/parts/Close.stories.tsx +++ b/src/components/NotificationBanner/parts/Close.stories.tsx @@ -19,7 +19,8 @@ const meta = { parameters: { docs: { description: { - component: 'NotificationBannerClose はノティフケーションバナーの閉じるボタンに使用します。', + component: + 'NotificationBannerClose はノティフィケーションバナーの閉じるボタンに使用します。', }, }, }, diff --git a/src/components/NotificationBanner/parts/Close.tsx b/src/components/NotificationBanner/parts/Close.tsx index 16b5d00..348de30 100644 --- a/src/components/NotificationBanner/parts/Close.tsx +++ b/src/components/NotificationBanner/parts/Close.tsx @@ -10,31 +10,29 @@ export const NotificationBannerClose = (props: Props) => { return ( ); }; diff --git a/src/components/NotificationBanner/parts/Header.stories.tsx b/src/components/NotificationBanner/parts/Header.stories.tsx index 1414d13..5caf173 100644 --- a/src/components/NotificationBanner/parts/Header.stories.tsx +++ b/src/components/NotificationBanner/parts/Header.stories.tsx @@ -12,7 +12,7 @@ const meta = { docs: { description: { component: - 'NotificationBannerHeader はノティフケーションバナーのヘッダー領域のレイアウトに使用します。中にバナータイトルと閉じるボタンを配置することを想定して作られています。\n\n※ CSS Grid レイアウトの `subgrid` を使用しているため、NotificationBanner コンポーネント内以外で使用した場合に崩れる可能性がありますのでご注意ください。', + 'NotificationBannerHeader はノティフィケーションバナーのヘッダー領域のレイアウトに使用します。中にバナータイトルと閉じるボタンを配置することを想定して作られています。\n\n※ CSS Grid レイアウトの `subgrid` を使用しているため、NotificationBanner コンポーネント内以外で使用した場合に崩れる可能性がありますのでご注意ください。', }, }, }, diff --git a/src/components/NotificationBanner/parts/Header.tsx b/src/components/NotificationBanner/parts/Header.tsx index 5a38b7c..f43b896 100644 --- a/src/components/NotificationBanner/parts/Header.tsx +++ b/src/components/NotificationBanner/parts/Header.tsx @@ -8,7 +8,7 @@ export const NotificationBannerHeader = (props: Props) => { return (
*:last-child]:-col-end-1 ${className ?? ''} `} diff --git a/src/components/NotificationBanner/parts/Heading.stories.tsx b/src/components/NotificationBanner/parts/Heading.stories.tsx index 18e7427..8c3bbdf 100644 --- a/src/components/NotificationBanner/parts/Heading.stories.tsx +++ b/src/components/NotificationBanner/parts/Heading.stories.tsx @@ -21,7 +21,7 @@ const meta = { docs: { description: { component: - 'NotificationBannerHeading コンポーネントはノティフケーションバナーのタイトルに使用します。', + 'NotificationBannerHeading コンポーネントはノティフィケーションバナーのタイトルに使用します。', }, }, }, diff --git a/src/components/NotificationBanner/parts/Heading.tsx b/src/components/NotificationBanner/parts/Heading.tsx index be09d91..cd8e942 100644 --- a/src/components/NotificationBanner/parts/Heading.tsx +++ b/src/components/NotificationBanner/parts/Heading.tsx @@ -1,8 +1,8 @@ import type { ComponentProps } from 'react'; -import type { NotifiationBannerHeadingLevel } from '../types'; +import type { NotificationBannerHeadingLevel } from '../types'; type NotificationBannerHeadingProps = ComponentProps<'h2'> & { - level: NotifiationBannerHeadingLevel; + level: NotificationBannerHeadingLevel; }; export const NotificationBannerHeading = (props: NotificationBannerHeadingProps) => { @@ -11,7 +11,7 @@ export const NotificationBannerHeading = (props: NotificationBannerHeadingProps) return ( {children} diff --git a/src/components/NotificationBanner/parts/Icon.stories.tsx b/src/components/NotificationBanner/parts/Icon.stories.tsx index 90a2c77..2fbc9ac 100644 --- a/src/components/NotificationBanner/parts/Icon.stories.tsx +++ b/src/components/NotificationBanner/parts/Icon.stories.tsx @@ -12,7 +12,7 @@ const meta = { docs: { description: { component: - 'NotificationBannerIcon はノティフケーションバナーのバナーアイコンに使用します。NotificationBanner コンポーネントに内包されているため、単体で使う必要はありません。', + 'NotificationBannerIcon はノティフィケーションバナーのバナーアイコンに使用します。NotificationBanner コンポーネントに内包されているため、単体で使う必要はありません。', }, }, }, diff --git a/src/components/NotificationBanner/parts/Icon.tsx b/src/components/NotificationBanner/parts/Icon.tsx index 3dd58ae..5c2d089 100644 --- a/src/components/NotificationBanner/parts/Icon.tsx +++ b/src/components/NotificationBanner/parts/Icon.tsx @@ -1,5 +1,5 @@ import type { ComponentProps } from 'react'; -import type { NotifiationBannerType } from '../types'; +import type { NotificationBannerType } from '../types'; type IconProps = ComponentProps<'svg'>; @@ -105,7 +105,7 @@ const SuccessIcon = (props: IconProps) => { }; type NotificationBannerIconProps = ComponentProps<'svg'> & { - type: NotifiationBannerType; + type: NotificationBannerType; }; export const NotificationBannerIcon = (props: NotificationBannerIconProps) => { diff --git a/src/components/NotificationBanner/parts/MobileClose.stories.tsx b/src/components/NotificationBanner/parts/MobileClose.stories.tsx new file mode 100644 index 0000000..87365c0 --- /dev/null +++ b/src/components/NotificationBanner/parts/MobileClose.stories.tsx @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { NotificationBannerMobileClose } from './MobileClose'; + +const meta = { + id: 'Component/DADS v2/NotificationBanner/Parts/MobileClose', + title: 'Component/ノティフィケーションバナー/Parts/MobileClose', + component: NotificationBannerMobileClose, + tags: ['autodocs'], + parameters: { + docs: { + description: { + component: + 'NotificationBannerMobileClose はノティフィケーションバナーの閉じるボタンに使用します。', + }, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Example: Story = {}; diff --git a/src/components/NotificationBanner/parts/MobileClose.tsx b/src/components/NotificationBanner/parts/MobileClose.tsx new file mode 100644 index 0000000..0325dcd --- /dev/null +++ b/src/components/NotificationBanner/parts/MobileClose.tsx @@ -0,0 +1,26 @@ +import type { ComponentProps } from 'react'; + +type Props = ComponentProps<'button'> & {}; + +export const NotificationBannerMobileClose = (props: Props) => { + const { className, children, ...rest } = props; + + return ( + + ); +}; diff --git a/src/components/NotificationBanner/styles.ts b/src/components/NotificationBanner/styles.ts index c75a3fc..296a040 100644 --- a/src/components/NotificationBanner/styles.ts +++ b/src/components/NotificationBanner/styles.ts @@ -1,12 +1,12 @@ -import type { NotifiationBannerStyle, NotifiationBannerType } from './types'; +import type { NotificationBannerStyle, NotificationBannerType } from './types'; -export const bannerStyleClasses: { [key in NotifiationBannerStyle]: string } = { +export const bannerStyleClasses: { [key in NotificationBannerStyle]: string } = { standard: ' border-[3px] rounded-12', 'color-chip': 'border-2 !pl-6 shadow-[inset_8px_0_0_0_var(--color-chip-color)] desktop:!pl-10 desktop:shadow-[inset_16px_0_0_0_var(--color-chip-color)]', }; -export const bannerTypeClasses: { [key in NotifiationBannerType]: string } = { +export const bannerTypeClasses: { [key in NotificationBannerType]: string } = { info1: 'text-blue-900 [--color-chip-color:currentColor]', info2: 'text-solid-gray-536 [--color-chip-color:currentColor]', warning: 'text-warning-yellow-2 [--color-chip-color:theme(colors.yellow.400)]', diff --git a/src/components/NotificationBanner/types.ts b/src/components/NotificationBanner/types.ts index da7b186..4116430 100644 --- a/src/components/NotificationBanner/types.ts +++ b/src/components/NotificationBanner/types.ts @@ -1,3 +1,3 @@ -export type NotifiationBannerHeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; -export type NotifiationBannerStyle = 'standard' | 'color-chip'; -export type NotifiationBannerType = 'info1' | 'info2' | 'warning' | 'error' | 'success'; +export type NotificationBannerHeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; +export type NotificationBannerStyle = 'standard' | 'color-chip'; +export type NotificationBannerType = 'info1' | 'info2' | 'warning' | 'error' | 'success'; diff --git a/src/components/UtilityLink/UtilityLink.stories.tsx b/src/components/UtilityLink/UtilityLink.stories.tsx index 5aa6ff4..29bb745 100644 --- a/src/components/UtilityLink/UtilityLink.stories.tsx +++ b/src/components/UtilityLink/UtilityLink.stories.tsx @@ -24,6 +24,16 @@ export const Example: Story = { + Slotを使ったリンク diff --git a/src/components/UtilityLink/UtilityLink.tsx b/src/components/UtilityLink/UtilityLink.tsx index 1778e36..499b047 100644 --- a/src/components/UtilityLink/UtilityLink.tsx +++ b/src/components/UtilityLink/UtilityLink.tsx @@ -39,15 +39,15 @@ export const UtilityLinkExternalLinkIcon = (props: UtilityLinkExternalLinkIconPr diff --git a/src/docs/introduction.mdx b/src/docs/introduction.mdx new file mode 100644 index 0000000..685b019 --- /dev/null +++ b/src/docs/introduction.mdx @@ -0,0 +1,60 @@ +import { Meta, Unstyled } from "@storybook/addon-docs/blocks"; +import { Link, Ul } from './../'; + + + + +
+ +# デジタル庁デザインシステム コードスニペット(React版) + +[デジタル庁デザインシステム](https://design.digital.go.jp/)をReact/Tailwind CSSで実装したサンプル集です。[HTML版はこちら](https://design.digital.go.jp/dads/html/)。 + +## コンセプト + +### アクセシビリティファースト + +アクセシビリティを最優先事項として位置付けています。 + +公開されているすべてのコンポーネントは、[WCAG](https://waic.jp/translations/WCAG22/)等のアクセシビリティガイドラインを最大限に取り込んだデジタル庁デザインシステムのガイドラインを基に作られており、アクセシビリティの専門家によるチェックも受けています。 + +これにより、デジタル庁デザインシステムのコンポーネントを使うことで、WCAGの各達成基準に適合または適合が容易になります。 + +### HTML ネイティブ機能の活用 + +保守性の観点から、可能な限りHTMLネイティブの機能を使用することを重視して開発をしています。 + +[HTML Living Standard](https://html.spec.whatwg.org)や[Open UI](https://open-ui.org/)の動向を常に確認し、新しいHTMLネイティブの機能が利用可能になった際には、既存の実装を最新の標準に置き換えていきます。この取り組みにより、一部のブラウザではまだ実装されていない最新機能を試験的に導入することもあります。 + +HTMLネイティブ機能だけでは実現できないコンポーネントに関しては、ヘッドレスUIライブラリの使用を推奨します。 + +一部のサンプルコードでは、Reactの機能を使った実装も提供していますので、実装の参考にしてください。WAI-ARIAやキーボード操作などの挙動については[ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/)の[Patterns](https://www.w3.org/WAI/ARIA/apg/patterns/)を参考にして実装しています。 + +## コンポーネントのバージョンについて + +DADS v2はv2.0.0以降の最新のガイドラインとデザインデータを基に作られたコンポーネントです。 + +v1.x系統が基となっているDADS v1のコンポーネントは非推奨となっています。それらのコンポーネントのガイドラインとデザインデータがv2に追加され次第、順次DADS v2に置き換えていく予定です。 + +## 検証済み環境 + +下記のブラウザで動作を確認しています。 + +- Google Chrome最新版 +- Microsoft Edge最新版 +- Safari最新版 +- Firefox最新版 + +下記のスクリーンリーダーでも動作を確認しています。 + +- NVDA +- iOS VoiceOver +- TalkBack +- Mac VoiceOver + +## 不具合報告・機能要望について + +本コードスニペットに関する不具合や機能要望は、[GitHubのリポジトリ](https://github.com/digital-go-jp/design-system-example-components)からIssueを作成して報告してください。 + +
+
diff --git a/src/docs/introduction.stories.tsx b/src/docs/introduction.stories.tsx deleted file mode 100644 index 7249562..0000000 --- a/src/docs/introduction.stories.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react-vite'; -import React, { Fragment } from 'react'; -import { Link, Ul } from './../'; - -const meta = { - title: 'Getting Started/Introduction', - component: Fragment, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Introduction: Story = { - render: () => { - return ( -
-

- React サンプルコンポーネント -

-

- - デジタル庁デザインシステム - - のコンポーネントの一部をReact / Tailwind CSSベースで実装したサンプル集です。 -

-

コンセプト

-

- アクセシビリティファースト -

-

アクセシビリティを最優先事項として位置付けています。

-

- 公開されているすべてのコンポーネントは、 - - WCAG - - 等のアクセシビリティガイドラインを最大限に取り込んだデジタル庁デザインシステムのガイドラインを基に作られており、アクセシビリティの専門家によるチェックも受けています。 -

-

- これにより、デジタル庁デザインシステムのコンポーネントを使うことで、WCAGの各達成基準に適合または適合が容易になります。 -

-

- HTML ネイティブ機能の活用 -

-

- 保守性の観点から、可能な限りHTMLネイティブの機能を使用することを重視して開発をしています。 -

-

- - HTML Living Standard - - や - - Open UI - - の動向を常に確認し、新しい - HTMLネイティブの機能が利用可能になった際には、既存の実装を最新の標準に置き換えていきます。この取り組みにより、一部のブラウザではまだ実装されていない最新機能を試験的に導入することもあります。 -

-

- HTMLネイティブ機能だけでは実現できないコンポーネントに関しては、ヘッドレスUIライブラリの使用を推奨します。 -

-

- 一部のサンプルコードでは、Reactの機能を使った実装も提供していますので、実装の参考にしてください。WAI-ARIAやキーボード操作などの挙動については - - ARIA Authoring Practices Guide (APG) - - の - - Patterns - - を参考にして実装しています。 -

- -

- コンポーネントのバージョンについて -

-

- DADS v2はv2.0.0以降の最新のガイドラインとデザインデータを基に作られたコンポーネントです。 -

-

- v1.x系統が基となっているDADS - v1のコンポーネントは非推奨となっています。それらのコンポーネントのガイドラインとデザインデータがv2に追加され次第、順次DADS - v2に置き換えていく予定です。 -

-

検証済み環境

-

以下のブラウザの最新版で動作確認を行なっています。

-
    -
  • Google Chrome
  • -
  • Microsoft Edge
  • -
  • Safari
  • -
  • Firefox
  • -
-

また、以下のスクリーンリーダーでも動作検証を行なっています。

-
    -
  • NVDA
  • -
  • iOS VoiceOver
  • -
  • TalkBack
  • -
  • Mac VoiceOver
  • -
-

リソース

-

- デジタル庁が提供する、デジタル庁デザインシステムのガイドラインやデザインデータなど、連携可能な各種リソースです。用途の必要性に応じてあわせてご利用ください。 -

-
    -
  • - - デジタル庁デザインシステムウェブサイト(ガイドライン) - -
  • -
  • - - デザインデータ(Figma) - -
  • -
  • - - ウェブアクセシビリティ導入ガイドブック - -
  • -
-

- 不具合報告・機能要望について -

-

- コンポーネントに関する不具合や機能要望は、 - - GitHubのリポジトリ - - からIssueを作成して報告してください。 -

-
- ); - }, -};