@charcoal-ui/react-sandbox 1.0.0-alpha.1

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 (41) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +18 -0
  3. package/package.json +72 -0
  4. package/src/_lib/compat.ts +15 -0
  5. package/src/components/Carousel/index.story.tsx +86 -0
  6. package/src/components/Carousel/index.tsx +382 -0
  7. package/src/components/CarouselButton/index.story.tsx +44 -0
  8. package/src/components/CarouselButton/index.tsx +162 -0
  9. package/src/components/Filter/index.story.tsx +80 -0
  10. package/src/components/Filter/index.tsx +182 -0
  11. package/src/components/HintText/index.story.tsx +19 -0
  12. package/src/components/HintText/index.tsx +95 -0
  13. package/src/components/Layout/index.story.tsx +121 -0
  14. package/src/components/Layout/index.tsx +363 -0
  15. package/src/components/LeftMenu/index.tsx +68 -0
  16. package/src/components/MenuListItem/index.story.tsx +143 -0
  17. package/src/components/MenuListItem/index.tsx +226 -0
  18. package/src/components/Pager/index.story.tsx +102 -0
  19. package/src/components/Pager/index.tsx +255 -0
  20. package/src/components/Spinner/index.story.tsx +47 -0
  21. package/src/components/Spinner/index.tsx +86 -0
  22. package/src/components/SwitchCheckbox/index.story.tsx +32 -0
  23. package/src/components/SwitchCheckbox/index.tsx +147 -0
  24. package/src/components/TextEllipsis/helper.ts +57 -0
  25. package/src/components/TextEllipsis/index.story.tsx +41 -0
  26. package/src/components/TextEllipsis/index.tsx +35 -0
  27. package/src/components/WithIcon/index.story.tsx +145 -0
  28. package/src/components/WithIcon/index.tsx +158 -0
  29. package/src/components/icons/Base.tsx +75 -0
  30. package/src/components/icons/DotsIcon.tsx +33 -0
  31. package/src/components/icons/InfoIcon.tsx +30 -0
  32. package/src/components/icons/NextIcon.tsx +47 -0
  33. package/src/components/icons/WedgeIcon.tsx +57 -0
  34. package/src/foundation/contants.ts +6 -0
  35. package/src/foundation/hooks.ts +195 -0
  36. package/src/foundation/support.ts +29 -0
  37. package/src/foundation/utils.ts +31 -0
  38. package/src/index.ts +45 -0
  39. package/src/misc/storybook-helper.ts +17 -0
  40. package/src/styled.ts +3 -0
  41. package/src/type.d.ts +12 -0
