jp.ui.app.ds 1.0.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 (47) hide show
  1. package/.storybook/main.ts +31 -0
  2. package/.storybook/preview.tsx +38 -0
  3. package/package.json +41 -0
  4. package/rollup.config.js +31 -0
  5. package/src/index.ts +1 -0
  6. package/src/matherial3/button/common-button.style.ts +35 -0
  7. package/src/matherial3/button/common-button.tsx +40 -0
  8. package/src/matherial3/button/filled-button.stories.ts +33 -0
  9. package/src/matherial3/button/filled-button.tsx +20 -0
  10. package/src/matherial3/button/index.ts +9 -0
  11. package/src/matherial3/button/outlined-button.stories.ts +33 -0
  12. package/src/matherial3/button/outlined-button.tsx +18 -0
  13. package/src/matherial3/button/text-button.stories.ts +33 -0
  14. package/src/matherial3/button/text-button.tsx +17 -0
  15. package/src/matherial3/checkbox/checkbox.stories.ts +29 -0
  16. package/src/matherial3/checkbox/checkbox.style.tsx +53 -0
  17. package/src/matherial3/checkbox/checkbox.tsx +49 -0
  18. package/src/matherial3/checkbox/index.ts +5 -0
  19. package/src/matherial3/helpers/backdrop/backdrop.style.ts +14 -0
  20. package/src/matherial3/helpers/backdrop/backdrop.tsx +9 -0
  21. package/src/matherial3/helpers/backdrop/index.ts +5 -0
  22. package/src/matherial3/helpers/index.ts +19 -0
  23. package/src/matherial3/helpers/no-style-button/index.ts +5 -0
  24. package/src/matherial3/helpers/no-style-button/no-style-button.style.ts +12 -0
  25. package/src/matherial3/helpers/outside-click.ts +17 -0
  26. package/src/matherial3/helpers/popup/index.ts +1 -0
  27. package/src/matherial3/helpers/popup/popup.style.tsx +14 -0
  28. package/src/matherial3/helpers/popup/popup.tsx +17 -0
  29. package/src/matherial3/helpers/stack/column-center.tsx +22 -0
  30. package/src/matherial3/helpers/stack/column-left.tsx +22 -0
  31. package/src/matherial3/helpers/stack/index.ts +13 -0
  32. package/src/matherial3/helpers/stack/row-center.tsx +19 -0
  33. package/src/matherial3/helpers/stack/row-start.tsx +20 -0
  34. package/src/matherial3/helpers/stack/stack.tsx +16 -0
  35. package/src/matherial3/helpers/svg-icon/index.ts +5 -0
  36. package/src/matherial3/helpers/svg-icon/svg-icon.tsx +46 -0
  37. package/src/matherial3/index.ts +2 -0
  38. package/src/matherial3/typography/body.tsx +19 -0
  39. package/src/matherial3/typography/display.tsx +19 -0
  40. package/src/matherial3/typography/headline.tsx +19 -0
  41. package/src/matherial3/typography/index.ts +13 -0
  42. package/src/matherial3/typography/label.tsx +19 -0
  43. package/src/matherial3/typography/m3-typography.tsx +45 -0
  44. package/src/matherial3/typography/title.tsx +19 -0
  45. package/src/matherial3/typography/typography-size.ts +1 -0
  46. package/tsconfig.json +30 -0
  47. package/types/emotion.d.ts +12 -0
