@lism-css/ui 0.11.0 → 0.13.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 (218) 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 -2
  26. package/dist/components/Callout/react/Callout.d.ts +3 -4
  27. package/dist/components/Callout/react/Callout.js +4 -4
  28. package/dist/components/Chat/Chat.stories.d.ts +9 -0
  29. package/dist/components/Chat/getProps.d.ts +43 -44
  30. package/dist/components/Chat/getProps.js +2 -2
  31. package/dist/components/Chat/react/Chat.d.ts +11 -7
  32. package/dist/components/Chat/react/Chat.js +10 -10
  33. package/dist/components/Details/Details.stories.d.ts +6 -0
  34. package/dist/components/Details/getProps.d.ts +34 -35
  35. package/dist/components/Details/getProps.js +17 -7
  36. package/dist/components/Details/react/Details.d.ts +11 -20
  37. package/dist/components/Details/react/Details.js +15 -15
  38. package/dist/components/Details/react/index.d.ts +7 -7
  39. package/dist/components/DummyImage/DummyImage.stories.d.ts +7 -0
  40. package/dist/components/DummyText/DummyText.stories.d.ts +9 -0
  41. package/dist/components/Modal/Modal.stories.d.ts +6 -0
  42. package/dist/components/Modal/getProps.d.ts +35 -36
  43. package/dist/components/Modal/getProps.js +34 -15
  44. package/dist/components/Modal/react/Body.d.ts +2 -4
  45. package/dist/components/Modal/react/CloseBtn.d.ts +9 -7
  46. package/dist/components/Modal/react/CloseBtn.js +5 -5
  47. package/dist/components/Modal/react/Inner.d.ts +3 -4
  48. package/dist/components/Modal/react/Modal.d.ts +4 -4
  49. package/dist/components/Modal/react/Modal.js +11 -9
  50. package/dist/components/Modal/react/OpenBtn.d.ts +7 -5
  51. package/dist/components/Modal/react/OpenBtn.js +4 -4
  52. package/dist/components/Modal/react/index.d.ts +7 -8
  53. package/dist/components/NavMenu/NavMenu.stories.d.ts +7 -0
  54. package/dist/components/NavMenu/getProps.d.ts +31 -29
  55. package/dist/components/NavMenu/react/NavMenu.d.ts +6 -16
  56. package/dist/components/NavMenu/react/NavMenu.js +21 -17
  57. package/dist/components/NavMenu/react/index.d.ts +6 -6
  58. package/dist/components/ShapeDivider/ShapeDivider.stories.d.ts +10 -0
  59. package/dist/components/ShapeDivider/getProps.d.ts +16 -11
  60. package/dist/components/ShapeDivider/getProps.js +10 -12
  61. package/dist/components/ShapeDivider/react/ShapeDivider.d.ts +3 -4
  62. package/dist/components/ShapeDivider/react/ShapeDivider.js +3 -3
  63. package/dist/components/Tabs/Tabs.stories.d.ts +6 -0
  64. package/dist/components/Tabs/getProps.d.ts +11 -4
  65. package/dist/components/Tabs/getProps.js +15 -5
  66. package/dist/components/Tabs/react/Tab.d.ts +8 -6
  67. package/dist/components/Tabs/react/Tab.js +15 -6
  68. package/dist/components/Tabs/react/TabItem.d.ts +7 -4
  69. package/dist/components/Tabs/react/TabList.d.ts +2 -1
  70. package/dist/components/Tabs/react/TabPanel.d.ts +8 -6
  71. package/dist/components/Tabs/react/Tabs.d.ts +9 -7
  72. package/dist/components/Tabs/react/Tabs.js +50 -36
  73. package/dist/components/Tabs/react/index.d.ts +8 -8
  74. package/dist/components/Tabs/setTabs.d.ts +1 -1
  75. package/dist/components/Tabs/setTabs.js +25 -15
  76. package/dist/lism-css/dist/components/{Center → layout/Center}/index.js +1 -1
  77. package/dist/lism-css/dist/components/{Flex → layout/Flex}/index.js +1 -1
  78. package/dist/lism-css/dist/components/{Flow → layout/Flow}/index.js +1 -1
  79. package/dist/lism-css/dist/components/{Frame → layout/Frame}/index.js +1 -1
  80. package/dist/lism-css/dist/components/{Grid → layout/Grid}/index.js +1 -1
  81. package/dist/lism-css/dist/components/{Stack → layout/Stack}/index.js +1 -1
  82. package/dist/lism-css/dist/config/default-config.js +6 -6
  83. package/dist/lism-css/dist/config/defaults/props.js +16 -26
  84. package/dist/lism-css/dist/config/defaults/traits.js +19 -0
  85. package/dist/lism-css/dist/config/index.js +9 -9
  86. package/dist/lism-css/dist/lib/getLayoutProps.js +6 -9
  87. package/dist/lism-css/dist/lib/getLismProps.js +116 -104
  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/_style.css +1 -1
  94. package/src/components/Accordion/astro/Button.astro +2 -2
  95. package/src/components/Accordion/getProps.ts +91 -0
  96. package/src/components/Accordion/react/{AccIcon.jsx → AccIcon.tsx} +2 -2
  97. package/src/components/Accordion/react/{Accordion.jsx → Accordion.tsx} +33 -11
  98. package/src/components/Accordion/setAccordion.ts +120 -0
  99. package/src/components/Alert/Alert.stories.tsx +64 -0
  100. package/src/components/Alert/getProps.ts +5 -3
  101. package/src/components/Alert/react/Alert.tsx +3 -3
  102. package/src/components/Avatar/Avatar.stories.tsx +42 -0
  103. package/src/components/Avatar/react/Avatar.tsx +17 -0
  104. package/src/components/Badge/Badge.stories.tsx +40 -0
  105. package/src/components/Badge/_style.css +1 -1
  106. package/src/components/Badge/astro/Badge.astro +1 -7
  107. package/src/components/Badge/react/Badge.tsx +7 -0
  108. package/src/components/Button/Button.stories.tsx +44 -0
  109. package/src/components/Button/_style.css +1 -1
  110. package/src/components/Button/astro/Button.astro +1 -7
  111. package/src/components/Button/react/Button.tsx +7 -0
  112. package/src/components/Callout/Callout.stories.tsx +55 -0
  113. package/src/components/Callout/getProps.ts +3 -2
  114. package/src/components/Callout/react/Callout.tsx +3 -3
  115. package/src/components/Chat/Chat.stories.tsx +58 -0
  116. package/src/components/Chat/_style.css +6 -6
  117. package/src/components/Chat/{getProps.js → getProps.ts} +10 -4
  118. package/src/components/Chat/react/{Chat.jsx → Chat.tsx} +13 -3
  119. package/src/components/Details/Details.stories.tsx +61 -0
  120. package/src/components/Details/_style.css +1 -1
  121. package/src/components/Details/astro/Title.astro +2 -2
  122. package/src/components/Details/{getProps.js → getProps.ts} +19 -6
  123. package/src/components/Details/react/Details.tsx +69 -0
  124. package/src/components/DummyImage/DummyImage.stories.tsx +23 -0
  125. package/src/components/DummyText/DummyText.stories.tsx +48 -0
  126. package/src/components/Modal/Modal.stories.tsx +67 -0
  127. package/src/components/Modal/_style.css +1 -1
  128. package/src/components/Modal/astro/CloseBtn.astro +2 -2
  129. package/src/components/Modal/astro/OpenBtn.astro +2 -3
  130. package/src/components/Modal/getProps.ts +64 -0
  131. package/src/components/Modal/react/Body.tsx +10 -0
  132. package/src/components/Modal/react/CloseBtn.tsx +24 -0
  133. package/src/components/Modal/react/Inner.tsx +6 -0
  134. package/src/components/Modal/react/Modal.tsx +24 -0
  135. package/src/components/Modal/react/OpenBtn.tsx +15 -0
  136. package/src/components/Modal/{script.js → script.ts} +1 -1
  137. package/src/components/NavMenu/NavMenu.stories.tsx +68 -0
  138. package/src/components/NavMenu/_style.css +1 -1
  139. package/src/components/NavMenu/getProps.ts +60 -0
  140. package/src/components/NavMenu/react/NavMenu.tsx +40 -0
  141. package/src/components/ShapeDivider/ShapeDivider.stories.tsx +87 -0
  142. package/src/components/ShapeDivider/_style.css +1 -1
  143. package/src/components/ShapeDivider/getProps.ts +36 -0
  144. package/src/components/ShapeDivider/react/{ShapeDivider.jsx → ShapeDivider.tsx} +4 -4
  145. package/src/components/Tabs/Tabs.stories.tsx +79 -0
  146. package/src/components/Tabs/_style.css +1 -1
  147. package/src/components/Tabs/astro/Tab.astro +2 -1
  148. package/src/components/Tabs/astro/{transformTabitems.js → transformTabitems.ts} +9 -9
  149. package/src/components/Tabs/getProps.ts +23 -0
  150. package/src/components/Tabs/react/Tab.tsx +21 -0
  151. package/src/components/Tabs/react/TabItem.tsx +13 -0
  152. package/src/components/Tabs/react/TabList.tsx +5 -0
  153. package/src/components/Tabs/react/{TabPanel.jsx → TabPanel.tsx} +8 -3
  154. package/src/components/Tabs/react/{Tabs.jsx → Tabs.tsx} +27 -12
  155. package/src/components/Tabs/{script.js → script.ts} +2 -2
  156. package/src/components/Tabs/setTabs.ts +65 -0
  157. package/src/helper/{uuid.js → uuid.ts} +2 -2
  158. package/src/vite-env.d.ts +1 -0
  159. package/dist/components/Accordion/astro/__setEvent.d.ts +0 -1
  160. package/dist/components/Accordion/astro/index.d.ts +0 -15
  161. package/dist/components/Alert/astro/index.d.ts +0 -1
  162. package/dist/components/Callout/astro/index.d.ts +0 -1
  163. package/dist/components/Details/astro/index.d.ts +0 -13
  164. package/dist/components/DummyImage/astro/index.d.ts +0 -1
  165. package/dist/components/DummyText/astro/index.d.ts +0 -1
  166. package/dist/components/Modal/astro/index.d.ts +0 -13
  167. package/dist/components/NavMenu/astro/index.d.ts +0 -11
  168. package/dist/components/Tabs/astro/index.d.ts +0 -13
  169. package/dist/components/Tabs/astro/transformTabitems.d.ts +0 -4
  170. package/dist/components/astro.d.ts +0 -14
  171. package/dist/lism-css/dist/config/defaults/states.js +0 -38
  172. package/dist/lism-css/dist/config/helper/getSvgUrl.js +0 -4
  173. package/src/components/Accordion/getProps.js +0 -77
  174. package/src/components/Accordion/setAccordion.js +0 -146
  175. package/src/components/Avatar/astro/index.js +0 -1
  176. package/src/components/Avatar/react/Avatar.jsx +0 -9
  177. package/src/components/Badge/astro/index.js +0 -1
  178. package/src/components/Badge/react/Badge.jsx +0 -12
  179. package/src/components/Button/astro/index.js +0 -1
  180. package/src/components/Button/react/Button.jsx +0 -12
  181. package/src/components/Chat/astro/index.js +0 -1
  182. package/src/components/Details/react/Details.jsx +0 -66
  183. package/src/components/Modal/getProps.js +0 -30
  184. package/src/components/Modal/react/Body.jsx +0 -10
  185. package/src/components/Modal/react/CloseBtn.jsx +0 -20
  186. package/src/components/Modal/react/Inner.jsx +0 -6
  187. package/src/components/Modal/react/Modal.jsx +0 -23
  188. package/src/components/Modal/react/OpenBtn.jsx +0 -11
  189. package/src/components/NavMenu/getProps.js +0 -65
  190. package/src/components/NavMenu/react/NavMenu.jsx +0 -19
  191. package/src/components/ShapeDivider/astro/index.js +0 -1
  192. package/src/components/ShapeDivider/getProps.js +0 -40
  193. package/src/components/Tabs/getProps.js +0 -8
  194. package/src/components/Tabs/react/Tab.jsx +0 -10
  195. package/src/components/Tabs/react/TabItem.jsx +0 -5
  196. package/src/components/Tabs/react/TabList.jsx +0 -6
  197. package/src/components/Tabs/setTabs.js +0 -87
  198. /package/src/components/Accordion/astro/{index.js → index.ts} +0 -0
  199. /package/src/components/Accordion/react/{index.js → index.ts} +0 -0
  200. /package/src/components/Accordion/{script.js → script.ts} +0 -0
  201. /package/{dist/components/Avatar/astro/index.d.ts → src/components/Avatar/astro/index.ts} +0 -0
  202. /package/src/components/Avatar/react/{index.js → index.ts} +0 -0
  203. /package/{dist/components/Badge/astro/index.d.ts → src/components/Badge/astro/index.ts} +0 -0
  204. /package/src/components/Badge/react/{index.js → index.ts} +0 -0
  205. /package/{dist/components/Button/astro/index.d.ts → src/components/Button/astro/index.ts} +0 -0
  206. /package/src/components/Button/react/{index.js → index.ts} +0 -0
  207. /package/{dist/components/Chat/astro/index.d.ts → src/components/Chat/astro/index.ts} +0 -0
  208. /package/src/components/Chat/react/{index.js → index.ts} +0 -0
  209. /package/src/components/Details/astro/{index.js → index.ts} +0 -0
  210. /package/src/components/Details/react/{index.js → index.ts} +0 -0
  211. /package/src/components/Modal/astro/{index.js → index.ts} +0 -0
  212. /package/src/components/Modal/react/{index.js → index.ts} +0 -0
  213. /package/src/components/NavMenu/astro/{index.js → index.ts} +0 -0
  214. /package/src/components/NavMenu/react/{index.js → index.ts} +0 -0
  215. /package/{dist/components/ShapeDivider/astro/index.d.ts → src/components/ShapeDivider/astro/index.ts} +0 -0
  216. /package/src/components/ShapeDivider/react/{index.js → index.ts} +0 -0
  217. /package/src/components/Tabs/astro/{index.js → index.ts} +0 -0
  218. /package/src/components/Tabs/react/{index.js → index.ts} +0 -0