@@ -0,0 +1,182 @@
1
+ import React from 'react'
2
+ import styled, { css } from 'styled-components'
3
+ import { useComponentAbstraction, LinkProps } from '@charcoal-ui/react'
4
+ import { maxWidth } from '@charcoal-ui/utils'
5
+
6
+ interface Props<T extends HTMLElement> {
7
+ active?: boolean
8
+ hover?: boolean
9
+ reactive?: boolean
10
+ children: React.ReactNode
11
+ onClick?: React.MouseEventHandler<T>
12
+ }
13
+
14
+ interface FilterIconButtonProps extends Props<HTMLButtonElement> {
15
+ width?: number
16
+ height?: number
17
+ }
18
+
19
+ export const FilterButton = React.forwardRef(function FilterButton(
20
+ {
21
+ onClick,
22
+ children,
23
+ active = false,
24
+ hover,
25
+ reactive = false,
26
+ }: Props<HTMLButtonElement>,
27
+ ref: React.Ref<HTMLButtonElement>
28
+ ) {
29
+ return (
30
+ <ButtonLike
31
+ active={active}
32
+ reactive={reactive}
33
+ hover={hover}
34
+ onClick={active && !reactive ? undefined : onClick}
35
+ ref={ref}
36
+ >
37
+ {children}
38
+ </ButtonLike>
39
+ )
40
+ })
41
+
42
+ export const FilterIconButton = React.forwardRef(function FilterIconButton(
43
+ {
44
+ onClick,
45
+ children,
46
+ active = false,
47
+ hover,
48
+ reactive = false,
49
+ width,
50
+ height,
51
+ }: FilterIconButtonProps,
52
+ ref: React.Ref<HTMLButtonElement>
53
+ ) {
54
+ return (
55
+ <StyledButtonLike
56
+ active={active}
57
+ reactive={reactive}
58
+ hover={hover}
59
+ onClick={active && !reactive ? undefined : onClick}
60
+ ref={ref}
61
+ buttonWidth={width}
62
+ buttonHeight={height}
63
+ >
64
+ {children}
65
+ </StyledButtonLike>
66
+ )
67
+ })
68
+
69
+ export const FilterLink = React.forwardRef(function FilterLink(
70
+ {
71
+ onClick,
72
+ children,
73
+ active = false,
74
+ hover,
75
+ reactive = false,
76
+ ...props
77
+ }: Props<HTMLAnchorElement> & LinkProps,
78
+ ref: React.Ref<HTMLAnchorElement>
79
+ ) {
80
+ const { Link } = useComponentAbstraction()
81
+ if (active && !reactive) {
82
+ return (
83
+ <PlainElement active hover={hover} ref={ref}>
84
+ {children}
85
+ </PlainElement>
86
+ )
87
+ } else {
88
+ return (
89
+ <Link {...props} onClick={onClick}>
90
+ <PlainElement
91
+ active={active}
92
+ reactive={reactive}
93
+ hover={hover}
94
+ ref={ref}
95
+ >
96
+ {children}
97
+ </PlainElement>
98
+ </Link>
99
+ )
100
+ }
101
+ })
102
+
103
+ interface ButtonCssProps {
104
+ active?: boolean
105
+ hover?: boolean
106
+ reactive?: boolean
107
+ }
108
+
109
+ const buttonCss = css`
110
+ display: block;
111
+ outline: none;
112
+ border: none;
113
+ padding: 9px 24px;
114
+ font-size: 14px;
115
+ line-height: 22px;
116
+ font-weight: bold;
117
+ border-radius: /* absurd radius, but ensures rounded corners */ 2000px;
118
+ transition: color 0.2s;
119
+ color: ${({ theme }) => theme.color.text3};
120
+ cursor: pointer;
121
+ user-select: none;
122
+ background-color: transparent;
123
+
124
+ &:hover {
125
+ color: ${({ theme }) => theme.color.text2};
126
+ }
127
+
128
+ ${({ hover = false }: ButtonCssProps) =>
129
+ hover &&
130
+ css`
131
+ color: ${({ theme }) => theme.color.text2};
132
+ `}
133
+
134
+ ${({ active = false }: ButtonCssProps) =>
135
+ active &&
136
+ css`
137
+ background-color: ${({ theme }) => theme.color.surface3};
138
+ color: ${({ theme }) => theme.color.text2};
139
+ `}
140
+
141
+ ${({ active = false, reactive = false }) =>
142
+ active &&
143
+ !reactive &&
144
+ css`
145
+ cursor: default;
146
+ `}
147
+
148
+ @media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
149
+ padding: 5px 16px;
150
+ }
151
+ `
152
+
153
+ const padding0Css = css`
154
+ padding: 0;
155
+
156
+ @media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
157
+ padding: 0;
158
+ }
159
+ `
160
+
161
+ const ButtonLike = styled.button`
162
+ ${buttonCss}
163
+ `
164
+
165
+ const PlainElement = styled.span`
166
+ ${buttonCss}
167
+ `
168
+
169
+ const StyledButtonLike = styled(ButtonLike)<{
170
+ buttonWidth: number | undefined
171
+ buttonHeight: number | undefined
172
+ }>`
173
+ ${padding0Css};
174
+ ${(p) => p.buttonWidth !== undefined && `width: ${p.buttonWidth}px;`}
175
+ ${(p) => p.buttonHeight !== undefined && `height: ${p.buttonHeight}px;`}
176
+ `
177
+
178
+ const Filter = styled.div`
179
+ display: flex;
180
+ `
181
+
182
+ export default Filter
@@ -0,0 +1,19 @@
1
+ import React from 'react'
2
+ import { Story } from '../../_lib/compat'
3
+ import HintText from '.'
4
+
5
+ export default {
6
+ title: 'Sandbox/HintText',
7
+ component: HintText,
8
+ }
9
+
10
+ const Template: Story<{ hintText: string; context: 'page' | 'section' }> = (
11
+ args
12
+ ) => <HintText context={args.context}>{args.hintText}</HintText>
13
+
14
+ export const Default = Template.bind({})
15
+ Default.args = {
16
+ hintText:
17
+ 'ヒントテキストだよおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお',
18
+ context: 'section',
19
+ }
@@ -0,0 +1,95 @@
1
+ import React from 'react'
2
+ import styled, { css } from 'styled-components'
3
+ import { theme } from '../../styled'
4
+ import InfoIcon from '../icons/InfoIcon'
5
+ import { maxWidth } from '@charcoal-ui/utils'
6
+
7
+ type Context = 'page' | 'section'
8
+ interface Props {
9
+ children: React.ReactNode
10
+ context: Context
11
+ className?: string
12
+ }
13
+
14
+ export default function HintText({ children, context, className }: Props) {
15
+ return (
16
+ <Container className={className} context={context}>
17
+ <IconWrap>
18
+ <InfoIcon />
19
+ </IconWrap>
20
+ <Text>{children}</Text>
21
+ </Container>
22
+ )
23
+ }
24
+
25
+ const Container = styled.div.attrs<Props, ReturnType<typeof styledProps>>(
26
+ styledProps
27
+ )`
28
+ ${(p) =>
29
+ theme((o) => [
30
+ o.bg.surface3,
31
+ o.borderRadius(8),
32
+ o.padding.vertical(p.default.vertical),
33
+ o.padding.horizontal(p.default.horizontal),
34
+ ])}
35
+
36
+ @media ${({ theme: t }) => maxWidth(t.breakpoint.screen1)} {
37
+ ${(p) =>
38
+ theme((o) => [
39
+ o.padding.vertical(p.screen1.vertical),
40
+ o.padding.horizontal(p.screen1.horizontal),
41
+ ])}
42
+ }
43
+
44
+ display: flex;
45
+ align-items: flex-start;
46
+ ${(p) =>
47
+ p.context === 'page' &&
48
+ css`
49
+ justify-content: center;
50
+ `}
51
+ `
52
+
53
+ const IconWrap = styled.div`
54
+ display: flex;
55
+ align-items: center;
56
+ color: ${(p) => p.theme.color.text4};
57
+ height: 22px;
58
+ margin: -4px 4px -4px 0;
59
+ `
60
+
61
+ const Text = styled.p`
62
+ ${theme((o) => [o.font.text2, o.typography(14)])}
63
+ margin: 0;
64
+ `
65
+
66
+ function styledProps(props: Props) {
67
+ return { ...props, ...contextToProps(props.context) }
68
+ }
69
+
70
+ function contextToProps(context: Context) {
71
+ switch (context) {
72
+ case 'page':
73
+ return {
74
+ default: {
75
+ horizontal: 40,
76
+ vertical: 24,
77
+ },
78
+ screen1: {
79
+ horizontal: 16,
80
+ vertical: 16,
81
+ },
82
+ } as const
83
+ case 'section':
84
+ return {
85
+ default: {
86
+ horizontal: 16,
87
+ vertical: 16,
88
+ },
89
+ screen1: {
90
+ horizontal: 16,
91
+ vertical: 16,
92
+ },
93
+ } as const
94
+ }
95
+ }
@@ -0,0 +1,121 @@
1
+ import React from 'react'
2
+ import styled from 'styled-components'
3
+ import { dummyText } from '../../misc/storybook-helper'
4
+ import { theme } from '../../styled'
5
+ import LeftMenu from '../LeftMenu'
6
+ import Layout, { LayoutItem, LayoutItemBody, LayoutItemHeader } from '.'
7
+
8
+ export default {
9
+ title: 'Sandbox/Layout',
10
+ component: Layout,
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ },
14
+ }
15
+
16
+ export function Basic() {
17
+ const menu = <DummyMenu />
18
+ const header = <>Header</>
19
+ return (
20
+ <Layout menu={menu} header={header}>
21
+ <DummyCard span={3}>Span 3</DummyCard>
22
+ <DummyCard span={2}>Span 2</DummyCard>
23
+ <DummyCard span={1}>Span 1</DummyCard>
24
+ <DummyCard span={1}>Span 1</DummyCard>
25
+ <DummyCard span={1}>Span 1</DummyCard>
26
+ <DummyCard span={1}>Span 1</DummyCard>
27
+ </Layout>
28
+ )
29
+ }
30
+
31
+ export function NoMenu() {
32
+ const header = <>Header</>
33
+ return (
34
+ <Layout header={header}>
35
+ <DummyCard span={3}>Span 3</DummyCard>
36
+ <DummyCard span={2}>Span 2</DummyCard>
37
+ <DummyCard span={1}>Span 1</DummyCard>
38
+ <DummyCard span={1}>Span 1</DummyCard>
39
+ <DummyCard span={1}>Span 1</DummyCard>
40
+ <DummyCard span={1}>Span 1</DummyCard>
41
+ </Layout>
42
+ )
43
+ }
44
+
45
+ export function Wide() {
46
+ const menu = <DummyMenu />
47
+ const header = <>Header</>
48
+ return (
49
+ <Layout menu={menu} header={header} wide>
50
+ <LayoutItem span={3}>
51
+ <LayoutItemHeader>Wide</LayoutItemHeader>
52
+ <LayoutItemBody>
53
+ <Dummy>Hello, Flexible Grid Layout!</Dummy>
54
+ </LayoutItemBody>
55
+ </LayoutItem>
56
+ </Layout>
57
+ )
58
+ }
59
+
60
+ export function Center() {
61
+ const header = <>Header</>
62
+ return (
63
+ <Layout header={header} wide center>
64
+ <LayoutItem span={3}>
65
+ <LayoutItemHeader>Center</LayoutItemHeader>
66
+ <LayoutItemBody>
67
+ <Dummy>Hello, Flexible Grid Layout!</Dummy>
68
+ </LayoutItemBody>
69
+ </LayoutItem>
70
+ </Layout>
71
+ )
72
+ }
73
+
74
+ function DummyCard({
75
+ span,
76
+ children,
77
+ }: {
78
+ span: number
79
+ children: React.ReactNode
80
+ }) {
81
+ return (
82
+ <LayoutItem span={span}>
83
+ <LayoutItemHeader>Dummy</LayoutItemHeader>
84
+ <LayoutItemBody>
85
+ <Dummy>{children}</Dummy>
86
+ </LayoutItemBody>
87
+ </LayoutItem>
88
+ )
89
+ }
90
+
91
+ const Dummy = styled.div`
92
+ ${theme((o) => o.height.column(2))}
93
+
94
+ ${dummyText}
95
+ `
96
+
97
+ function DummyMenu() {
98
+ const links = [
99
+ {
100
+ id: 'hello',
101
+ text: 'Hello',
102
+ to: '#hello',
103
+ },
104
+ {
105
+ id: 'world',
106
+ text: 'World',
107
+ to: '#world',
108
+ },
109
+ {
110
+ id: 'dummy',
111
+ text: 'Dummy',
112
+ to: '#dummy',
113
+ },
114
+ {
115
+ id: 'menu',
116
+ text: 'Menu',
117
+ to: '#menu',
118
+ },
119
+ ] as const
120
+ return <LeftMenu links={links} active="hello" />
121
+ }