@@ -0,0 +1,31 @@
1
+ import type { StorybookConfig } from '@storybook/react-webpack5';
2
+
3
+ const config: StorybookConfig = {
4
+ stories: [
5
+ "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
6
+ ],
7
+ addons: [
8
+ "@storybook/addon-webpack5-compiler-swc",
9
+ "@storybook/addon-docs",
10
+ "@storybook/addon-themes",
11
+ ],
12
+ framework: {
13
+ name: "@storybook/react-webpack5",
14
+ options: {}
15
+ },
16
+ webpackFinal: config => {
17
+ // remove svg from existing rule
18
+ const fileLoaderRule = config.module.rules.find(
19
+ (rule) => rule.test && rule.test.test('.svg')
20
+ )
21
+ fileLoaderRule.exclude = /\.svg$/
22
+
23
+ config.module.rules.push({
24
+ test: /\.svg$/,
25
+ use: ['@svgr/webpack'],
26
+ })
27
+
28
+ return config
29
+ }
30
+ };
31
+ export default config;
@@ -0,0 +1,38 @@
1
+ import type { Preview } from '@storybook/react-webpack5';
2
+ import { Global, css, ThemeProvider } from '@emotion/react';
3
+ import { withThemeFromJSXProvider } from '@storybook/addon-themes';
4
+ import { ColorSchema, getDarkTheme, getLightTheme } from '@choochoochoo/jp.theme';
5
+
6
+ const GlobalStyles = () => (
7
+ <Global
8
+ styles={css`
9
+ body {
10
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
11
+ }
12
+ `}
13
+ />
14
+ );
15
+
16
+ const preview: Preview = {
17
+ parameters: {
18
+ controls: {
19
+ matchers: {
20
+ color: /(background|color)$/i,
21
+ date: /Date$/i,
22
+ },
23
+ },
24
+ },
25
+ decorators: [
26
+ withThemeFromJSXProvider({
27
+ themes: {
28
+ light: getLightTheme<object>(ColorSchema.DEFAULT, {}),
29
+ dark: getDarkTheme<object>('color_schema__default', {}),
30
+ },
31
+ defaultTheme: 'light',
32
+ Provider: ThemeProvider,
33
+ GlobalStyles,
34
+ })
35
+ ]
36
+ };
37
+
38
+ export default preview;
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "jp.ui.app.ds",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "test": "echo \"Error: no test specified\" && exit 1",
10
+ "dev": "storybook dev -p 6006",
11
+ "build:storybook": "storybook build",
12
+ "build": "rollup -c"
13
+ },
14
+ "author": "",
15
+ "license": "ISC",
16
+ "devDependencies": {
17
+ "@emotion/react": "11.14.0",
18
+ "@emotion/styled": "11.14.1",
19
+ "@rollup/plugin-commonjs": "28.0.8",
20
+ "@rollup/plugin-terser": "0.4.4",
21
+ "@rollup/plugin-typescript": "12.2.0",
22
+ "@storybook/addon-docs": "9.1.13",
23
+ "@storybook/addon-themes": "9.1.13",
24
+ "@storybook/addon-webpack5-compiler-swc": "4.0.1",
25
+ "@storybook/react-webpack5": "9.1.13",
26
+ "@svgr/rollup": "8.1.0",
27
+ "@svgr/webpack": "8.1.0",
28
+ "@types/node": "24.9.1",
29
+ "@types/react": "19.2.2",
30
+ "react": "^19.2.0",
31
+ "react-dom": "^19.2.0",
32
+ "rollup": "4.52.5",
33
+ "rollup-plugin-dts": "6.2.3",
34
+ "storybook": "9.1.13",
35
+ "typescript": "5.9.3"
36
+ },
37
+ "dependencies": {
38
+ "@choochoochoo/jp.theme": "1.0.0",
39
+ "@material-design-icons/svg": "0.14.15"
40
+ }
41
+ }
@@ -0,0 +1,31 @@
1
+ import commonjs from '@rollup/plugin-commonjs';
2
+ import typescript from '@rollup/plugin-typescript';
3
+ import { dts } from 'rollup-plugin-dts';
4
+ import terser from '@rollup/plugin-terser';
5
+ import svgr from '@svgr/rollup'
6
+
7
+ const config = [
8
+ {
9
+ input: 'src/index.ts',
10
+ output: [
11
+ {
12
+ file: 'dist/index.js',
13
+ format: 'es',
14
+ sourcemap: true,
15
+ },
16
+ ],
17
+ plugins: [
18
+ commonjs(),
19
+ typescript(),
20
+ svgr(),
21
+ // terser(),
22
+ ],
23
+ },
24
+ {
25
+ input: './dist/index.d.ts',
26
+ output: [{ file: 'dist/index.d.ts', format: 'es' }],
27
+ plugins: [dts()],
28
+ },
29
+ ];
30
+
31
+ export default config;
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './matherial3';
@@ -0,0 +1,35 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ import { NoStyleButton } from '../helpers/no-style-button';
4
+
5
+ export const filled_button_border_radius = 100;
6
+
7
+ type CommonButtonStyledProps = {
8
+ borderColor?: string;
9
+ backgroundColor?: string;
10
+ hoverColor?: string;
11
+ }
12
+
13
+ export const CommonButtonStyled = styled(NoStyleButton)<CommonButtonStyledProps>`
14
+ background-color: ${({ backgroundColor }: { backgroundColor?: string }) => backgroundColor ?? 'transparent'};
15
+ border: 1px solid ${({ borderColor }: CommonButtonStyledProps) => borderColor ?? 'transparent'};
16
+ border-radius: ${filled_button_border_radius}px;
17
+ padding: 10px 24px;
18
+ position: relative;
19
+
20
+ :hover {
21
+ ::before {
22
+ left: 0;
23
+ bottom: 0;
24
+ content: "\\00a0";
25
+ position: absolute;
26
+ right: 0;
27
+ pointer-events: none;
28
+ width: 100%;
29
+ height: 100%;
30
+ background-color: ${({ hoverColor }: { hoverColor?: string }) => hoverColor};
31
+ opacity: 0.08;
32
+ border-radius: ${filled_button_border_radius}px;
33
+ }
34
+ }
35
+ `;
@@ -0,0 +1,40 @@
1
+ import * as React from 'react';
2
+ import { useTheme, Theme } from '@emotion/react';
3
+
4
+ import { Label } from '../typography';
5
+
6
+ import { CommonButtonStyled } from './common-button.style';
7
+
8
+ export type CommonTypeStyle = {
9
+ text: string;
10
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
11
+ className?: string;
12
+ disabled?: boolean;
13
+ textColor?: string;
14
+ }
15
+
16
+ type componentTypeStyle = CommonTypeStyle & {
17
+ backgroundColor?: string;
18
+ textColor: string;
19
+ borderColor?: string;
20
+ }
21
+
22
+ export const CommonButton = ({ text, onClick, className, backgroundColor, textColor, borderColor, disabled }: componentTypeStyle) => {
23
+ const theme = useTheme() as Theme;
24
+
25
+ return (
26
+ <CommonButtonStyled
27
+ title={text}
28
+ onClick={onClick}
29
+ className={className}
30
+ backgroundColor={backgroundColor}
31
+ borderColor={borderColor}
32
+ hoverColor={theme.m3Schema.onPrimaryContainer}
33
+ disabled={disabled}
34
+ >
35
+ <Label color={textColor} size="lg">
36
+ {text}
37
+ </Label>
38
+ </CommonButtonStyled>
39
+ );
40
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { fn } from 'storybook/test';
3
+
4
+ import { FilledButton } from './filled-button';
5
+
6
+ const meta = {
7
+ title: 'm3/button/FilledButton',
8
+ component: FilledButton,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ text: 'text',
15
+ },
16
+ args: { onClick: fn() },
17
+ } satisfies Meta<typeof FilledButton>;
18
+
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+
22
+ export const Default: Story = {
23
+ args: {
24
+ text: 'Button',
25
+ },
26
+ };
27
+
28
+ export const Disabled: Story = {
29
+ args: {
30
+ text: 'disabled',
31
+ disabled: true,
32
+ },
33
+ };
@@ -0,0 +1,20 @@
1
+ import * as React from 'react';
2
+ import { useTheme, Theme } from '@emotion/react';
3
+
4
+ import { CommonButton, CommonTypeStyle } from './common-button';
5
+
6
+ export const FilledButton = ({ text, onClick, className, disabled }: CommonTypeStyle) => {
7
+ const theme = useTheme() as Theme;
8
+
9
+ return (
10
+ <CommonButton
11
+ text={text}
12
+ onClick={onClick}
13
+ backgroundColor={disabled ? `${theme.m3Schema.onSurface}1f` : theme.m3Schema.primary}
14
+ borderColor={disabled ? 'transparent' : theme.m3Schema.primary}
15
+ textColor={disabled ? `${theme.m3Schema.onSurface}b0` : theme.m3Schema.onPrimary}
16
+ className={className}
17
+ disabled={disabled}
18
+ />
19
+ );
20
+ };
@@ -0,0 +1,9 @@
1
+ import { FilledButton } from './filled-button';
2
+ import { OutlinedButton } from './outlined-button';
3
+ import { TextButton } from './text-button';
4
+
5
+ export {
6
+ FilledButton,
7
+ OutlinedButton,
8
+ TextButton,
9
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { fn } from 'storybook/test';
3
+
4
+ import { OutlinedButton } from './outlined-button';
5
+
6
+ const meta = {
7
+ title: 'm3/button/OutlinedButton',
8
+ component: OutlinedButton,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ text: 'text',
15
+ },
16
+ args: { onClick: fn() },
17
+ } satisfies Meta<typeof OutlinedButton>;
18
+
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+
22
+ export const Default: Story = {
23
+ args: {
24
+ text: 'default',
25
+ },
26
+ };
27
+
28
+ export const Disabled: Story = {
29
+ args: {
30
+ text: 'disabled',
31
+ disabled: true,
32
+ },
33
+ };
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ import { useTheme, Theme } from '@emotion/react';
3
+
4
+ import { CommonButton, CommonTypeStyle } from './common-button';
5
+
6
+ export const OutlinedButton = ({ text, onClick, className }: CommonTypeStyle) => {
7
+ const theme = useTheme() as Theme;
8
+
9
+ return (
10
+ <CommonButton
11
+ text={text}
12
+ onClick={onClick}
13
+ textColor={theme.m3Schema.primary}
14
+ borderColor={theme.m3Schema.outline}
15
+ className={className}
16
+ />
17
+ );
18
+ };
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { fn } from 'storybook/test';
3
+
4
+ import { TextButton } from './text-button';
5
+
6
+ const meta = {
7
+ title: 'm3/button/TextButton',
8
+ component: TextButton,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ text: 'text',
15
+ },
16
+ args: { onClick: fn() },
17
+ } satisfies Meta<typeof TextButton>;
18
+
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+
22
+ export const Default: Story = {
23
+ args: {
24
+ text: 'Button',
25
+ },
26
+ };
27
+
28
+ export const Disabled: Story = {
29
+ args: {
30
+ text: 'disabled',
31
+ disabled: true,
32
+ },
33
+ };
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+ import { useTheme, Theme } from '@emotion/react';
3
+
4
+ import { CommonButton, CommonTypeStyle } from './common-button';
5
+
6
+ export const TextButton = ({ text, onClick, className, textColor }: CommonTypeStyle) => {
7
+ const theme = useTheme() as Theme;
8
+
9
+ return (
10
+ <CommonButton
11
+ text={text}
12
+ onClick={onClick}
13
+ textColor={textColor ?? theme.m3Schema.primary}
14
+ className={className}
15
+ />
16
+ );
17
+ };
@@ -0,0 +1,29 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { fn } from 'storybook/test';
3
+
4
+ import { Checkbox } from './checkbox';
5
+
6
+ const meta = {
7
+ title: 'm3/Checkbox',
8
+ component: Checkbox,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ args: { onChange: fn(), checked: false },
14
+ } satisfies Meta<typeof Checkbox>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof meta>;
18
+
19
+ export const Default: Story = {
20
+ args: {
21
+ checked: false,
22
+ },
23
+ };
24
+
25
+ export const Checked: Story = {
26
+ args: {
27
+ checked: true,
28
+ },
29
+ };
@@ -0,0 +1,53 @@
1
+ import styled from '@emotion/styled';
2
+ import { Theme } from '@emotion/react';
3
+ import { SvgIcon } from '../helpers';
4
+
5
+
6
+ export const CheckboxRootWrapper = styled.div`
7
+ display: inline-flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ position: relative;
11
+ box-sizing: border-box;
12
+ -webkit-tap-highlight-color: transparent;
13
+ background-color: transparent;
14
+ outline: 0;
15
+ border: 0;
16
+ margin: 0;
17
+ cursor: pointer;
18
+ user-select: none;
19
+ vertical-align: middle;
20
+ appearance: none;
21
+ text-decoration: none;
22
+ border-radius: 50%;
23
+ `;
24
+
25
+ export const CheckboxCheckedIcon = styled(SvgIcon)`
26
+ svg {
27
+ path {
28
+ fill: ${({ theme }: { theme?: Theme }) => theme?.m3Schema.onSurfaceVariant};
29
+ }
30
+ }
31
+ `;
32
+
33
+ export const CheckboxUncheckedIcon = styled(SvgIcon)`
34
+ svg {
35
+ path {
36
+ fill: ${({ theme }: { theme?: Theme }) => theme?.m3Schema.onSurfaceVariant};
37
+ }
38
+ }
39
+ `;
40
+
41
+ export const CheckboxInput = styled.input`
42
+ cursor: inherit;
43
+ position: absolute;
44
+ opacity: 0;
45
+ width: 100%;
46
+ height: 100%;
47
+ top: 0;
48
+ left: 0;
49
+ margin: 0;
50
+ padding: 0;
51
+ z-index: 1;
52
+ `;
53
+
@@ -0,0 +1,49 @@
1
+ import * as React from 'react';
2
+ import { useCallback } from 'react';
3
+ import CheckBoxIcon from '@material-design-icons/svg/filled/check_box.svg';
4
+ import CheckBoxOutlineBlankIcon from '@material-design-icons/svg/filled/check_box_outline_blank.svg';
5
+
6
+ import {
7
+ CheckboxRootWrapper,
8
+ CheckboxInput,
9
+ CheckboxUncheckedIcon,
10
+ CheckboxCheckedIcon,
11
+ } from './checkbox.style';
12
+
13
+ export type CheckboxProps = {
14
+ checked: boolean;
15
+ onChange?: (checked: boolean) => void;
16
+ }
17
+
18
+ export const Checkbox = ({ checked, onChange }: CheckboxProps) => {
19
+ return (
20
+ <div>
21
+ <CheckboxRootWrapper>
22
+ <CheckboxInput
23
+ type="checkbox"
24
+ checked={checked}
25
+ onChange={useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
26
+ if (onChange) {
27
+ onChange(event.target.checked);
28
+ }
29
+ }, [onChange])}
30
+ />
31
+ {
32
+ checked ? (
33
+ <CheckboxCheckedIcon
34
+ width={24}
35
+ height={24}
36
+ icon={CheckBoxIcon}
37
+ />
38
+ ) : (
39
+ <CheckboxUncheckedIcon
40
+ width={24}
41
+ height={24}
42
+ icon={CheckBoxOutlineBlankIcon}
43
+ />
44
+ )
45
+ }
46
+ </CheckboxRootWrapper>
47
+ </div>
48
+ );
49
+ };
@@ -0,0 +1,5 @@
1
+ import { Checkbox } from './checkbox';
2
+
3
+ export {
4
+ Checkbox,
5
+ };
@@ -0,0 +1,14 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ export const BackdropStyled = styled.div`
4
+ background-color: ${({ theme }) => theme.m3Schema.scrim}85;
5
+ position: fixed;
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: center;
9
+ top: 0;
10
+ left: 0;
11
+ right: 0;
12
+ bottoM: 0;
13
+ z-index: -1;
14
+ `;
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+
3
+ import { BackdropStyled } from './backdrop.style';
4
+
5
+ export const Backdrop = () => {
6
+ return (
7
+ <BackdropStyled aria-hidden="true"/>
8
+ );
9
+ };
@@ -0,0 +1,5 @@
1
+ import { Backdrop } from './backdrop';
2
+
3
+ export {
4
+ Backdrop,
5
+ };
@@ -0,0 +1,19 @@
1
+ import { Backdrop } from './backdrop';
2
+ import { NoStyleButton } from './no-style-button';
3
+ import { Popup } from './popup';
4
+ import { ColumnLeft, ColumnCenter, RowCenter, RowStart, Stack} from './stack';
5
+ import { useOutsideClick } from './outside-click';
6
+ import { SvgIcon } from './svg-icon';
7
+
8
+ export {
9
+ Backdrop,
10
+ NoStyleButton,
11
+ Popup,
12
+ ColumnLeft,
13
+ ColumnCenter,
14
+ RowCenter,
15
+ RowStart,
16
+ Stack,
17
+ useOutsideClick,
18
+ SvgIcon,
19
+ }
@@ -0,0 +1,5 @@
1
+ import { NoStyleButton } from './no-style-button.style';
2
+
3
+ export {
4
+ NoStyleButton,
5
+ };
@@ -0,0 +1,12 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ export const NoStyleButton = styled.button`
4
+ background-color: transparent;
5
+ cursor: pointer;
6
+ border: none;
7
+ padding: 0;
8
+ margin: 0;
9
+ -webkit-tap-highlight-color: transparent;
10
+ appearance: none;
11
+ user-select: none;
12
+ `;
@@ -0,0 +1,17 @@
1
+ import { MutableRefObject, useEffect } from 'react';
2
+
3
+ export const useOutsideClick = (ref: MutableRefObject<HTMLElement | undefined | null>, callback: (event: MouseEvent) => void) => {
4
+ const handleClickOutside = (event: DocumentEventMap['mousedown']) => {
5
+ const target = event.target as HTMLElement;
6
+ if (ref.current && !ref.current?.contains(target)) {
7
+ callback(event);
8
+ }
9
+ };
10
+
11
+ useEffect(() => {
12
+ document.addEventListener('mousedown', handleClickOutside);
13
+ return () => {
14
+ document.removeEventListener('mousedown', handleClickOutside);
15
+ };
16
+ });
17
+ };
@@ -0,0 +1 @@
1
+ export { Popup } from './popup';
@@ -0,0 +1,14 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ export type PopupStyleType = {
4
+ zIndex: number;
5
+ }
6
+
7
+ export const PopupStyle = styled.div`
8
+ position: fixed;
9
+ z-index: ${({ zIndex }: PopupStyleType) => zIndex};
10
+ top: 0;
11
+ left: 0;
12
+ right: 0;
13
+ bottoM: 0;
14
+ `;
@@ -0,0 +1,17 @@
1
+ import * as React from 'react';
2
+
3
+ import { PopupStyle } from './popup.style';
4
+
5
+ type componentType = {
6
+ children: React.ReactNode;
7
+ zIndex: number;
8
+ className?: string;
9
+ }
10
+
11
+ export const Popup = ({ children, zIndex, className }: componentType) => {
12
+ return (
13
+ <PopupStyle zIndex={zIndex} className={className}>
14
+ {children}
15
+ </PopupStyle>
16
+ );
17
+ };
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import { SerializedStyles } from '@emotion/react';
3
+
4
+ import { Stack } from './stack';
5
+
6
+ type componentType = {
7
+ children: React.ReactNode;
8
+ css?: SerializedStyles;
9
+ }
10
+
11
+ export const ColumnCenter = ({ children, css }: componentType) => {
12
+ return (
13
+ <Stack
14
+ direction="column"
15
+ alignItems="center"
16
+ justifyContent="center"
17
+ css={css}
18
+ >
19
+ {children}
20
+ </Stack>
21
+ );
22
+ };
@@ -0,0 +1,22 @@
1
+ import * as React from 'react';
2
+ import { SerializedStyles } from '@emotion/react';
3
+
4
+ import { Stack } from './stack';
5
+
6
+ type componentType = {
7
+ children: React.ReactNode;
8
+ css?: SerializedStyles;
9
+ }
10
+
11
+ export const ColumnLeft = ({ children, css }: componentType) => {
12
+ return (
13
+ <Stack
14
+ direction="column"
15
+ alignItems="start"
16
+ justifyContent="center"
17
+ css={css}
18
+ >
19
+ {children}
20
+ </Stack>
21
+ );
22
+ };
@@ -0,0 +1,13 @@
1
+ import { ColumnLeft } from './column-left';
2
+ import { ColumnCenter } from './column-center';
3
+ import { RowCenter } from './row-center';
4
+ import { RowStart } from './row-start';
5
+ import { Stack } from './stack';
6
+
7
+ export {
8
+ ColumnLeft,
9
+ ColumnCenter,
10
+ RowCenter,
11
+ RowStart,
12
+ Stack,
13
+ }
@@ -0,0 +1,19 @@
1
+ import * as React from 'react';
2
+
3
+ import { Stack } from './stack';
4
+
5
+ type componentType = {
6
+ children: React.ReactNode;
7
+ }
8
+
9
+ export const RowCenter = ({ children }: componentType) => {
10
+ return (
11
+ <Stack
12
+ direction="row"
13
+ alignItems="center"
14
+ justifyContent="center"
15
+ >
16
+ {children}
17
+ </Stack>
18
+ );
19
+ };
@@ -0,0 +1,20 @@
1
+
2
+ import * as React from 'react';
3
+
4
+ import { Stack } from './stack';
5
+
6
+ type componentType = {
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ export const RowStart = ({ children }: componentType) => {
11
+ return (
12
+ <Stack
13
+ direction="row"
14
+ alignItems="start"
15
+ justifyContent="center"
16
+ >
17
+ {children}
18
+ </Stack>
19
+ );
20
+ };
@@ -0,0 +1,16 @@
1
+ import styled from '@emotion/styled';
2
+
3
+ type componentType = {
4
+ direction: 'row' | 'column'
5
+ justifyContent: 'start' | 'center' | 'space-between' | 'space-around' | 'space-evenly' | 'end'
6
+ alignItems: 'stretch' | 'center' | 'start' | 'end'
7
+ gap?: number
8
+ }
9
+
10
+ export const Stack = styled.div`
11
+ display: flex;
12
+ flex-direction: ${({ direction }: componentType) => direction};
13
+ justify-content: ${({ justifyContent }: componentType) => justifyContent};
14
+ align-items: ${({ alignItems }: componentType) => alignItems};
15
+ gap: ${({ gap }: componentType) => gap ? `${gap}px` : 'initial'};
16
+ `;
@@ -0,0 +1,5 @@
1
+ import { SvgIcon } from './svg-icon';
2
+
3
+ export {
4
+ SvgIcon,
5
+ };
@@ -0,0 +1,46 @@
1
+ import * as React from 'react';
2
+ import styled from '@emotion/styled';
3
+
4
+ type componentTypeStyle = {
5
+ width?: number;
6
+ height?: number;
7
+ color?: string;
8
+ className?: string;
9
+ }
10
+
11
+ export const SvgIconStyle = styled.div`
12
+ display: flex;
13
+ width: ${({ width }: componentTypeStyle) => width}px;
14
+ height: ${({ height }: componentTypeStyle) => height}px;
15
+
16
+ svg {
17
+ width: ${({ width }: componentTypeStyle) => width}px;
18
+ height: ${({ height }: componentTypeStyle) => height}px;
19
+ }
20
+ path {
21
+ fill: ${({ color }: componentTypeStyle) => color};
22
+ };
23
+
24
+ circle {
25
+ fill: ${({ color }: componentTypeStyle) => color};
26
+ };
27
+ `;
28
+
29
+ type componentType = {
30
+ icon: string;
31
+ } & componentTypeStyle;
32
+
33
+ export const SvgIcon = ({ icon, width, height, color, className }: componentType) => {
34
+ const Icon = icon;
35
+
36
+ return (
37
+ <SvgIconStyle
38
+ width={width}
39
+ height={height}
40
+ color={color}
41
+ className={className}
42
+ >
43
+ <Icon />
44
+ </SvgIconStyle>
45
+ );
46
+ };
@@ -0,0 +1,2 @@
1
+ export { FilledButton, OutlinedButton, TextButton } from './button';
2
+ export { Checkbox } from './checkbox';
@@ -0,0 +1,19 @@
1
+ import { useTheme } from '@emotion/react';
2
+ import * as React from 'react';
3
+
4
+ import { TextStyle, TypographyProps } from './m3-typography';
5
+
6
+ export const Body = ({ size, color, children, className }: TypographyProps) => {
7
+ const theme = useTheme();
8
+
9
+ return (
10
+ <TextStyle
11
+ className={className}
12
+ body={theme.m3TextStyle.body}
13
+ size={size}
14
+ color={color}
15
+ >
16
+ {children}
17
+ </TextStyle>
18
+ );
19
+ };
@@ -0,0 +1,19 @@
1
+ import { useTheme } from '@emotion/react';
2
+ import * as React from 'react';
3
+
4
+ import { TextStyle, TypographyProps } from './m3-typography';
5
+
6
+ export const Display = ({ size, color, children, className }: TypographyProps) => {
7
+ const theme = useTheme();
8
+
9
+ return (
10
+ <TextStyle
11
+ className={className}
12
+ body={theme.m3TextStyle.display}
13
+ size={size}
14
+ color={color}
15
+ >
16
+ {children}
17
+ </TextStyle>
18
+ );
19
+ };
@@ -0,0 +1,19 @@
1
+ import { useTheme } from '@emotion/react';
2
+ import * as React from 'react';
3
+
4
+ import { TextStyle, TypographyProps } from './m3-typography';
5
+
6
+ export const Headline = ({ size, color, children, className }: TypographyProps) => {
7
+ const theme = useTheme();
8
+
9
+ return (
10
+ <TextStyle
11
+ className={className}
12
+ body={theme.m3TextStyle.headline}
13
+ size={size}
14
+ color={color}
15
+ >
16
+ {children}
17
+ </TextStyle>
18
+ );
19
+ };
@@ -0,0 +1,13 @@
1
+ import { Title } from './title';
2
+ import { Body } from './body';
3
+ import { Label } from './label';
4
+ import { Display } from './display';
5
+ import { Headline } from './headline';
6
+
7
+ export {
8
+ Title,
9
+ Body,
10
+ Label,
11
+ Display,
12
+ Headline,
13
+ }
@@ -0,0 +1,19 @@
1
+ import { useTheme } from '@emotion/react';
2
+ import * as React from 'react';
3
+
4
+ import { TextStyle, TypographyProps } from './m3-typography';
5
+
6
+ export const Label = ({ size, color, children, className }: TypographyProps) => {
7
+ const theme = useTheme();
8
+
9
+ return (
10
+ <TextStyle
11
+ className={className}
12
+ body={theme.m3TextStyle.label}
13
+ size={size}
14
+ color={color}
15
+ >
16
+ {children}
17
+ </TextStyle>
18
+ );
19
+ };
@@ -0,0 +1,45 @@
1
+ import * as React from 'react';
2
+ import styled from '@emotion/styled';
3
+ import { Theme } from '@emotion/react'
4
+ import { M3TextStylesBody } from '@choochoochoo/jp.theme';
5
+
6
+ import { TypographySize } from './typography-size';
7
+
8
+ export function getTextStyle (styleBody: M3TextStylesBody, size: TypographySize) {
9
+ switch (size) {
10
+ case 'lg': {
11
+ return styleBody.large;
12
+ }
13
+ case 'sm': {
14
+ return styleBody.small;
15
+ }
16
+ }
17
+
18
+ return styleBody.medium;
19
+ }
20
+
21
+ export type TypographyProps = {
22
+ color: string;
23
+ size: TypographySize;
24
+ children: React.ReactNode;
25
+ className?: string;
26
+ }
27
+
28
+ type TextStyleType = {
29
+ body: M3TextStylesBody;
30
+ size: TypographySize;
31
+ color: string;
32
+ theme?: Theme;
33
+ }
34
+
35
+ export const TextStyle = styled.div(({ body, size, color }: TextStyleType) => ({
36
+ fontFamily: `${getTextStyle(body, size).fontFamilyName}`,
37
+ fontStyle: 'normal',
38
+ fontWeight: `${getTextStyle(body, size).fontWeight}`,
39
+ fontSize: `${getTextStyle(body, size).fontSize}px`,
40
+ lineHeight: `${getTextStyle(body, size).lineHeight}px`,
41
+ letterSpacing: `${getTextStyle(body, size).letterSpacing}px`,
42
+ color: `${color}`,
43
+ margin: 0,
44
+ }))
45
+
@@ -0,0 +1,19 @@
1
+ import { useTheme } from '@emotion/react';
2
+ import * as React from 'react';
3
+
4
+ import { TextStyle, TypographyProps } from './m3-typography';
5
+
6
+ export const Title = ({ size, color, children, className }: TypographyProps) => {
7
+ const theme = useTheme();
8
+
9
+ return (
10
+ <TextStyle
11
+ className={className}
12
+ body={theme.m3TextStyle.title}
13
+ size={size}
14
+ color={color}
15
+ >
16
+ {children}
17
+ </TextStyle>
18
+ );
19
+ };
@@ -0,0 +1 @@
1
+ export type TypographySize = 'sm' | 'md' | 'lg';
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ // Default
4
+ "target": "es5",
5
+ "esModuleInterop": true,
6
+ "forceConsistentCasingInFileNames": true,
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+
10
+ // Added
11
+ "jsx": "react",
12
+ "module": "ESNext",
13
+ "sourceMap": true,
14
+ "outDir": "dist",
15
+ "moduleResolution": "node",
16
+ "allowSyntheticDefaultImports": true,
17
+ "typeRoots": [
18
+ "node_modules/@types",
19
+ "types"
20
+ ],
21
+ "allowImportingTsExtensions": true,
22
+ "emitDeclarationOnly": true,
23
+ "declaration": true,
24
+ "declarationDir": "dist"
25
+ },
26
+ "exclude": [
27
+ "src/**/*.stories.ts",
28
+ "src/**/*.stories.tsx"
29
+ ]
30
+ }
@@ -0,0 +1,12 @@
1
+ import '@emotion/react';
2
+ import { M3Palettes, M3Schema, M3TextStyles, ThemesEnum } from '@choochoochoo/jp.theme';
3
+
4
+ declare module '@emotion/react' {
5
+ export interface Theme {
6
+ themeId: ThemesEnum;
7
+ m3Schema: M3Schema;
8
+ m3TextStyle: M3TextStyles;
9
+ m3Palettes: M3Palettes;
10
+ ext: object;
11
+ }
12
+ }