@@ -0,0 +1,79 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { expect, userEvent, within } from 'storybook/test';
3
+ import Tabs from './react';
4
+
5
+ const meta: Meta = {
6
+ title: 'UI/Tabs',
7
+ tags: ['autodocs'],
8
+ };
9
+
10
+ export default meta;
11
+ type Story = StoryObj;
12
+
13
+ export const Default: Story = {
14
+ render: () => (
15
+ <Tabs.Root>
16
+ <Tabs.Item>
17
+ <Tabs.Tab>タブ 1</Tabs.Tab>
18
+ <Tabs.Panel>タブ 1 のコンテンツです。</Tabs.Panel>
19
+ </Tabs.Item>
20
+ <Tabs.Item>
21
+ <Tabs.Tab>タブ 2</Tabs.Tab>
22
+ <Tabs.Panel>タブ 2 のコンテンツです。</Tabs.Panel>
23
+ </Tabs.Item>
24
+ <Tabs.Item>
25
+ <Tabs.Tab>タブ 3</Tabs.Tab>
26
+ <Tabs.Panel>タブ 3 のコンテンツです。</Tabs.Panel>
27
+ </Tabs.Item>
28
+ </Tabs.Root>
29
+ ),
30
+ play: async ({ canvasElement }) => {
31
+ const canvas = within(canvasElement);
32
+ const tabs = canvas.getAllByRole('tab');
33
+ const [tab1, tab2, tab3] = tabs;
34
+
35
+ // 初期状態: タブ 1 が選択されている
36
+ await expect(tab1).toHaveAttribute('aria-selected', 'true');
37
+ await expect(tab2).toHaveAttribute('aria-selected', 'false');
38
+ await expect(tab3).toHaveAttribute('aria-selected', 'false');
39
+
40
+ // タブ 2 をクリック
41
+ await userEvent.click(tab2);
42
+ await expect(tab1).toHaveAttribute('aria-selected', 'false');
43
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
44
+
45
+ // タブ 3 をクリック
46
+ await userEvent.click(tab3);
47
+ await expect(tab2).toHaveAttribute('aria-selected', 'false');
48
+ await expect(tab3).toHaveAttribute('aria-selected', 'true');
49
+ },
50
+ };
51
+
52
+ export const DefaultIndex2: Story = {
53
+ name: 'defaultIndex: 2(2番目をデフォルト選択)',
54
+ render: () => (
55
+ <Tabs.Root defaultIndex={2}>
56
+ <Tabs.Item>
57
+ <Tabs.Tab>タブ 1</Tabs.Tab>
58
+ <Tabs.Panel>タブ 1 のコンテンツです。</Tabs.Panel>
59
+ </Tabs.Item>
60
+ <Tabs.Item>
61
+ <Tabs.Tab>タブ 2</Tabs.Tab>
62
+ <Tabs.Panel>タブ 2 がデフォルトで選択されています。</Tabs.Panel>
63
+ </Tabs.Item>
64
+ <Tabs.Item>
65
+ <Tabs.Tab>タブ 3</Tabs.Tab>
66
+ <Tabs.Panel>タブ 3 のコンテンツです。</Tabs.Panel>
67
+ </Tabs.Item>
68
+ </Tabs.Root>
69
+ ),
70
+ play: async ({ canvasElement }) => {
71
+ const canvas = within(canvasElement);
72
+ const tabs = canvas.getAllByRole('tab');
73
+ const [tab1, tab2] = tabs;
74
+
75
+ // 初期状態: タブ 2 が選択されている
76
+ await expect(tab1).toHaveAttribute('aria-selected', 'false');
77
+ await expect(tab2).toHaveAttribute('aria-selected', 'true');
78
+ },
79
+ };
@@ -1,4 +1,4 @@
1
- @layer lism-modules {
1
+ @layer lism-component {
2
2
  .c--tabs {
3
3
  display: grid;
4
4
  grid: 'list' 'panel' / 100%;
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  // import type { LismProps } from 'lism-css/types';
3
3
  import { Lism } from 'lism-css/astro';
4
+ import { getTabProps } from '../getProps';
4
5
 
5
6
  // export interface Props extends LismProps {
6
7
  // // controlId: string;
@@ -12,6 +13,6 @@ const { tabId = 'tab', index = 0, isActive, ...props } = Astro.props;
12
13
  const controlId = `${tabId}-${index}`;
13
14
  ---
14
15
 
15
- <Lism as="button" lismClass="c--tabs_tab" setPlain role="tab" aria-controls={controlId} aria-selected={isActive ? 'true' : 'false'} {...props}>
16
+ <Lism {...getTabProps(props)} role="tab" aria-controls={controlId} aria-selected={isActive ? 'true' : 'false'}>
16
17
  <slot />
17
18
  </Lism>
@@ -1,30 +1,30 @@
1
+ type TransformResult = {
2
+ btns: string[];
3
+ panels: string[];
4
+ };
5
+
1
6
  // <lism-placeholder-tabitem> → div.tabitem へ 変換
2
- export default function transformHTML(htmlString, tabID, defaultIndex) {
7
+ export default function transformHTML(htmlString: string, tabID: string, defaultIndex: number): TransformResult {
3
8
  let index = 1; // 1スタート
4
- let btns = [];
5
- let panels = [];
9
+ const btns: string[] = [];
10
+ const panels: string[] = [];
6
11
 
7
- // <lism-placeholder-tabitem>でコンテンツを囲んでいるので中身を解析する。
8
12
  const regex = /<lism-placeholder-tabitem(.*?)>(.*?)<\/lism-placeholder-tabitem>/gs;
9
13
  const matches = [...htmlString.matchAll(regex)];
10
14
 
11
- // console.log(matches);
12
15
  matches.forEach((match) => {
13
- // const tabItemAttrs = match[1]; // 使わないがdata-astro-source-file属性が自動でついてきたりするので、属性値があっても問題ないようにしている。
14
16
  const tabItemContent = match[2];
15
17
 
16
18
  const controlId = `${tabID}-${index}`;
17
19
  const isActive = index === defaultIndex;
18
20
  index++;
19
21
 
20
- // <lism-placeholder-tabtbn>からタブボタンを生成
21
22
  const btnMatch = tabItemContent.match(/<button(.*?)>(.*?)<\/button>(.*)/s);
22
23
  if (!btnMatch) return;
23
24
  let btnAtts = btnMatch[1];
24
- let btnContent = btnMatch[2];
25
+ const btnContent = btnMatch[2];
25
26
  let panel = btnMatch[3];
26
27
 
27
- // btnContent = btnContent.replace(` slot="tab"`, '');
28
28
  btnAtts = btnAtts.replace(`aria-controls="tab-0"`, `aria-controls="${controlId}"`);
29
29
  panel = panel.replace(`id="tab-0"`, `id="${controlId}"`);
30
30
  if (isActive) {
@@ -0,0 +1,23 @@
1
+ import atts from 'lism-css/lib/helper/atts';
2
+ import mergeSet from 'lism-css/lib/helper/mergeSet';
3
+
4
+ type TabsProps = {
5
+ lismClass?: string;
6
+ [key: string]: unknown;
7
+ };
8
+
9
+ export default function getTabsProps({ lismClass, ...props }: TabsProps) {
10
+ return {
11
+ lismClass: atts(lismClass, 'c--tabs'),
12
+ ...props,
13
+ };
14
+ }
15
+
16
+ export function getTabProps({ set, ...props }: Record<string, unknown>) {
17
+ return {
18
+ as: 'button',
19
+ lismClass: 'c--tabs_tab',
20
+ set: mergeSet('plain', set),
21
+ ...props,
22
+ };
23
+ }
@@ -0,0 +1,21 @@
1
+ import { Lism, type LismComponentProps } from 'lism-css/react';
2
+ import { getTabProps } from '../getProps';
3
+
4
+ type TabProps = LismComponentProps & {
5
+ tabId?: string;
6
+ index?: number;
7
+ isActive?: boolean;
8
+ };
9
+
10
+ export default function Tab({ tabId = 'tab', index = 0, isActive = false, ...props }: TabProps) {
11
+ const controlId = `${tabId}-${index}`;
12
+
13
+ return (
14
+ <Lism
15
+ {...(getTabProps(props as Record<string, unknown>) as object)}
16
+ role="tab"
17
+ aria-controls={controlId}
18
+ aria-selected={isActive ? 'true' : 'false'}
19
+ />
20
+ );
21
+ }
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ type TabItemProps = {
4
+ isTabItem?: boolean;
5
+ children?: ReactNode;
6
+ };
7
+
8
+ // Note: <Tabs>側でループして色々処理される。
9
+ // 引数でちゃんと処理したいpropを書いておかないとだめ。
10
+ export default function TabItem({ isTabItem = true, children }: TabItemProps) {
11
+ void isTabItem;
12
+ return <div>{children}</div>;
13
+ }
@@ -0,0 +1,5 @@
1
+ import { Lism, type LismComponentProps } from 'lism-css/react';
2
+
3
+ export default function TabList(props: LismComponentProps) {
4
+ return <Lism lismClass="c--tabs_list" role="tablist" {...props} />;
5
+ }
@@ -1,7 +1,12 @@
1
- // import React from 'react';
2
- import { Lism } from 'lism-css/react';
1
+ import { Lism, type LismComponentProps } from 'lism-css/react';
3
2
 
4
- export default function TabPanel({ tabId = 'tab', isActive = false, index = 0, ...props }) {
3
+ type TabPanelProps = LismComponentProps & {
4
+ tabId?: string;
5
+ isActive?: boolean;
6
+ index?: number;
7
+ };
8
+
9
+ export default function TabPanel({ tabId = 'tab', isActive = false, index = 0, ...props }: TabPanelProps) {
5
10
  const controlId = `${tabId}-${index}`;
6
11
 
7
12
  return <Lism id={controlId} role="tabpanel" aria-hidden={isActive ? 'false' : 'true'} lismClass="c--tabs_panel" {...props} />;
@@ -1,34 +1,41 @@
1
1
  'use client';
2
2
  import { useState, useId, Children, isValidElement } from 'react';
3
- import { Lism } from 'lism-css/react';
3
+ import type { ElementType } from 'react';
4
+ import { Lism, type LismComponentProps } from 'lism-css/react';
4
5
  import Tab from './Tab';
5
6
  import TabItem from './TabItem';
6
7
  import TabList from './TabList';
7
8
  import TabPanel from './TabPanel';
8
9
  import getTabsProps from '../getProps';
9
- // import { TabContext } from './context';
10
10
 
11
11
  import '../_style.css';
12
12
 
13
- export default function Tabs({ tabId = '', defaultIndex = 1, listProps = {}, children, ...props }) {
13
+ type TabsProps<T extends ElementType = 'div'> = LismComponentProps<T> & {
14
+ tabId?: string;
15
+ defaultIndex?: number;
16
+ listProps?: LismComponentProps;
17
+ };
18
+
19
+ export default function Tabs<T extends ElementType = 'div'>({ tabId = '', defaultIndex = 1, listProps = {}, children, ...props }: TabsProps<T>) {
14
20
  const [activeIndex, setActiveIndex] = useState(defaultIndex);
15
- const theTabId = tabId || useId();
16
- const btns = [];
17
- const panels = [];
21
+ const generatedId = useId();
22
+ const theTabId = tabId || generatedId;
23
+ const btns: React.ReactElement[] = [];
24
+ const panels: React.ReactElement[] = [];
18
25
 
19
26
  // Tabs.Item の処理
20
27
  Children.forEach(children, (child, index) => {
21
28
  const tabIndex = index + 1; // 1 はじまり
22
- // console.log('child.type', isValidElement(child), child.type);
23
29
 
24
30
  if (isValidElement(child) && child.type === TabItem) {
25
- Children.forEach(child.props.children, (nestedChild) => {
31
+ const childProps = child.props as { children?: React.ReactNode };
32
+ Children.forEach(childProps.children, (nestedChild) => {
26
33
  if (isValidElement(nestedChild)) {
27
34
  if (nestedChild.type === Tab) {
28
- const tabProps = nestedChild.props;
35
+ const tabProps = nestedChild.props as Record<string, unknown>;
29
36
  btns.push(
30
37
  <Tab
31
- {...tabProps}
38
+ {...(tabProps as LismComponentProps)}
32
39
  tabId={theTabId}
33
40
  index={tabIndex}
34
41
  key={tabIndex}
@@ -37,8 +44,16 @@ export default function Tabs({ tabId = '', defaultIndex = 1, listProps = {}, chi
37
44
  />
38
45
  );
39
46
  } else if (nestedChild.type === TabPanel) {
40
- const panelProps = nestedChild.props;
41
- panels.push(<TabPanel {...panelProps} tabId={theTabId} index={tabIndex} key={tabIndex} isActive={tabIndex === activeIndex} />);
47
+ const panelProps = nestedChild.props as Record<string, unknown>;
48
+ panels.push(
49
+ <TabPanel
50
+ {...(panelProps as LismComponentProps)}
51
+ tabId={theTabId}
52
+ index={tabIndex}
53
+ key={tabIndex}
54
+ isActive={tabIndex === activeIndex}
55
+ />
56
+ );
42
57
  }
43
58
  }
44
59
  });
@@ -1,7 +1,7 @@
1
- import setTabs from './setTabs.js';
1
+ import setTabs from './setTabs';
2
2
 
3
3
  document.addEventListener('DOMContentLoaded', function () {
4
- const tabsAll = document.querySelectorAll('.c--tabs');
4
+ const tabsAll = document.querySelectorAll<HTMLElement>('.c--tabs');
5
5
  tabsAll.forEach((tabs) => {
6
6
  setTabs(tabs);
7
7
  });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * タブ
3
+ */
4
+ function tabControl(e: MouseEvent): void {
5
+ e.preventDefault();
6
+ const clickedButton = e.currentTarget as HTMLButtonElement;
7
+ toggleAriaData(clickedButton);
8
+ }
9
+
10
+ const toggleAriaData = (clickedButton: HTMLButtonElement): void => {
11
+ const isOpend = 'true' === clickedButton.getAttribute('aria-selected');
12
+ if (isOpend) return;
13
+
14
+ const targetID = clickedButton.getAttribute('aria-controls');
15
+ if (!targetID) return;
16
+ const targetBody = document.getElementById(targetID);
17
+ if (null === targetBody) return;
18
+
19
+ const parentTabList = clickedButton.parentNode?.parentNode as HTMLElement | null;
20
+ if (!parentTabList) return;
21
+
22
+ const selectedButton = parentTabList.querySelector<HTMLButtonElement>('[aria-selected="true"]');
23
+ if (!selectedButton) return;
24
+
25
+ const displayedID = selectedButton.getAttribute('aria-controls');
26
+ if (!displayedID) return;
27
+ const displayedBody = document.getElementById(displayedID);
28
+
29
+ clickedButton.setAttribute('aria-selected', 'true');
30
+ selectedButton.setAttribute('aria-selected', 'false');
31
+ displayedBody?.setAttribute('aria-hidden', 'true');
32
+ targetBody.setAttribute('aria-hidden', 'false');
33
+ };
34
+
35
+ function setTabs(tabs: HTMLElement): void {
36
+ const tabBtns = tabs.querySelectorAll<HTMLButtonElement>('button[role="tab"]');
37
+ tabBtns.forEach((tabBtn) => {
38
+ tabBtn.addEventListener('click', function (e) {
39
+ tabControl(e);
40
+ });
41
+ });
42
+
43
+ const nowUrl = window?.location?.href;
44
+ if (!nowUrl) return;
45
+
46
+ const hasTabLink = -1 !== nowUrl.indexOf('?lism-tab=');
47
+ if (!hasTabLink) return;
48
+
49
+ const url = new URL(nowUrl);
50
+ const params = url.searchParams;
51
+
52
+ const targetTabId = params.get('lism-tab');
53
+ if (!targetTabId) return;
54
+
55
+ const target = tabs.querySelector<HTMLButtonElement>(`[aria-controls="${targetTabId}"]`);
56
+ if (target) {
57
+ tabs.dataset.hasTabLink = '1';
58
+ toggleAriaData(target);
59
+ setTimeout(() => {
60
+ delete tabs.dataset.hasTabLink;
61
+ }, 10);
62
+ }
63
+ }
64
+
65
+ export default setTabs;
@@ -1,6 +1,6 @@
1
1
  // https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid
2
- export default function uuidv4() {
2
+ export default function uuidv4(): string {
3
3
  return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) =>
4
- (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
4
+ (parseInt(c) ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (parseInt(c) / 4)))).toString(16)
5
5
  );
6
6
  }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -1 +0,0 @@
1
- export default setEvent;
@@ -1,15 +0,0 @@
1
- import { default as Root } from './Root.astro';
2
- import { default as Item } from './Item.astro';
3
- import { default as Heading } from './Heading.astro';
4
- import { default as Panel } from './Panel.astro';
5
- import { default as Icon } from './Icon.astro';
6
- import { default as Button } from './Button.astro';
7
- declare namespace _default {
8
- export { Root };
9
- export { Item };
10
- export { Heading };
11
- export { Panel };
12
- export { Icon };
13
- export { Button };
14
- }
15
- export default _default;
@@ -1 +0,0 @@
1
- export { default } from './Alert.astro';
@@ -1 +0,0 @@
1
- export { default } from './Callout.astro';
@@ -1,13 +0,0 @@
1
- import { default as Root } from './Details.astro';
2
- import { default as Summary } from './Summary.astro';
3
- import { default as Title } from './Title.astro';
4
- import { default as Content } from './Content.astro';
5
- import { default as Icon } from './Icon.astro';
6
- declare namespace _default {
7
- export { Root };
8
- export { Summary };
9
- export { Title };
10
- export { Content };
11
- export { Icon };
12
- }
13
- export default _default;
@@ -1 +0,0 @@
1
- export { default } from './DummyImage.astro';
@@ -1 +0,0 @@
1
- export { default } from './DummyText.astro';
@@ -1,13 +0,0 @@
1
- import { default as Root } from './Modal.astro';
2
- import { default as Inner } from './Inner.astro';
3
- import { default as Body } from './Body.astro';
4
- import { default as CloseBtn } from './CloseBtn.astro';
5
- import { default as OpenBtn } from './OpenBtn.astro';
6
- declare namespace _default {
7
- export { Root };
8
- export { Inner };
9
- export { Body };
10
- export { CloseBtn };
11
- export { OpenBtn };
12
- }
13
- export default _default;
@@ -1,11 +0,0 @@
1
- import { default as Root } from './Root.astro';
2
- import { default as Nest } from './Nest.astro';
3
- import { default as Item } from './Item.astro';
4
- import { default as Link } from './Link.astro';
5
- declare namespace _default {
6
- export { Root };
7
- export { Nest };
8
- export { Item };
9
- export { Link };
10
- }
11
- export default _default;
@@ -1,13 +0,0 @@
1
- import { default as Root } from './Tabs.astro';
2
- import { default as List } from './TabList.astro';
3
- import { default as Panel } from './TabPanel.astro';
4
- import { default as Item } from './TabItem.astro';
5
- import { default as Tab } from './Tab.astro';
6
- declare namespace _default {
7
- export { Root };
8
- export { List };
9
- export { Panel };
10
- export { Item };
11
- export { Tab };
12
- }
13
- export default _default;
@@ -1,4 +0,0 @@
1
- export default function transformHTML(htmlString: any, tabID: any, defaultIndex: any): {
2
- btns: any[];
3
- panels: any[];
4
- };
@@ -1,14 +0,0 @@
1
- export { default as Accordion } from './Accordion/astro';
2
- export { default as Alert } from './Alert/astro';
3
- export { default as Avatar } from './Avatar/astro';
4
- export { default as Badge } from './Badge/astro';
5
- export { default as Button } from './Button/astro';
6
- export { default as Callout } from './Callout/astro';
7
- export { default as Chat } from './Chat/astro';
8
- export { default as Details } from './Details/astro';
9
- export { default as Modal } from './Modal/astro';
10
- export { default as NavMenu } from './NavMenu/astro';
11
- export { default as ShapeDivider } from './ShapeDivider/astro';
12
- export { default as Tabs } from './Tabs/astro';
13
- export { default as DummyText } from './DummyText/astro';
14
- export { default as DummyImage } from './DummyImage/astro';
@@ -1,38 +0,0 @@
1
- import t from "../helper/getSvgUrl.js";
2
- const a = {
3
- isContainer: "is--container",
4
- isWrapper: {
5
- className: "is--wrapper",
6
- preset: ["s", "l"],
7
- presetClass: "-contentSize",
8
- customVar: "--contentSize",
9
- tokenKey: "sz"
10
- },
11
- isLayer: "is--layer",
12
- isLinkBox: "is--linkBox",
13
- isSide: "is--side",
14
- isSkipFlow: "is--skipFlow",
15
- isVertical: "is--vertical",
16
- setGutter: "set--gutter",
17
- // set class
18
- setShadow: "set--shadow",
19
- setHov: "set--hov",
20
- setTransition: "set--transition",
21
- setMask: {
22
- // 'set--mask',
23
- className: "set--mask",
24
- setStyles: (e) => {
25
- let s = e;
26
- return s.startsWith("<svg") && (s = t(e, "base64")), {
27
- "--maskImg": s
28
- };
29
- }
30
- },
31
- setPlain: "set--plain",
32
- // setRevert: 'set--revert',
33
- setInnerRs: "set--innerRs",
34
- setBp: "set--bp"
35
- };
36
- export {
37
- a as default
38
- };
@@ -1,4 +0,0 @@
1
- const g = (a, r = "") => a ? r === "base64" ? (a = Buffer.from(a).toString("base64"), `url(data:image/svg+xml;base64,${a})`) : (a = a.replace(/'/g, '"'), a = a.replace(/="#/g, '="%23'), `url('data:image/svg+xml,${a}')`) : "";
2
- export {
3
- g as default
4
- };
@@ -1,77 +0,0 @@
1
- import atts from 'lism-css/lib/helper/atts';
2
-
3
- export function getRootProps({ lismClass, allowMultiple, ...props }) {
4
- props.lismClass = atts(lismClass, 'c--accordion');
5
- if (allowMultiple) props['data-allow-multiple'] = '';
6
- return props;
7
- }
8
-
9
- // duration: [s]
10
- export function getItemProps({ lismClass, ...props }) {
11
- props.lismClass = atts(lismClass, 'c--accordion_item');
12
- return props;
13
- }
14
-
15
- export function getHeadingProps(props) {
16
- const defaultProps = {
17
- lismClass: 'c--accordion_heading',
18
- as: 'div',
19
- setPlain: 1,
20
- };
21
-
22
- const returnProps = { ...defaultProps, ...props };
23
-
24
- // div の時は role 付与
25
- if (returnProps.as === 'div') {
26
- returnProps.role = 'heading';
27
- }
28
- return returnProps;
29
- }
30
-
31
- // id: Context から取得できればそれを優先(React用)
32
- export function getPanelProps({ lismClass, _contextID, accID = '__LISM_ACC_ID__', isOpen = false, ...props }) {
33
- // panel側は必要最低限のプロパティのみ。
34
- const panelProps = {
35
- lismClass: atts(lismClass, 'c--accordion_panel'),
36
- id: _contextID || accID,
37
- hidden: isOpen ? undefined : 'until-found',
38
- pos: 'relative',
39
- ov: 'hidden',
40
- };
41
-
42
- // 余白などその他の指定は全て _content 側へ渡す
43
- const contentProps = { lismClass: 'c--accordion_content', layout: 'flow', ...props };
44
-
45
- // content側へ移すprops
46
- // ['p', 'px', 'py', 'pl', 'pr', 'pt', 'pb', 'px-s', 'px-e', 'py-s', 'py-e'].forEach((prop) => {
47
- // if (props[prop]) {
48
- // contentProps[prop] = props[prop];
49
- // delete props[prop];
50
- // }
51
- // });
52
-
53
- // 2つ返す
54
- return { panelProps, contentProps };
55
- }
56
-
57
- export const defaultProps = {
58
- // header: { lismClass: 'c--accordion_header' },
59
- button: {
60
- lismClass: 'c--accordion_button',
61
- as: 'button',
62
- layout: 'flex',
63
- setPlain: 1,
64
- g: '10',
65
- w: '100%',
66
- ai: 'center',
67
- jc: 'between',
68
- },
69
- icon: {
70
- lismClass: 'c--accordion_icon a--icon',
71
- as: 'span',
72
- // d: 'grid',
73
- pi: 'center',
74
- fxsh: '0',
75
- 'aria-hidden': 'true',
76
- },
77
- };