@lism-css/ui 0.10.0 → 0.12.0

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.
Files changed (209) hide show
  1. package/README.md +1 -1
  2. package/dist/components/Accordion/Accordion.stories.d.ts +7 -0
  3. package/dist/components/Accordion/getProps.d.ts +55 -42
  4. package/dist/components/Accordion/getProps.js +36 -32
  5. package/dist/components/Accordion/react/AccIcon.d.ts +2 -1
  6. package/dist/components/Accordion/react/Accordion.d.ts +12 -21
  7. package/dist/components/Accordion/react/Accordion.js +30 -29
  8. package/dist/components/Accordion/react/index.d.ts +10 -11
  9. package/dist/components/Accordion/setAccordion.d.ts +6 -3
  10. package/dist/components/Accordion/setAccordion.js +12 -10
  11. package/dist/components/Alert/Alert.stories.d.ts +13 -0
  12. package/dist/components/Alert/getProps.d.ts +6 -4
  13. package/dist/components/Alert/react/Alert.d.ts +3 -4
  14. package/dist/components/Alert/react/Alert.js +2 -2
  15. package/dist/components/Avatar/Avatar.stories.d.ts +8 -0
  16. package/dist/components/Avatar/react/Avatar.d.ts +10 -6
  17. package/dist/components/Avatar/react/Avatar.js +1 -1
  18. package/dist/components/Badge/Badge.stories.d.ts +8 -0
  19. package/dist/components/Badge/react/Badge.d.ts +3 -1
  20. package/dist/components/Badge/react/Badge.js +5 -8
  21. package/dist/components/Button/Button.stories.d.ts +8 -0
  22. package/dist/components/Button/react/Button.d.ts +3 -1
  23. package/dist/components/Button/react/Button.js +3 -6
  24. package/dist/components/Callout/Callout.stories.d.ts +12 -0
  25. package/dist/components/Callout/getProps.d.ts +3 -3
  26. package/dist/components/Callout/getProps.js +11 -12
  27. package/dist/components/Callout/react/Callout.d.ts +3 -4
  28. package/dist/components/Callout/react/Callout.js +4 -4
  29. package/dist/components/Chat/Chat.stories.d.ts +9 -0
  30. package/dist/components/Chat/getProps.d.ts +43 -44
  31. package/dist/components/Chat/getProps.js +2 -2
  32. package/dist/components/Chat/react/Chat.d.ts +11 -7
  33. package/dist/components/Chat/react/Chat.js +10 -10
  34. package/dist/components/Details/Details.stories.d.ts +6 -0
  35. package/dist/components/Details/getProps.d.ts +34 -35
  36. package/dist/components/Details/getProps.js +16 -6
  37. package/dist/components/Details/react/Details.d.ts +11 -20
  38. package/dist/components/Details/react/Details.js +15 -15
  39. package/dist/components/Details/react/index.d.ts +7 -7
  40. package/dist/components/DummyImage/DummyImage.stories.d.ts +7 -0
  41. package/dist/components/DummyText/DummyText.stories.d.ts +9 -0
  42. package/dist/components/Modal/Modal.stories.d.ts +6 -0
  43. package/dist/components/Modal/getProps.d.ts +36 -36
  44. package/dist/components/Modal/getProps.js +36 -17
  45. package/dist/components/Modal/react/Body.d.ts +2 -4
  46. package/dist/components/Modal/react/CloseBtn.d.ts +9 -7
  47. package/dist/components/Modal/react/CloseBtn.js +5 -5
  48. package/dist/components/Modal/react/Inner.d.ts +3 -4
  49. package/dist/components/Modal/react/Modal.d.ts +4 -4
  50. package/dist/components/Modal/react/Modal.js +11 -9
  51. package/dist/components/Modal/react/OpenBtn.d.ts +7 -5
  52. package/dist/components/Modal/react/OpenBtn.js +4 -4
  53. package/dist/components/Modal/react/index.d.ts +7 -8
  54. package/dist/components/NavMenu/NavMenu.stories.d.ts +7 -0
  55. package/dist/components/NavMenu/getProps.d.ts +31 -29
  56. package/dist/components/NavMenu/react/NavMenu.d.ts +6 -16
  57. package/dist/components/NavMenu/react/NavMenu.js +21 -17
  58. package/dist/components/NavMenu/react/index.d.ts +6 -6
  59. package/dist/components/ShapeDivider/ShapeDivider.stories.d.ts +10 -0
  60. package/dist/components/ShapeDivider/getProps.d.ts +16 -11
  61. package/dist/components/ShapeDivider/getProps.js +10 -12
  62. package/dist/components/ShapeDivider/react/ShapeDivider.d.ts +3 -4
  63. package/dist/components/ShapeDivider/react/ShapeDivider.js +3 -3
  64. package/dist/components/Tabs/Tabs.stories.d.ts +6 -0
  65. package/dist/components/Tabs/getProps.d.ts +11 -4
  66. package/dist/components/Tabs/getProps.js +14 -4
  67. package/dist/components/Tabs/react/Tab.d.ts +8 -6
  68. package/dist/components/Tabs/react/Tab.js +15 -6
  69. package/dist/components/Tabs/react/TabItem.d.ts +7 -4
  70. package/dist/components/Tabs/react/TabList.d.ts +2 -1
  71. package/dist/components/Tabs/react/TabPanel.d.ts +8 -6
  72. package/dist/components/Tabs/react/Tabs.d.ts +9 -7
  73. package/dist/components/Tabs/react/Tabs.js +50 -36
  74. package/dist/components/Tabs/react/index.d.ts +8 -8
  75. package/dist/components/Tabs/setTabs.d.ts +1 -1
  76. package/dist/components/Tabs/setTabs.js +25 -15
  77. package/dist/lism-css/dist/components/{Center → layout/Center}/index.js +1 -1
  78. package/dist/lism-css/dist/components/{Flex → layout/Flex}/index.js +1 -1
  79. package/dist/lism-css/dist/components/{Flow → layout/Flow}/index.js +1 -1
  80. package/dist/lism-css/dist/components/{Frame → layout/Frame}/index.js +1 -1
  81. package/dist/lism-css/dist/components/{Grid → layout/Grid}/index.js +1 -1
  82. package/dist/lism-css/dist/components/{Stack → layout/Stack}/index.js +1 -1
  83. package/dist/lism-css/dist/config/defaults/props.js +16 -26
  84. package/dist/lism-css/dist/config/defaults/states.js +3 -24
  85. package/dist/lism-css/dist/config/defaults/tokens.js +2 -2
  86. package/dist/lism-css/dist/lib/getLayoutProps.js +6 -9
  87. package/dist/lism-css/dist/lib/getLismProps.js +94 -92
  88. package/dist/lism-css/dist/lib/helper/mergeSet.js +14 -0
  89. package/dist/style.css +1 -1
  90. package/dist/ui.css +1 -1
  91. package/package.json +14 -7
  92. package/src/components/Accordion/Accordion.stories.tsx +105 -0
  93. package/src/components/Accordion/astro/Button.astro +2 -2
  94. package/src/components/Accordion/getProps.ts +91 -0
  95. package/src/components/Accordion/react/{AccIcon.jsx → AccIcon.tsx} +2 -2
  96. package/src/components/Accordion/react/{Accordion.jsx → Accordion.tsx} +33 -11
  97. package/src/components/Accordion/setAccordion.ts +120 -0
  98. package/src/components/Alert/Alert.stories.tsx +64 -0
  99. package/src/components/Alert/getProps.ts +5 -3
  100. package/src/components/Alert/react/Alert.tsx +3 -3
  101. package/src/components/Avatar/Avatar.stories.tsx +42 -0
  102. package/src/components/Avatar/react/Avatar.tsx +17 -0
  103. package/src/components/Badge/Badge.stories.tsx +40 -0
  104. package/src/components/Badge/astro/Badge.astro +1 -7
  105. package/src/components/Badge/react/Badge.tsx +7 -0
  106. package/src/components/Button/Button.stories.tsx +44 -0
  107. package/src/components/Button/astro/Button.astro +1 -7
  108. package/src/components/Button/react/Button.tsx +7 -0
  109. package/src/components/Callout/Callout.stories.tsx +55 -0
  110. package/src/components/Callout/getProps.ts +5 -5
  111. package/src/components/Callout/react/Callout.tsx +3 -3
  112. package/src/components/Chat/Chat.stories.tsx +58 -0
  113. package/src/components/Chat/_style.css +5 -5
  114. package/src/components/Chat/{getProps.js → getProps.ts} +10 -4
  115. package/src/components/Chat/react/{Chat.jsx → Chat.tsx} +13 -3
  116. package/src/components/Details/Details.stories.tsx +61 -0
  117. package/src/components/Details/astro/Title.astro +2 -2
  118. package/src/components/Details/{getProps.js → getProps.ts} +19 -6
  119. package/src/components/Details/react/Details.tsx +69 -0
  120. package/src/components/DummyImage/DummyImage.stories.tsx +23 -0
  121. package/src/components/DummyText/DummyText.stories.tsx +48 -0
  122. package/src/components/Modal/Modal.stories.tsx +67 -0
  123. package/src/components/Modal/astro/CloseBtn.astro +2 -2
  124. package/src/components/Modal/astro/OpenBtn.astro +2 -3
  125. package/src/components/Modal/getProps.ts +65 -0
  126. package/src/components/Modal/react/Body.tsx +10 -0
  127. package/src/components/Modal/react/CloseBtn.tsx +24 -0
  128. package/src/components/Modal/react/Inner.tsx +6 -0
  129. package/src/components/Modal/react/Modal.tsx +24 -0
  130. package/src/components/Modal/react/OpenBtn.tsx +15 -0
  131. package/src/components/Modal/{script.js → script.ts} +1 -1
  132. package/src/components/NavMenu/NavMenu.stories.tsx +68 -0
  133. package/src/components/NavMenu/getProps.ts +60 -0
  134. package/src/components/NavMenu/react/NavMenu.tsx +40 -0
  135. package/src/components/ShapeDivider/ShapeDivider.stories.tsx +87 -0
  136. package/src/components/ShapeDivider/getProps.ts +36 -0
  137. package/src/components/ShapeDivider/react/{ShapeDivider.jsx → ShapeDivider.tsx} +4 -4
  138. package/src/components/Tabs/Tabs.stories.tsx +79 -0
  139. package/src/components/Tabs/astro/Tab.astro +2 -1
  140. package/src/components/Tabs/astro/{transformTabitems.js → transformTabitems.ts} +9 -9
  141. package/src/components/Tabs/getProps.ts +23 -0
  142. package/src/components/Tabs/react/Tab.tsx +21 -0
  143. package/src/components/Tabs/react/TabItem.tsx +13 -0
  144. package/src/components/Tabs/react/TabList.tsx +5 -0
  145. package/src/components/Tabs/react/{TabPanel.jsx → TabPanel.tsx} +8 -3
  146. package/src/components/Tabs/react/{Tabs.jsx → Tabs.tsx} +27 -12
  147. package/src/components/Tabs/{script.js → script.ts} +2 -2
  148. package/src/components/Tabs/setTabs.ts +65 -0
  149. package/src/helper/{uuid.js → uuid.ts} +2 -2
  150. package/src/vite-env.d.ts +1 -0
  151. package/dist/components/Accordion/astro/__setEvent.d.ts +0 -1
  152. package/dist/components/Accordion/astro/index.d.ts +0 -15
  153. package/dist/components/Alert/astro/index.d.ts +0 -1
  154. package/dist/components/Callout/astro/index.d.ts +0 -1
  155. package/dist/components/Details/astro/index.d.ts +0 -13
  156. package/dist/components/DummyImage/astro/index.d.ts +0 -1
  157. package/dist/components/DummyText/astro/index.d.ts +0 -1
  158. package/dist/components/Modal/astro/index.d.ts +0 -13
  159. package/dist/components/NavMenu/astro/index.d.ts +0 -11
  160. package/dist/components/Tabs/astro/index.d.ts +0 -13
  161. package/dist/components/Tabs/astro/transformTabitems.d.ts +0 -4
  162. package/dist/components/astro.d.ts +0 -14
  163. package/dist/lism-css/dist/config/helper/getSvgUrl.js +0 -4
  164. package/src/components/Accordion/getProps.js +0 -77
  165. package/src/components/Accordion/setAccordion.js +0 -146
  166. package/src/components/Avatar/astro/index.js +0 -1
  167. package/src/components/Avatar/react/Avatar.jsx +0 -9
  168. package/src/components/Badge/astro/index.js +0 -1
  169. package/src/components/Badge/react/Badge.jsx +0 -12
  170. package/src/components/Button/astro/index.js +0 -1
  171. package/src/components/Button/react/Button.jsx +0 -12
  172. package/src/components/Chat/astro/index.js +0 -1
  173. package/src/components/Details/react/Details.jsx +0 -66
  174. package/src/components/Modal/getProps.js +0 -30
  175. package/src/components/Modal/react/Body.jsx +0 -10
  176. package/src/components/Modal/react/CloseBtn.jsx +0 -20
  177. package/src/components/Modal/react/Inner.jsx +0 -6
  178. package/src/components/Modal/react/Modal.jsx +0 -23
  179. package/src/components/Modal/react/OpenBtn.jsx +0 -11
  180. package/src/components/NavMenu/getProps.js +0 -65
  181. package/src/components/NavMenu/react/NavMenu.jsx +0 -19
  182. package/src/components/ShapeDivider/astro/index.js +0 -1
  183. package/src/components/ShapeDivider/getProps.js +0 -40
  184. package/src/components/Tabs/getProps.js +0 -8
  185. package/src/components/Tabs/react/Tab.jsx +0 -10
  186. package/src/components/Tabs/react/TabItem.jsx +0 -5
  187. package/src/components/Tabs/react/TabList.jsx +0 -6
  188. package/src/components/Tabs/setTabs.js +0 -87
  189. /package/src/components/Accordion/astro/{index.js → index.ts} +0 -0
  190. /package/src/components/Accordion/react/{index.js → index.ts} +0 -0
  191. /package/src/components/Accordion/{script.js → script.ts} +0 -0
  192. /package/{dist/components/Avatar/astro/index.d.ts → src/components/Avatar/astro/index.ts} +0 -0
  193. /package/src/components/Avatar/react/{index.js → index.ts} +0 -0
  194. /package/{dist/components/Badge/astro/index.d.ts → src/components/Badge/astro/index.ts} +0 -0
  195. /package/src/components/Badge/react/{index.js → index.ts} +0 -0
  196. /package/{dist/components/Button/astro/index.d.ts → src/components/Button/astro/index.ts} +0 -0
  197. /package/src/components/Button/react/{index.js → index.ts} +0 -0
  198. /package/{dist/components/Chat/astro/index.d.ts → src/components/Chat/astro/index.ts} +0 -0
  199. /package/src/components/Chat/react/{index.js → index.ts} +0 -0
  200. /package/src/components/Details/astro/{index.js → index.ts} +0 -0
  201. /package/src/components/Details/react/{index.js → index.ts} +0 -0
  202. /package/src/components/Modal/astro/{index.js → index.ts} +0 -0
  203. /package/src/components/Modal/react/{index.js → index.ts} +0 -0
  204. /package/src/components/NavMenu/astro/{index.js → index.ts} +0 -0
  205. /package/src/components/NavMenu/react/{index.js → index.ts} +0 -0
  206. /package/{dist/components/ShapeDivider/astro/index.d.ts → src/components/ShapeDivider/astro/index.ts} +0 -0
  207. /package/src/components/ShapeDivider/react/{index.js → index.ts} +0 -0
  208. /package/src/components/Tabs/astro/{index.js → index.ts} +0 -0
  209. /package/src/components/Tabs/react/{index.js → index.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  @layer lism-modules {
2
2
  .c--chat {
3
3
  --cbox-bgPct: 8%;
4
- --gta: 'avatar name' 'avatar body';
5
- --gtc: auto 1fr;
6
- --gtr: minmax(1.5rem, auto) auto;
4
+ grid-template-areas: 'avatar name' 'avatar body';
5
+ grid-template-columns: auto 1fr;
6
+ grid-template-rows: minmax(1.5rem, auto) auto;
7
7
  --_avator-size: clamp(48px, 32px + 5cqw, 64px); /* @320px:40px ~ @640:64px */
8
8
  --_deco-size: calc(min(var(--_avator-size), 80px) / 4 + 0.25rem);
9
9
  --_deco-mask: none;
@@ -46,8 +46,8 @@
46
46
  [data-chat-dir='end'] {
47
47
  --_deco-scale: -1 1;
48
48
  --_deco-inset-x: calc(100% - 1px) auto;
49
- --gta: 'name avatar' 'body avatar';
50
- --gtc: 1fr auto;
49
+ grid-template-areas: 'name avatar' 'body avatar';
50
+ grid-template-columns: 1fr auto;
51
51
  }
52
52
  }
53
53
 
@@ -2,7 +2,6 @@
2
2
  * Chat コンポーネントの共通プロパティ処理
3
3
  */
4
4
 
5
- // 各サブ要素のデフォルトプロパティ
6
5
  export const defaultProps = {
7
6
  avatar: {
8
7
  lismClass: 'c--chat_avatar',
@@ -23,11 +22,11 @@ export const defaultProps = {
23
22
  },
24
23
  body: {
25
24
  lismClass: 'c--chat_body',
26
- pos: 'rel',
25
+ pos: 'relative',
27
26
  },
28
27
  deco: {
29
28
  lismClass: 'c--chat_deco',
30
- pos: 'abs',
29
+ pos: 'absolute',
31
30
  },
32
31
  content: {
33
32
  lismClass: 'c--chat_content',
@@ -35,12 +34,19 @@ export const defaultProps = {
35
34
  p: '20',
36
35
  lh: 's',
37
36
  },
37
+ } as const;
38
+
39
+ export type ChatProps = {
40
+ variant?: string;
41
+ direction?: string;
42
+ keycolor?: string;
43
+ [key: string]: unknown;
38
44
  };
39
45
 
40
46
  /**
41
47
  * Chat コンポーネントのルートプロパティを生成
42
48
  */
43
- export default function getChatProps({ variant = 'speak', direction = 'start', keycolor = 'gray', ...props }) {
49
+ export default function getChatProps({ variant = 'speak', direction = 'start', keycolor = 'gray', ...props }: ChatProps) {
44
50
  return {
45
51
  lismClass: 'c--chat',
46
52
  variant,
@@ -1,14 +1,24 @@
1
- import { Lism, Flow, Grid, Frame, Decorator } from 'lism-css/react';
1
+ import type { ElementType } from 'react';
2
+ import { Lism, Flow, Grid, Frame, Decorator, type LayoutComponentProps } from 'lism-css/react';
3
+ import type { GridLayoutProps } from 'lism-css/lib/types/LayoutProps';
2
4
  import getChatProps, { defaultProps } from '../getProps';
5
+ import type { ChatProps } from '../getProps';
3
6
  import '../_style.css';
4
7
 
5
- export default function Chat({ name, avatar, flow = 's', children, ...props }) {
8
+ type Props<T extends ElementType = 'div'> = ChatProps &
9
+ LayoutComponentProps<T, GridLayoutProps> & {
10
+ name?: string;
11
+ avatar?: string;
12
+ flow?: string;
13
+ };
14
+
15
+ export default function Chat<T extends ElementType = 'div'>({ name, avatar, flow = 's', children, ...props }: Props<T>) {
6
16
  const { 'data-chat-dir': direction, ...chatProps } = getChatProps(props);
7
17
 
8
18
  return (
9
19
  <Grid data-chat-dir={direction} {...chatProps}>
10
20
  {avatar && (
11
- <Frame {...defaultProps.avatar} src={avatar} alt="">
21
+ <Frame {...defaultProps.avatar}>
12
22
  <img src={avatar} alt="" width="60" height="60" decoding="async" />
13
23
  </Frame>
14
24
  )}
@@ -0,0 +1,61 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { expect, userEvent, within } from 'storybook/test';
3
+ import Details from './react';
4
+
5
+ const meta: Meta = {
6
+ title: 'UI/Details',
7
+ tags: ['autodocs'],
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <Details.Root>
16
+ <Details.Summary>
17
+ <Details.Icon>▶</Details.Icon>
18
+ <Details.Title>詳細を見る</Details.Title>
19
+ </Details.Summary>
20
+ <Details.Content>
21
+ <p>詳細コンテンツです。クリックで開閉できます。</p>
22
+ </Details.Content>
23
+ </Details.Root>
24
+ ),
25
+ play: async ({ canvasElement }) => {
26
+ const details = within(canvasElement).getByRole('group'); // <details>
27
+ const summary = details.querySelector('summary') as HTMLElement;
28
+
29
+ // 初期状態: 閉じている
30
+ await expect(details).not.toHaveAttribute('open');
31
+
32
+ // クリックで開く
33
+ await userEvent.click(summary);
34
+ await expect(details).toHaveAttribute('open');
35
+
36
+ // 再クリックで閉じる
37
+ await userEvent.click(summary);
38
+ await expect(details).not.toHaveAttribute('open');
39
+ },
40
+ };
41
+
42
+ export const OpenByDefault: Story = {
43
+ name: '初期展開状態',
44
+ render: () => (
45
+ <Details.Root open>
46
+ <Details.Summary>
47
+ <Details.Icon>▼</Details.Icon>
48
+ <Details.Title>最初から開いている詳細</Details.Title>
49
+ </Details.Summary>
50
+ <Details.Content>
51
+ <p>open 属性を付けると初期状態で展開されます。</p>
52
+ </Details.Content>
53
+ </Details.Root>
54
+ ),
55
+ play: async ({ canvasElement }) => {
56
+ const details = within(canvasElement).getByRole('group'); // <details>
57
+
58
+ // 初期状態: 開いている(open 属性あり)
59
+ await expect(details).toHaveAttribute('open');
60
+ },
61
+ };
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  import { Lism } from 'lism-css/astro';
3
- import { defaultProps } from '../getProps';
3
+ import { getTitleProps } from '../getProps';
4
4
 
5
5
  const props = Astro.props || {};
6
6
  ---
7
7
 
8
- <Lism {...defaultProps.title} {...props}>
8
+ <Lism {...getTitleProps(props)}>
9
9
  <slot />
10
10
  </Lism>
@@ -1,23 +1,36 @@
1
1
  import atts from 'lism-css/lib/helper/atts';
2
+ import mergeSet from 'lism-css/lib/helper/mergeSet';
3
+ import type { LismProps } from 'lism-css/lib/getLismProps';
4
+
5
+ export type DetailsProps = {
6
+ lismClass?: string;
7
+ [key: string]: unknown;
8
+ };
2
9
 
3
10
  /**
4
11
  * Detailsコンポーネントのルート要素用プロパティを生成
5
- * @param {Object} props - コンポーネントのプロパティ
6
- * @param {string} props.lismClass - 追加のLismクラス
7
- * @returns {Object} 処理済みプロパティ
8
12
  */
9
- export function getDetailsProps({ lismClass, ...props }) {
13
+ export function getDetailsProps({ lismClass, ...props }: DetailsProps): LismProps {
10
14
  props.lismClass = atts(lismClass, 'c--details');
11
15
  return props;
12
16
  }
13
17
 
18
+ export function getTitleProps({ set, unset, ...props }: Record<string, unknown>) {
19
+ return {
20
+ lismClass: 'c--details_title',
21
+ as: 'span',
22
+ fx: '1',
23
+ set: mergeSet('plain', set, unset),
24
+ ...props,
25
+ };
26
+ }
27
+
14
28
  /**
15
29
  * 各サブコンポーネント用のデフォルトプロパティ
16
30
  */
17
31
  export const defaultProps = {
18
32
  summary: { lismClass: 'c--details_summary', layout: 'flex', g: '10', ai: 'center' },
19
- title: { lismClass: 'c--details_title', as: 'span', fx: '1', setPlain: 1 },
20
33
  icon: { lismClass: 'c--details_icon a--icon', as: 'span', 'aria-hidden': 'true' },
21
34
  body: { lismClass: 'c--details_body' },
22
35
  content: { lismClass: 'c--details_content', layout: 'flow', flow: 's' },
23
- };
36
+ } as const;
@@ -0,0 +1,69 @@
1
+ /**
2
+ * React版 Detailsコンポーネント
3
+ */
4
+ import type { ElementType } from 'react';
5
+ import getLismProps from 'lism-css/lib/getLismProps';
6
+ import { Lism, type LismComponentProps } from 'lism-css/react';
7
+ import { getDetailsProps, getTitleProps, defaultProps } from '../getProps';
8
+
9
+ // スタイルのインポート
10
+ import '../_style.css';
11
+
12
+ type DetailsRootProps = LismComponentProps<'details'> & { open?: boolean };
13
+
14
+ /**
15
+ * Details - ルートコンポーネント
16
+ * details要素をレンダリング
17
+ */
18
+ export function Details({ children, open, ...props }: DetailsRootProps) {
19
+ const lismProps = getLismProps(getDetailsProps(props));
20
+
21
+ return (
22
+ <details open={open} {...lismProps}>
23
+ {children}
24
+ </details>
25
+ );
26
+ }
27
+
28
+ /**
29
+ * Summary - サマリーコンポーネント
30
+ * details要素のsummary部分
31
+ */
32
+ export function Summary<T extends ElementType = 'summary'>({ children, ...props }: LismComponentProps<T>) {
33
+ return (
34
+ <Lism as="summary" {...(defaultProps.summary as object)} {...(props as object)}>
35
+ {children}
36
+ </Lism>
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Title - タイトルコンポーネント
42
+ */
43
+ export function Title<T extends ElementType = 'span'>({ children, ...props }: LismComponentProps<T>) {
44
+ return <Lism {...(getTitleProps(props as Record<string, unknown>) as object)}>{children}</Lism>;
45
+ }
46
+
47
+ /**
48
+ * Icon - アイコンコンポーネント
49
+ */
50
+ export function Icon<T extends ElementType = 'span'>({ children, ...props }: LismComponentProps<T>) {
51
+ return (
52
+ <Lism {...(defaultProps.icon as object)} {...(props as object)}>
53
+ {children}
54
+ </Lism>
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Content - コンテンツコンポーネント
60
+ */
61
+ export function Content<T extends ElementType = 'div'>({ children, ...props }: LismComponentProps<T>) {
62
+ return (
63
+ <Lism {...defaultProps.body}>
64
+ <Lism {...(defaultProps.content as object)} {...(props as object)}>
65
+ {children}
66
+ </Lism>
67
+ </Lism>
68
+ );
69
+ }
@@ -0,0 +1,23 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import DummyImage from './react/DummyImage';
3
+
4
+ const meta: Meta<typeof DummyImage> = {
5
+ title: 'UI/DummyImage',
6
+ component: DummyImage,
7
+ tags: ['autodocs'],
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj<typeof DummyImage>;
12
+
13
+ export const Default: Story = {
14
+ args: {},
15
+ };
16
+
17
+ export const WithSize: Story = {
18
+ name: 'サイズ指定',
19
+ args: {
20
+ w: '300px',
21
+ h: '200px',
22
+ },
23
+ };
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import DummyText from './react/DummyText';
3
+
4
+ const meta: Meta<typeof DummyText> = {
5
+ title: 'UI/DummyText',
6
+ component: DummyText,
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ lang: { control: 'select', options: ['en', 'ja', 'ar'] },
10
+ length: { control: 'select', options: ['s', 'm', 'l'] },
11
+ offset: { control: 'number' },
12
+ pre: { control: 'text' },
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof DummyText>;
18
+
19
+ export const Default: Story = {
20
+ args: {
21
+ lang: 'en',
22
+ length: 'm',
23
+ },
24
+ };
25
+
26
+ export const Japanese: Story = {
27
+ name: '日本語',
28
+ args: {
29
+ lang: 'ja',
30
+ length: 'm',
31
+ },
32
+ };
33
+
34
+ export const Short: Story = {
35
+ name: '短い(length: s)',
36
+ args: {
37
+ lang: 'en',
38
+ length: 's',
39
+ },
40
+ };
41
+
42
+ export const Long: Story = {
43
+ name: '長い(length: l)',
44
+ args: {
45
+ lang: 'en',
46
+ length: 'l',
47
+ },
48
+ };
@@ -0,0 +1,67 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { expect, userEvent, within, waitFor } from 'storybook/test';
3
+ import Modal from './react';
4
+
5
+ const meta: Meta = {
6
+ title: 'UI/Modal',
7
+ tags: ['autodocs'],
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <>
16
+ <Modal.OpenBtn modalId="story-modal-1">モーダルを開く</Modal.OpenBtn>
17
+ <Modal.Root id="story-modal-1">
18
+ <Modal.Inner>
19
+ <Modal.Body>
20
+ <p>モーダルのコンテンツです。</p>
21
+ </Modal.Body>
22
+ <Modal.CloseBtn modalId="story-modal-1">閉じる</Modal.CloseBtn>
23
+ </Modal.Inner>
24
+ </Modal.Root>
25
+ </>
26
+ ),
27
+ play: async ({ canvasElement }) => {
28
+ const canvas = within(canvasElement);
29
+
30
+ const dialog = canvas.getByRole('dialog', { hidden: true });
31
+ const openBtn = canvas.getByRole('button', { name: 'モーダルを開く' });
32
+
33
+ // 初期状態: モーダルは閉じている
34
+ await expect(dialog).not.toHaveAttribute('open');
35
+
36
+ // 開くボタンをクリック
37
+ await userEvent.click(openBtn);
38
+
39
+ // モーダルが開いている
40
+ await waitFor(() => expect(dialog).toHaveAttribute('open'));
41
+
42
+ // 閉じるボタンをクリック
43
+ const closeBtn = within(dialog).getByRole('button', { name: '閉じる' });
44
+ await userEvent.click(closeBtn);
45
+
46
+ // モーダルが閉じている(アニメーション完了待ち)
47
+ await waitFor(() => expect(dialog).not.toHaveAttribute('open'), { timeout: 2000 });
48
+ },
49
+ };
50
+
51
+ export const WithTitle: Story = {
52
+ name: 'タイトル付き',
53
+ render: () => (
54
+ <>
55
+ <Modal.OpenBtn modalId="story-modal-2">モーダルを開く</Modal.OpenBtn>
56
+ <Modal.Root id="story-modal-2">
57
+ <Modal.Inner>
58
+ <Modal.Body>
59
+ <h2>モーダルタイトル</h2>
60
+ <p>モーダルのコンテンツです。</p>
61
+ </Modal.Body>
62
+ <Modal.CloseBtn modalId="story-modal-2">閉じる</Modal.CloseBtn>
63
+ </Modal.Inner>
64
+ </Modal.Root>
65
+ </>
66
+ ),
67
+ };
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  // import type { LismProps } from 'lism-css/types';
3
3
  import { Lism, Icon } from 'lism-css/astro';
4
- import { defaultProps } from '../getProps';
4
+ import { getCloseBtnProps } from '../getProps';
5
5
 
6
6
  // Propsの定義
7
7
  // interface Props extends LismProps {}
8
8
  const { modalId = '', icon, srText = 'Close', ...props } = Astro.props || {};
9
- const btnProps = { ...defaultProps.closeBtn, ...props };
9
+ const btnProps = getCloseBtnProps(props);
10
10
  ---
11
11
 
12
12
  {
@@ -1,14 +1,13 @@
1
1
  ---
2
2
  // import type { LismProps } from 'lism-css/types';
3
3
  import { Lism } from 'lism-css/astro';
4
- import { defaultProps } from '../getProps';
4
+ import { getOpenBtnProps } from '../getProps';
5
5
 
6
6
  // Propsの定義
7
7
  // interface Props extends LismProps {}
8
8
  const { modalId = '', ...props } = Astro.props || {};
9
- const btnProps = { ...defaultProps.openBtn, ...props };
10
9
  ---
11
10
 
12
- <Lism data-modal-open={modalId} {...btnProps}>
11
+ <Lism data-modal-open={modalId} {...getOpenBtnProps(props)}>
13
12
  <slot />
14
13
  </Lism>
@@ -0,0 +1,65 @@
1
+ import atts from 'lism-css/lib/helper/atts';
2
+ import mergeSet from 'lism-css/lib/helper/mergeSet';
3
+
4
+ export type ModalRootProps = {
5
+ lismClass?: string;
6
+ set?: string;
7
+ unset?: string;
8
+ duration?: string;
9
+ style?: Record<string, string>;
10
+ [key: string]: unknown;
11
+ };
12
+
13
+ export type ModalInnerProps = {
14
+ lismClass?: string;
15
+ offset?: string;
16
+ style?: Record<string, string>;
17
+ [key: string]: unknown;
18
+ };
19
+
20
+ export function getProps({ lismClass = '', set, unset, duration, style = {}, ...props }: ModalRootProps) {
21
+ const theProps = {
22
+ lismClass: atts(lismClass, 'c--modal'),
23
+ set: mergeSet('plain', set, unset),
24
+ };
25
+ if (duration) {
26
+ style['--duration'] = duration;
27
+ }
28
+
29
+ return { as: 'dialog', ...theProps, style, ...props };
30
+ }
31
+
32
+ export function getInnerProps({ lismClass = '', offset, style = {}, ...props }: ModalInnerProps) {
33
+ if (offset) {
34
+ style['--offset'] = offset;
35
+ }
36
+ return {
37
+ lismClass: atts(lismClass, 'c--modal_inner'),
38
+ style,
39
+ ...props,
40
+ };
41
+ }
42
+
43
+ export function getOpenBtnProps({ set, unset, ...props }: Record<string, unknown>) {
44
+ return {
45
+ as: 'button',
46
+ set: mergeSet('plain', set, unset),
47
+ hov: 'o',
48
+ d: 'inline-flex',
49
+ ...props,
50
+ };
51
+ }
52
+
53
+ export function getCloseBtnProps({ set, unset, ...props }: Record<string, unknown>) {
54
+ return {
55
+ as: 'button',
56
+ set: mergeSet('plain', set, unset),
57
+ hov: 'o',
58
+ d: 'inline-flex',
59
+ ...props,
60
+ };
61
+ }
62
+
63
+ export const defaultProps = {
64
+ body: { lismClass: 'c--modal_body' },
65
+ };
@@ -0,0 +1,10 @@
1
+ import { Lism, type LismComponentProps } from 'lism-css/react';
2
+ import { defaultProps } from '../getProps';
3
+
4
+ export default function ModalBody({ children, ...props }: LismComponentProps) {
5
+ return (
6
+ <Lism {...defaultProps.body} {...props}>
7
+ {children}
8
+ </Lism>
9
+ );
10
+ }
@@ -0,0 +1,24 @@
1
+ import type { ElementType } from 'react';
2
+ import { Lism, Icon, type LismComponentProps, type IconProps } from 'lism-css/react';
3
+ import { getCloseBtnProps } from '../getProps';
4
+
5
+ type CloseBtnProps<T extends ElementType = 'button'> = LismComponentProps<T> & {
6
+ modalId?: string;
7
+ icon?: IconProps['icon'];
8
+ srText?: string;
9
+ };
10
+
11
+ export default function CloseBtn<T extends ElementType = 'button'>({ children, modalId = '', icon, srText = 'Close', ...props }: CloseBtnProps<T>) {
12
+ return (
13
+ <Lism data-modal-close={modalId} {...(getCloseBtnProps(props as Record<string, unknown>) as object)}>
14
+ {children ? (
15
+ children
16
+ ) : (
17
+ <>
18
+ <Icon icon={icon || 'x'} />
19
+ <span className="u--srOnly">{srText || 'Close'}</span>
20
+ </>
21
+ )}
22
+ </Lism>
23
+ );
24
+ }
@@ -0,0 +1,6 @@
1
+ import { Lism, type LismComponentProps } from 'lism-css/react';
2
+ import { getInnerProps, type ModalInnerProps } from '../getProps';
3
+
4
+ export default function ModalInner({ children, ...props }: ModalInnerProps & LismComponentProps) {
5
+ return <Lism {...getInnerProps(props)}>{children}</Lism>;
6
+ }
@@ -0,0 +1,24 @@
1
+ 'use client';
2
+ import { useRef, useEffect } from 'react';
3
+ import type { ElementType } from 'react';
4
+ import { Lism, type LismComponentProps } from 'lism-css/react';
5
+ import { setEvent } from '../setModal';
6
+ import { getProps, type ModalRootProps } from '../getProps';
7
+
8
+ import '../_style.css';
9
+
10
+ const Modal = <T extends ElementType = 'dialog'>({ children, ...props }: ModalRootProps & LismComponentProps<T>) => {
11
+ const ref = useRef<HTMLDialogElement>(null);
12
+ useEffect(() => {
13
+ if (!ref?.current) return;
14
+ return setEvent(ref?.current);
15
+ }, [ref]);
16
+
17
+ const { as: modalAs, ...modalProps } = getProps(props);
18
+ return (
19
+ <Lism as={modalAs as ElementType} forwardedRef={ref} {...modalProps}>
20
+ {children}
21
+ </Lism>
22
+ );
23
+ };
24
+ export default Modal;
@@ -0,0 +1,15 @@
1
+ import type { ElementType } from 'react';
2
+ import { Lism, type LismComponentProps } from 'lism-css/react';
3
+ import { getOpenBtnProps } from '../getProps';
4
+
5
+ type OpenBtnProps<T extends ElementType = 'button'> = LismComponentProps<T> & {
6
+ modalId?: string;
7
+ };
8
+
9
+ export default function OpenBtn<T extends ElementType = 'button'>({ children, modalId = '', ...props }: OpenBtnProps<T>) {
10
+ return (
11
+ <Lism data-modal-open={modalId} {...(getOpenBtnProps(props as Record<string, unknown>) as object)}>
12
+ {children}
13
+ </Lism>
14
+ );
15
+ }
@@ -1,5 +1,5 @@
1
1
  /* Memo: この script は defer をつけて読み込む (DOMパース後に読み込まれます) */
2
- import setModal from './setModal.ts';
2
+ import setModal from './setModal';
3
3
 
4
4
  document.addEventListener('DOMContentLoaded', function () {
5
5
  setModal();