@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.
- package/LICENSE +201 -0
- package/README.md +18 -0
- package/package.json +72 -0
- package/src/_lib/compat.ts +15 -0
- package/src/components/Carousel/index.story.tsx +86 -0
- package/src/components/Carousel/index.tsx +382 -0
- package/src/components/CarouselButton/index.story.tsx +44 -0
- package/src/components/CarouselButton/index.tsx +162 -0
- package/src/components/Filter/index.story.tsx +80 -0
- package/src/components/Filter/index.tsx +182 -0
- package/src/components/HintText/index.story.tsx +19 -0
- package/src/components/HintText/index.tsx +95 -0
- package/src/components/Layout/index.story.tsx +121 -0
- package/src/components/Layout/index.tsx +363 -0
- package/src/components/LeftMenu/index.tsx +68 -0
- package/src/components/MenuListItem/index.story.tsx +143 -0
- package/src/components/MenuListItem/index.tsx +226 -0
- package/src/components/Pager/index.story.tsx +102 -0
- package/src/components/Pager/index.tsx +255 -0
- package/src/components/Spinner/index.story.tsx +47 -0
- package/src/components/Spinner/index.tsx +86 -0
- package/src/components/SwitchCheckbox/index.story.tsx +32 -0
- package/src/components/SwitchCheckbox/index.tsx +147 -0
- package/src/components/TextEllipsis/helper.ts +57 -0
- package/src/components/TextEllipsis/index.story.tsx +41 -0
- package/src/components/TextEllipsis/index.tsx +35 -0
- package/src/components/WithIcon/index.story.tsx +145 -0
- package/src/components/WithIcon/index.tsx +158 -0
- package/src/components/icons/Base.tsx +75 -0
- package/src/components/icons/DotsIcon.tsx +33 -0
- package/src/components/icons/InfoIcon.tsx +30 -0
- package/src/components/icons/NextIcon.tsx +47 -0
- package/src/components/icons/WedgeIcon.tsx +57 -0
- package/src/foundation/contants.ts +6 -0
- package/src/foundation/hooks.ts +195 -0
- package/src/foundation/support.ts +29 -0
- package/src/foundation/utils.ts +31 -0
- package/src/index.ts +45 -0
- package/src/misc/storybook-helper.ts +17 -0
- package/src/styled.ts +3 -0
- package/src/type.d.ts +12 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
|
+
import styled, { createGlobalStyle, css } from 'styled-components'
|
|
3
|
+
import {
|
|
4
|
+
MAIN_COLUMN_HORIZONTAL_MIN_MARGIN,
|
|
5
|
+
RESPONSIVE_LEFT_WIDTH,
|
|
6
|
+
RESPONSIVE_MAIN_MAX_WIDTH,
|
|
7
|
+
} from '../../foundation/contants'
|
|
8
|
+
import { useMediaScreen1 } from '../../foundation/hooks'
|
|
9
|
+
import { columnPx, GUTTER_UNIT } from '@charcoal-ui/foundation'
|
|
10
|
+
import { maxWidth } from '@charcoal-ui/utils'
|
|
11
|
+
|
|
12
|
+
interface Props {
|
|
13
|
+
menu?: React.ReactNode
|
|
14
|
+
isHeaderTopMenu?: boolean
|
|
15
|
+
children: React.ReactNode
|
|
16
|
+
header?: React.ReactNode
|
|
17
|
+
wide?: boolean
|
|
18
|
+
center?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const LayoutConfigContext = React.createContext({
|
|
22
|
+
wide: false,
|
|
23
|
+
center: false,
|
|
24
|
+
withLeft: false,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export default function Layout({
|
|
28
|
+
menu,
|
|
29
|
+
children,
|
|
30
|
+
header,
|
|
31
|
+
center = false,
|
|
32
|
+
wide,
|
|
33
|
+
isHeaderTopMenu = false,
|
|
34
|
+
}: Props) {
|
|
35
|
+
const config = {
|
|
36
|
+
center,
|
|
37
|
+
wide: center ? true : wide ?? false,
|
|
38
|
+
withLeft: menu != null && !isHeaderTopMenu,
|
|
39
|
+
}
|
|
40
|
+
return (
|
|
41
|
+
<LayoutRoot>
|
|
42
|
+
<LayoutConfigContext.Provider value={config}>
|
|
43
|
+
{config.withLeft && <LeftArea>{menu}</LeftArea>}
|
|
44
|
+
<MainArea center={center}>
|
|
45
|
+
{header != null && <Header>{header}</Header>}
|
|
46
|
+
{isHeaderTopMenu && (
|
|
47
|
+
<HeaderTopMenuContainer>{menu}</HeaderTopMenuContainer>
|
|
48
|
+
)}
|
|
49
|
+
<Grid>{children}</Grid>
|
|
50
|
+
</MainArea>
|
|
51
|
+
</LayoutConfigContext.Provider>
|
|
52
|
+
<GlobalStyle />
|
|
53
|
+
</LayoutRoot>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const HeaderTopMenuContainer = styled.div`
|
|
58
|
+
margin-bottom: 40px;
|
|
59
|
+
overflow-x: auto;
|
|
60
|
+
word-break: keep-all;
|
|
61
|
+
|
|
62
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
63
|
+
margin-bottom: 0;
|
|
64
|
+
padding-left: 16px;
|
|
65
|
+
padding-bottom: 16px;
|
|
66
|
+
background-color: ${({ theme }) => theme.color.surface2};
|
|
67
|
+
}
|
|
68
|
+
`
|
|
69
|
+
|
|
70
|
+
const GlobalStyle = createGlobalStyle`
|
|
71
|
+
:root {
|
|
72
|
+
background-color: ${({ theme }) => theme.color.background2};
|
|
73
|
+
|
|
74
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
75
|
+
background-color: ${({ theme }) => theme.color.background1};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`
|
|
79
|
+
|
|
80
|
+
const LayoutRoot = styled.div`
|
|
81
|
+
display: flex;
|
|
82
|
+
background-color: ${({ theme }) => theme.color.background2};
|
|
83
|
+
|
|
84
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
85
|
+
background-color: ${({ theme }) => theme.color.background1};
|
|
86
|
+
}
|
|
87
|
+
`
|
|
88
|
+
|
|
89
|
+
const LeftArea = styled.div`
|
|
90
|
+
min-width: ${RESPONSIVE_LEFT_WIDTH}px;
|
|
91
|
+
padding: 40px 0 40px ${GUTTER_UNIT}px;
|
|
92
|
+
box-sizing: border-box;
|
|
93
|
+
|
|
94
|
+
@media ${({ theme }) => theme.breakpoint.screen3} {
|
|
95
|
+
display: none;
|
|
96
|
+
}
|
|
97
|
+
`
|
|
98
|
+
|
|
99
|
+
const MainArea = styled.div<{ center: boolean }>`
|
|
100
|
+
flex-grow: 1;
|
|
101
|
+
/* https://www.w3.org/TR/css-flexbox-1/#min-size-auto */
|
|
102
|
+
min-width: 0;
|
|
103
|
+
max-width: ${(p) => (p.center ? columnPx(6) : RESPONSIVE_MAIN_MAX_WIDTH)}px;
|
|
104
|
+
padding: 40px ${MAIN_COLUMN_HORIZONTAL_MIN_MARGIN}px;
|
|
105
|
+
margin: 0 auto;
|
|
106
|
+
display: flex;
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
|
|
109
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
110
|
+
padding: 0;
|
|
111
|
+
}
|
|
112
|
+
`
|
|
113
|
+
|
|
114
|
+
const Header = styled.div`
|
|
115
|
+
font-weight: bold;
|
|
116
|
+
margin-bottom: 12px;
|
|
117
|
+
font-size: 20px;
|
|
118
|
+
line-height: 28px;
|
|
119
|
+
color: ${({ theme }) => theme.color.text2};
|
|
120
|
+
|
|
121
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
122
|
+
margin-bottom: 0;
|
|
123
|
+
padding: 12px;
|
|
124
|
+
font-size: 16px;
|
|
125
|
+
line-height: 24px;
|
|
126
|
+
display: flex;
|
|
127
|
+
justify-content: center;
|
|
128
|
+
background-color: ${({ theme }) => theme.color.surface2};
|
|
129
|
+
}
|
|
130
|
+
`
|
|
131
|
+
|
|
132
|
+
const Grid = styled.div`
|
|
133
|
+
display: grid;
|
|
134
|
+
gap: ${GUTTER_UNIT}px;
|
|
135
|
+
grid-template-columns: 1fr;
|
|
136
|
+
grid-auto-columns: 1fr;
|
|
137
|
+
grid-auto-rows: auto;
|
|
138
|
+
|
|
139
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
140
|
+
gap: 0;
|
|
141
|
+
background-color: ${({ theme }) => theme.color.background1};
|
|
142
|
+
padding-bottom: 60px;
|
|
143
|
+
}
|
|
144
|
+
`
|
|
145
|
+
|
|
146
|
+
interface LayoutItemProps {
|
|
147
|
+
span: number
|
|
148
|
+
children?: React.ReactNode
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export const LayoutItem = React.forwardRef<HTMLDivElement, LayoutItemProps>(
|
|
152
|
+
function LayoutItem({ span, children }, ref) {
|
|
153
|
+
const { withLeft } = useContext(LayoutConfigContext)
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<StyledLayoutItem span={span} withLeft={withLeft} ref={ref}>
|
|
157
|
+
{children}
|
|
158
|
+
</StyledLayoutItem>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
interface StyledLayoutItemProps {
|
|
164
|
+
span: number
|
|
165
|
+
withLeft: boolean
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const StyledLayoutItem = styled.div<StyledLayoutItemProps>`
|
|
169
|
+
grid-column-start: auto;
|
|
170
|
+
grid-column-end: span ${(p) => p.span};
|
|
171
|
+
border-radius: 24px;
|
|
172
|
+
color: ${({ theme }) => theme.color.text2};
|
|
173
|
+
background-color: ${({ theme }) => theme.color.background1};
|
|
174
|
+
/* https://www.w3.org/TR/css-grid-1/#min-size-auto */
|
|
175
|
+
min-width: 0;
|
|
176
|
+
|
|
177
|
+
@media ${(p) =>
|
|
178
|
+
p.withLeft ? p.theme.breakpoint.screen4 : p.theme.breakpoint.screen3} {
|
|
179
|
+
${(p) =>
|
|
180
|
+
p.span > 2 &&
|
|
181
|
+
css`
|
|
182
|
+
grid-column-end: span 2;
|
|
183
|
+
`}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
187
|
+
${(p) =>
|
|
188
|
+
p.span > 1 &&
|
|
189
|
+
css`
|
|
190
|
+
grid-column-end: span 1;
|
|
191
|
+
`}
|
|
192
|
+
|
|
193
|
+
border-radius: 0;
|
|
194
|
+
padding-bottom: 40px;
|
|
195
|
+
}
|
|
196
|
+
`
|
|
197
|
+
|
|
198
|
+
export function LayoutItemHeader({ children }: { children: React.ReactNode }) {
|
|
199
|
+
const { wide, center } = useContext(LayoutConfigContext)
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<StyledLayoutItemHeader wide={wide} center={center}>
|
|
203
|
+
{children}
|
|
204
|
+
</StyledLayoutItemHeader>
|
|
205
|
+
)
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
interface StyledLayoutItemHeaderProps {
|
|
209
|
+
wide: boolean
|
|
210
|
+
center: boolean
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const StyledLayoutItemHeader = styled.div<StyledLayoutItemHeaderProps>`
|
|
214
|
+
padding: 0 ${(p) => (p.wide ? 40 : 24)}px;
|
|
215
|
+
height: ${(p) => (p.wide ? 64 : 48)}px;
|
|
216
|
+
display: grid;
|
|
217
|
+
align-items: center;
|
|
218
|
+
font-size: 16px;
|
|
219
|
+
line-height: 24px;
|
|
220
|
+
font-weight: bold;
|
|
221
|
+
background-color: ${({ theme }) => theme.color.surface2};
|
|
222
|
+
color: ${({ theme }) => theme.color.text2};
|
|
223
|
+
border-radius: 24px 24px 0 0;
|
|
224
|
+
${(p) =>
|
|
225
|
+
p.center &&
|
|
226
|
+
css`
|
|
227
|
+
justify-content: center;
|
|
228
|
+
`}
|
|
229
|
+
|
|
230
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
231
|
+
margin-top: 4px;
|
|
232
|
+
padding: 0 16px;
|
|
233
|
+
background: none;
|
|
234
|
+
overflow-x: auto;
|
|
235
|
+
border-radius: unset;
|
|
236
|
+
${(p) =>
|
|
237
|
+
p.wide &&
|
|
238
|
+
css`
|
|
239
|
+
height: 48px;
|
|
240
|
+
margin-top: 0;
|
|
241
|
+
`}
|
|
242
|
+
}
|
|
243
|
+
`
|
|
244
|
+
|
|
245
|
+
export const LAYOUT_ITEM_BODY_PADDING = {
|
|
246
|
+
wide: {
|
|
247
|
+
x: 40,
|
|
248
|
+
y: 40,
|
|
249
|
+
},
|
|
250
|
+
default: {
|
|
251
|
+
x: 24,
|
|
252
|
+
y: 24,
|
|
253
|
+
},
|
|
254
|
+
column1: {
|
|
255
|
+
x: 16,
|
|
256
|
+
y: 16,
|
|
257
|
+
},
|
|
258
|
+
narrow: {
|
|
259
|
+
x: 24,
|
|
260
|
+
yTop: 12,
|
|
261
|
+
yBottom: 20,
|
|
262
|
+
},
|
|
263
|
+
narrowColumn1: {
|
|
264
|
+
x: 16,
|
|
265
|
+
yTop: 4,
|
|
266
|
+
yBottom: 0,
|
|
267
|
+
},
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export function LayoutItemBody({
|
|
271
|
+
children,
|
|
272
|
+
horizontal = false,
|
|
273
|
+
narrow = false,
|
|
274
|
+
}: {
|
|
275
|
+
children: React.ReactNode
|
|
276
|
+
horizontal?: boolean
|
|
277
|
+
narrow?: boolean
|
|
278
|
+
}) {
|
|
279
|
+
const { wide } = useContext(LayoutConfigContext)
|
|
280
|
+
|
|
281
|
+
return (
|
|
282
|
+
<StyledLayoutItemBody wide={wide} horizontal={horizontal} narrow={narrow}>
|
|
283
|
+
{children}
|
|
284
|
+
</StyledLayoutItemBody>
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
interface StyledLayoutItemBodyProps {
|
|
289
|
+
wide: boolean
|
|
290
|
+
horizontal: boolean
|
|
291
|
+
narrow: boolean
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export const StyledLayoutItemBody = styled.div<StyledLayoutItemBodyProps>`
|
|
295
|
+
padding: ${(p) =>
|
|
296
|
+
p.narrow
|
|
297
|
+
? `${LAYOUT_ITEM_BODY_PADDING.narrow.yTop}px ${
|
|
298
|
+
p.horizontal ? 0 : LAYOUT_ITEM_BODY_PADDING.narrow.x
|
|
299
|
+
}px ${LAYOUT_ITEM_BODY_PADDING.narrow.yBottom}px`
|
|
300
|
+
: p.wide
|
|
301
|
+
? `${p.horizontal ? 0 : LAYOUT_ITEM_BODY_PADDING.wide.y}px ${
|
|
302
|
+
LAYOUT_ITEM_BODY_PADDING.wide.x
|
|
303
|
+
}px`
|
|
304
|
+
: `${p.horizontal ? 0 : LAYOUT_ITEM_BODY_PADDING.default.y}px ${
|
|
305
|
+
LAYOUT_ITEM_BODY_PADDING.default.x
|
|
306
|
+
}px`};
|
|
307
|
+
|
|
308
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
309
|
+
padding: ${(p) =>
|
|
310
|
+
p.narrow
|
|
311
|
+
? `${LAYOUT_ITEM_BODY_PADDING.narrowColumn1.yTop}px ${
|
|
312
|
+
p.horizontal ? 0 : LAYOUT_ITEM_BODY_PADDING.narrowColumn1.x
|
|
313
|
+
}px ${LAYOUT_ITEM_BODY_PADDING.narrowColumn1.yBottom}px`
|
|
314
|
+
: `${LAYOUT_ITEM_BODY_PADDING.column1.y}px ${
|
|
315
|
+
LAYOUT_ITEM_BODY_PADDING.column1.x
|
|
316
|
+
}px ${0}`};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
width: 100%;
|
|
320
|
+
box-sizing: border-box;
|
|
321
|
+
`
|
|
322
|
+
|
|
323
|
+
export function useLayoutItemBodyPadding() {
|
|
324
|
+
const { wide } = useContext(LayoutConfigContext)
|
|
325
|
+
return useMediaScreen1()
|
|
326
|
+
? LAYOUT_ITEM_BODY_PADDING.column1
|
|
327
|
+
: wide
|
|
328
|
+
? LAYOUT_ITEM_BODY_PADDING.wide
|
|
329
|
+
: LAYOUT_ITEM_BODY_PADDING.default
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export function CancelLayoutItemBodyPadding({
|
|
333
|
+
children,
|
|
334
|
+
cancelTop,
|
|
335
|
+
}: {
|
|
336
|
+
children: React.ReactNode
|
|
337
|
+
cancelTop?: boolean
|
|
338
|
+
}) {
|
|
339
|
+
const { wide } = useContext(LayoutConfigContext)
|
|
340
|
+
|
|
341
|
+
return (
|
|
342
|
+
<StyledCancelLayoutItemBodyPadding wide={wide} cancelTop={cancelTop}>
|
|
343
|
+
{children}
|
|
344
|
+
</StyledCancelLayoutItemBodyPadding>
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
interface StyledCancelLayoutItemBodyPaddingProps {
|
|
349
|
+
wide: boolean
|
|
350
|
+
cancelTop?: boolean
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/* eslint-disable max-len */
|
|
354
|
+
export const StyledCancelLayoutItemBodyPadding = styled.div<StyledCancelLayoutItemBodyPaddingProps>`
|
|
355
|
+
margin: 0 -${(p) => (p.wide ? LAYOUT_ITEM_BODY_PADDING.wide.x : LAYOUT_ITEM_BODY_PADDING.default.x)}px;
|
|
356
|
+
margin-top: -${({ cancelTop = false, wide }) => (!cancelTop ? 0 : wide ? LAYOUT_ITEM_BODY_PADDING.wide.y : LAYOUT_ITEM_BODY_PADDING.default.y)}px;
|
|
357
|
+
|
|
358
|
+
@media ${({ theme }) => maxWidth(theme.breakpoint.screen1)} {
|
|
359
|
+
margin: 0 -${LAYOUT_ITEM_BODY_PADDING.column1.x}px;
|
|
360
|
+
margin-top: -${({ cancelTop = false }) => (!cancelTop ? 0 : LAYOUT_ITEM_BODY_PADDING.column1.x)}px;
|
|
361
|
+
}
|
|
362
|
+
`
|
|
363
|
+
/* eslint-enable max-len */
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import styled from 'styled-components'
|
|
3
|
+
import { MenuListLinkItem } from '../MenuListItem'
|
|
4
|
+
import { useComponentAbstraction } from '@charcoal-ui/react'
|
|
5
|
+
|
|
6
|
+
interface Props<ID extends string> {
|
|
7
|
+
links: readonly {
|
|
8
|
+
text: string
|
|
9
|
+
to: string
|
|
10
|
+
id: ID
|
|
11
|
+
}[]
|
|
12
|
+
active: ID
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default function LeftMenu<ID extends string>({
|
|
16
|
+
links,
|
|
17
|
+
active,
|
|
18
|
+
}: Props<ID>) {
|
|
19
|
+
const { Link } = useComponentAbstraction()
|
|
20
|
+
return (
|
|
21
|
+
<Container>
|
|
22
|
+
{links.map((link, index) => (
|
|
23
|
+
<Link to={link.to} key={index}>
|
|
24
|
+
<LinkItem aria-current={link.id === active || undefined}>
|
|
25
|
+
{link.text}
|
|
26
|
+
</LinkItem>
|
|
27
|
+
</Link>
|
|
28
|
+
))}
|
|
29
|
+
</Container>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function LeftMenuContent<ID extends string>({ links }: Props<ID>) {
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
{links.map((link, index) => (
|
|
37
|
+
<MenuListLinkItem link={link.to} key={index} primary={link.text} />
|
|
38
|
+
))}
|
|
39
|
+
</>
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const Container = styled.div`
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
align-items: flex-start;
|
|
47
|
+
`
|
|
48
|
+
|
|
49
|
+
const LinkItem = styled.div`
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
color: ${({ theme }) => theme.color.text3};
|
|
53
|
+
border-radius: 24px;
|
|
54
|
+
font-weight: bold;
|
|
55
|
+
font-size: 14px;
|
|
56
|
+
line-height: 22px;
|
|
57
|
+
padding: 0 16px;
|
|
58
|
+
height: 40px;
|
|
59
|
+
transition: 0.2s color;
|
|
60
|
+
&:hover {
|
|
61
|
+
transition: 0.2s color;
|
|
62
|
+
color: ${({ theme }) => theme.color.text2};
|
|
63
|
+
}
|
|
64
|
+
&[aria-current] {
|
|
65
|
+
color: ${({ theme }) => theme.color.text2};
|
|
66
|
+
background-color: ${({ theme }) => theme.color.surface3};
|
|
67
|
+
}
|
|
68
|
+
`
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions'
|
|
2
|
+
import { boolean, select, text } from '@storybook/addon-knobs'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import styled from 'styled-components'
|
|
5
|
+
import SwitchCheckbox from '../SwitchCheckbox'
|
|
6
|
+
import WithIcon from '../WithIcon'
|
|
7
|
+
import MenuListItem, {
|
|
8
|
+
MenuListItemContext,
|
|
9
|
+
MenuListLabel,
|
|
10
|
+
MenuListLinkItem,
|
|
11
|
+
MenuListLinkItemWithIcon,
|
|
12
|
+
MenuListSpacer,
|
|
13
|
+
} from '.'
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
title: 'Sandbox/MenuListItem',
|
|
17
|
+
component: MenuListItem,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const Default = () => {
|
|
21
|
+
const primary = text('primary', 'Knob to change')
|
|
22
|
+
const secondary = text('secondary', '')
|
|
23
|
+
const disabled = boolean('diasbled', false)
|
|
24
|
+
const padding = select('padding', { '16': 16, '24': 24 }, 24)
|
|
25
|
+
const noHover = boolean('noHover', false)
|
|
26
|
+
return (
|
|
27
|
+
<MenuListItemContext.Provider value={{ padding }}>
|
|
28
|
+
<MenuListItem
|
|
29
|
+
primary={primary}
|
|
30
|
+
secondary={secondary === '' ? undefined : secondary}
|
|
31
|
+
disabled={disabled}
|
|
32
|
+
onClick={action('click')}
|
|
33
|
+
noHover={noHover}
|
|
34
|
+
/>
|
|
35
|
+
</MenuListItemContext.Provider>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const Simple = () => (
|
|
40
|
+
<MenuListItem
|
|
41
|
+
primary="Simple item"
|
|
42
|
+
secondary="with secondary"
|
|
43
|
+
onClick={action('click')}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
export const Disabled = () => (
|
|
48
|
+
<MenuListItem
|
|
49
|
+
primary="Disabled item"
|
|
50
|
+
disabled
|
|
51
|
+
onClick={action('disabled click')}
|
|
52
|
+
/>
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
export const Link = () => (
|
|
56
|
+
<MenuListLinkItem
|
|
57
|
+
primary="This is link"
|
|
58
|
+
onClick={action('link click')}
|
|
59
|
+
link="#linkTo"
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export const HardLink = () => (
|
|
64
|
+
<MenuListLinkItem
|
|
65
|
+
primary='This is link with target "_blank"'
|
|
66
|
+
onClick={action('link click')}
|
|
67
|
+
link="#linkTo"
|
|
68
|
+
target="_blank"
|
|
69
|
+
rel="noopener noreferrer"
|
|
70
|
+
/>
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
export const InlineIcon = () => (
|
|
74
|
+
<MenuListItem
|
|
75
|
+
primary={
|
|
76
|
+
<WithIcon icon={<TestInlineIcon />}>Label with inline icon</WithIcon>
|
|
77
|
+
}
|
|
78
|
+
onClick={action('toggle')}
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
export const Icon = () => (
|
|
83
|
+
<MenuListLinkItemWithIcon
|
|
84
|
+
primary="Link with 24px icon"
|
|
85
|
+
icon={<TestIcon />}
|
|
86
|
+
link="#linkTo"
|
|
87
|
+
/>
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
export const NoHoverEffect = () => (
|
|
91
|
+
<MenuListItem
|
|
92
|
+
primary="With toggle (no hover effect)"
|
|
93
|
+
onClick={action('toggle')}
|
|
94
|
+
noHover
|
|
95
|
+
>
|
|
96
|
+
<SwitchCheckbox checked onChange={action('toggle')} />
|
|
97
|
+
</MenuListItem>
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
export const Spacer = () => (
|
|
101
|
+
<>
|
|
102
|
+
<MenuListItem primary="↓ This is spacer" />
|
|
103
|
+
<MenuListSpacer />
|
|
104
|
+
<MenuListItem primary="↑ This is spacer" />
|
|
105
|
+
</>
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
export const Label = () => (
|
|
109
|
+
<>
|
|
110
|
+
<MenuListLabel>Label</MenuListLabel>
|
|
111
|
+
<MenuListItem primary="Label grouped items" />
|
|
112
|
+
</>
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
export const TextEllipsis = () => (
|
|
116
|
+
<div
|
|
117
|
+
css={`
|
|
118
|
+
width: 300px;
|
|
119
|
+
`}
|
|
120
|
+
>
|
|
121
|
+
<MenuListItem primary="Loooooooooooooooooooooooooong texxxxxxxxxxxxxxxxxxxxxxxxxt" />
|
|
122
|
+
</div>
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
const TestIcon = styled.div`
|
|
126
|
+
display: inline-block;
|
|
127
|
+
width: 24px;
|
|
128
|
+
height: 24px;
|
|
129
|
+
background-color: currentColor;
|
|
130
|
+
`
|
|
131
|
+
|
|
132
|
+
const TestInlineIcon = styled.div`
|
|
133
|
+
display: inline-flex;
|
|
134
|
+
vertical-align: top;
|
|
135
|
+
align-items: center;
|
|
136
|
+
&::before {
|
|
137
|
+
content: '';
|
|
138
|
+
display: inline-block;
|
|
139
|
+
height: 16px;
|
|
140
|
+
width: 16px;
|
|
141
|
+
background-color: currentColor;
|
|
142
|
+
}
|
|
143
|
+
`
|