agroptima-design-system 0.11.1 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agroptima-design-system",
3
- "version": "0.11.1",
3
+ "version": "0.13.0",
4
4
  "scripts": {
5
5
  "dev": "npm run storybook",
6
6
  "storybook": "storybook dev -p 6006 --ci",
@@ -260,13 +260,7 @@
260
260
  &.success,
261
261
  &.warning,
262
262
  &.info,
263
- &.neutral,
264
- &.primary-outlined,
265
- &.error-outlined,
266
- &.success-outlined,
267
- &.warning-outlined,
268
- &.info-outlined,
269
- &.neutral-outlined {
263
+ &.neutral {
270
264
  &:disabled {
271
265
  background: color_alias.$neutral-color-50;
272
266
  }
@@ -279,7 +273,8 @@
279
273
  &.info-outlined,
280
274
  &.neutral-outlined {
281
275
  &:disabled {
282
- border: 1px solid transparent;
276
+ background: transparent;
277
+ border: 1px solid color_alias.$neutral-color-400;
283
278
  }
284
279
  }
285
280
  }
@@ -0,0 +1,71 @@
1
+ @use '../settings/color_alias';
2
+ @use '../settings/typography/content' as typography;
3
+ @use '../settings/config';
4
+ @use '../settings/breakpoints';
5
+
6
+ .card {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: config.$space-1x;
10
+ padding: config.$space-3x;
11
+
12
+ p {
13
+ margin: 0;
14
+ }
15
+
16
+ .actions {
17
+ display: flex;
18
+ gap: config.$space-4x;
19
+ }
20
+
21
+ .icon {
22
+ width: config.$icon-size-4x;
23
+ height: config.$icon-size-4x;
24
+ > svg {
25
+ width: 100%;
26
+ height: 100%;
27
+ }
28
+ }
29
+
30
+ .header {
31
+ display: flex;
32
+ flex-direction: row;
33
+ justify-content: space-between;
34
+ margin-bottom: config.$space-1x;
35
+
36
+ > .bold {
37
+ @include typography.body-bold;
38
+ }
39
+ }
40
+
41
+ .content {
42
+ margin-bottom: config.$space-2x;
43
+ }
44
+
45
+ .footer {
46
+ margin-top: auto;
47
+ .button {
48
+ width: 100%;
49
+ }
50
+ }
51
+
52
+ &.primary {
53
+ @include typography.body-regular-primary;
54
+ box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.25);
55
+
56
+ &.disabled {
57
+ @include typography.body-regular-disabled;
58
+ background: color_alias.$neutral-color-50;
59
+ }
60
+ }
61
+
62
+ // Media queries
63
+ // Mobile case
64
+ @media only screen and (min-width: breakpoints.$small) and (max-width: breakpoints.$medium) {
65
+ width: 100%;
66
+ }
67
+ // Tablet & Desktop cases
68
+ @media only screen and (min-width: breakpoints.$medium) {
69
+ width: 18.625rem;
70
+ }
71
+ }
@@ -0,0 +1,28 @@
1
+ import './Card.scss'
2
+ import React from 'react'
3
+ import { classNames } from '../utils/classNames'
4
+
5
+ export type Variant = 'primary'
6
+
7
+ export interface CardProps extends React.ComponentPropsWithoutRef<'div'> {
8
+ variant?: Variant
9
+ isDisabled?: boolean
10
+ }
11
+
12
+ export function Card({
13
+ className,
14
+ variant = 'primary',
15
+ isDisabled = false,
16
+ children,
17
+ ...props
18
+ }: CardProps): React.JSX.Element {
19
+ const cssClasses = classNames('card', className, variant, {
20
+ disabled: isDisabled,
21
+ })
22
+
23
+ return (
24
+ <div className={cssClasses} {...props}>
25
+ {children}
26
+ </div>
27
+ )
28
+ }
@@ -0,0 +1,20 @@
1
+ import './Card.scss'
2
+ import React from 'react'
3
+ import { classNames } from '../utils/classNames'
4
+
5
+ export interface CardContentProps
6
+ extends React.ComponentPropsWithoutRef<'div'> {}
7
+
8
+ export function CardContent({
9
+ className,
10
+ children,
11
+ ...props
12
+ }: CardContentProps): React.JSX.Element {
13
+ const cssClasses = classNames('content', className)
14
+
15
+ return (
16
+ <div className={cssClasses} {...props}>
17
+ {children}
18
+ </div>
19
+ )
20
+ }
@@ -0,0 +1,20 @@
1
+ import './Card.scss'
2
+ import React from 'react'
3
+ import { classNames } from '../utils/classNames'
4
+
5
+ export interface CardFooterProps
6
+ extends React.ComponentPropsWithoutRef<'div'> {}
7
+
8
+ export function CardFooter({
9
+ className,
10
+ children,
11
+ ...props
12
+ }: CardFooterProps): React.JSX.Element {
13
+ const cssClasses = classNames('footer', className)
14
+
15
+ return (
16
+ <div className={cssClasses} {...props}>
17
+ {children}
18
+ </div>
19
+ )
20
+ }
@@ -0,0 +1,25 @@
1
+ import './Card.scss'
2
+ import React from 'react'
3
+ import { classNames } from '../utils/classNames'
4
+
5
+ export interface CardHeaderProps extends React.ComponentPropsWithoutRef<'div'> {
6
+ title: string
7
+ isBold: boolean
8
+ }
9
+
10
+ export function CardHeader({
11
+ className,
12
+ title,
13
+ isBold = false,
14
+ children,
15
+ ...props
16
+ }: CardHeaderProps): React.JSX.Element {
17
+ const cssClasses = classNames('header', className, { bold: isBold })
18
+
19
+ return (
20
+ <div className={cssClasses} {...props}>
21
+ <span className={classNames({ bold: isBold })}>{title}</span>
22
+ <div className="actions">{children}</div>
23
+ </div>
24
+ )
25
+ }
@@ -0,0 +1,84 @@
1
+ @use '../../settings/color_alias';
2
+ @use '../../settings/typography/content' as typography;
3
+ @use '../../settings/config';
4
+ @use '../../settings/depth';
5
+
6
+ .card-menu-option {
7
+ display: flex;
8
+ flex-direction: row;
9
+ align-items: flex-start;
10
+ justify-content: space-between;
11
+ width: 100%;
12
+ padding: config.$space-3x;
13
+ gap: config.$space-3x;
14
+ border-radius: config.$corner-radius-xxs;
15
+ border-bottom: 1px solid color_alias.$neutral-color-200;
16
+ cursor: default;
17
+
18
+ @include typography.body-regular-primary;
19
+
20
+ .icon {
21
+ width: config.$icon-size-4x;
22
+ height: config.$icon-size-4x;
23
+ > svg {
24
+ width: 100%;
25
+ height: 100%;
26
+ }
27
+ }
28
+
29
+ .left {
30
+ display: flex;
31
+ flex-direction: column;
32
+ gap: config.$space-2x;
33
+
34
+ .title-container {
35
+ display: flex;
36
+ width: 100%;
37
+ gap: config.$space-2x;
38
+ justify-content: flex-start;
39
+ align-items: center;
40
+ flex: 1;
41
+ }
42
+
43
+ .content {
44
+ margin: 0;
45
+ text-align: left;
46
+ }
47
+ }
48
+
49
+ .right {
50
+ margin-top: auto;
51
+ margin-bottom: auto;
52
+ }
53
+
54
+ &.primary {
55
+ background: color_alias.$neutral-white;
56
+
57
+ .icon {
58
+ > svg {
59
+ fill: color_alias.$primary-color-600;
60
+ path {
61
+ fill: color_alias.$primary-color-600;
62
+ }
63
+ }
64
+ }
65
+
66
+ &:not(.disabled):hover {
67
+ background: color_alias.$primary-color-50;
68
+ }
69
+
70
+ &.disabled {
71
+ background: color_alias.$neutral-color-50;
72
+ @include typography.body-regular-disabled;
73
+
74
+ .icon {
75
+ > svg {
76
+ fill: color_alias.$neutral-color-400;
77
+ path {
78
+ fill: color_alias.$neutral-color-400;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,12 @@
1
+ export interface CardMenuProps extends React.ComponentPropsWithoutRef<'div'> {}
2
+
3
+ export function CardMenu({
4
+ children,
5
+ ...props
6
+ }: CardMenuProps): React.JSX.Element {
7
+ return (
8
+ <div role="menu" {...props}>
9
+ {children}
10
+ </div>
11
+ )
12
+ }
@@ -0,0 +1,50 @@
1
+ import { Icon, IconType } from '../Icon'
2
+ import './CardMenu.scss'
3
+ import { classNames } from '../../utils/classNames'
4
+
5
+ export type Variant = 'primary'
6
+
7
+ export interface CardMenuOptionProps
8
+ extends React.ComponentPropsWithoutRef<'div'> {
9
+ id?: string
10
+ variant?: Variant
11
+ icon: IconType
12
+ title: string
13
+ description?: string
14
+ disabled?: boolean
15
+ }
16
+
17
+ export function CardMenuOption({
18
+ id,
19
+ variant = 'primary',
20
+ className,
21
+ icon,
22
+ title,
23
+ description,
24
+ disabled,
25
+ ...props
26
+ }: CardMenuOptionProps): React.JSX.Element {
27
+ const cssClasses = classNames('card-menu-option', variant, className, {
28
+ disabled: disabled,
29
+ })
30
+
31
+ return (
32
+ <div
33
+ role="menuitem"
34
+ className={cssClasses}
35
+ {...props}
36
+ aria-disabled={disabled}
37
+ >
38
+ <div className="left">
39
+ <div className="title-container">
40
+ <Icon name={icon} className={variant} />
41
+ <span className="title">{title}</span>
42
+ </div>
43
+ <p className="content">{description}</p>
44
+ </div>
45
+ <div className="right">
46
+ <Icon name="AngleRight" className={variant} />
47
+ </div>
48
+ </div>
49
+ )
50
+ }
@@ -0,0 +1,4 @@
1
+ import { CardMenu } from './CardMenu'
2
+ import { CardMenuOption } from './CardMenuOption'
3
+
4
+ export { CardMenu, CardMenuOption }
@@ -1,6 +1,7 @@
1
1
  @use '../settings/color_alias';
2
2
  @use '../settings/typography/cards_table' as typography;
3
3
  @use '../settings/config';
4
+ @use '../settings/breakpoints';
4
5
 
5
6
  .cards-table-list {
6
7
  display: flex;
@@ -133,12 +134,8 @@
133
134
  }
134
135
 
135
136
  // Media queries
136
- $small: 375px;
137
- $medium: 768px;
138
- $large: 1200px;
139
-
140
137
  // Mobile & tablet cases
141
- @media only screen and (min-width: $small) and (max-width: $large) {
138
+ @media only screen and (min-width: breakpoints.$small) and (max-width: breakpoints.$large) {
142
139
  thead {
143
140
  display: none;
144
141
  }
@@ -177,7 +174,7 @@
177
174
  }
178
175
  }
179
176
  // Desktop case
180
- @media only screen and (min-width: $large) {
177
+ @media only screen and (min-width: breakpoints.$large) {
181
178
  thead {
182
179
  display: flex;
183
180
  }
@@ -0,0 +1,3 @@
1
+ $small: 375px;
2
+ $medium: 768px;
3
+ $large: 1200px;
@@ -0,0 +1,431 @@
1
+ import { IconButton } from '../atoms/IconButton'
2
+ import { Card } from '../atoms/Card'
3
+ import { CardHeader } from '../atoms/CardHeader'
4
+ import { CardContent } from '../atoms/CardContent'
5
+ import { CardFooter } from '../atoms/CardFooter'
6
+ import { Button } from '../atoms/Button'
7
+
8
+ const figmaPrimaryDesign = {
9
+ design: {
10
+ type: 'figma',
11
+ url: 'https://www.figma.com/file/DN2ova21vWqCRvPspBXgI1/Design-System?type=design&node-id=2236-754&mode=dev',
12
+ },
13
+ }
14
+
15
+ const meta = {
16
+ title: 'Design System/Atoms/Card',
17
+ component: Card,
18
+ tags: ['autodocs'],
19
+ argTypes: {
20
+ variant: {
21
+ description: 'Component variant used',
22
+ },
23
+ isBold: {
24
+ description: 'Is component title shown with bold style?',
25
+ },
26
+ title: {
27
+ description: 'Title text',
28
+ },
29
+ isDisabled: {
30
+ description: 'Is component disabled?',
31
+ },
32
+ },
33
+ parameters: figmaPrimaryDesign,
34
+ }
35
+
36
+ export default meta
37
+
38
+ export const ProductCard = {
39
+ render: () => (
40
+ <div style={{ display: 'flex' }}>
41
+ <Card variant="primary">
42
+ <CardHeader
43
+ isBold
44
+ title="Metal Gear Solid 5: Ground Zeroes + The Phantom Pain"
45
+ />
46
+ <CardContent>
47
+ <div
48
+ style={{
49
+ display: 'flex',
50
+ flexDirection: 'column',
51
+ color: '#727272FF',
52
+ fontSize: '0.875rem',
53
+ fontWeight: '400',
54
+ }}
55
+ >
56
+ <span>PlayStation 4</span>
57
+ <div>
58
+ <span
59
+ style={{
60
+ color: '#444',
61
+ fontSize: '1rem',
62
+ fontWeight: '700',
63
+ }}
64
+ >
65
+ 6,99€&nbsp;
66
+ </span>
67
+ <span
68
+ style={{
69
+ color: '#444',
70
+ fontSize: '1rem',
71
+ fontWeight: '400',
72
+ }}
73
+ >
74
+ / unit
75
+ </span>
76
+ </div>
77
+ </div>
78
+ </CardContent>
79
+ <CardFooter>
80
+ <Button variant="primary-outlined" label="Buy" />
81
+ </CardFooter>
82
+ </Card>
83
+ </div>
84
+ ),
85
+ }
86
+
87
+ export const ProductCardsGroup = {
88
+ render: () => (
89
+ <div
90
+ style={{
91
+ display: 'flex',
92
+ flexWrap: 'wrap',
93
+ width: '100%',
94
+ gap: '1.5rem',
95
+ }}
96
+ >
97
+ <Card variant="primary">
98
+ <CardHeader
99
+ isBold
100
+ title="Metal Gear Solid 5: Ground Zeroes + The Phantom Pain"
101
+ />
102
+ <CardContent>
103
+ <div
104
+ style={{
105
+ display: 'flex',
106
+ flexDirection: 'column',
107
+ color: '#727272FF',
108
+ fontSize: '0.875rem',
109
+ fontWeight: '400',
110
+ }}
111
+ >
112
+ <span>PlayStation 4</span>
113
+ <div>
114
+ <span
115
+ style={{
116
+ color: '#444',
117
+ fontSize: '1rem',
118
+ fontWeight: '700',
119
+ }}
120
+ >
121
+ 6,99€&nbsp;
122
+ </span>
123
+ <span
124
+ style={{
125
+ color: '#444',
126
+ fontSize: '1rem',
127
+ fontWeight: '400',
128
+ }}
129
+ >
130
+ / unit
131
+ </span>
132
+ </div>
133
+ </div>
134
+ </CardContent>
135
+ <CardFooter>
136
+ <Button variant="primary-outlined" label="Buy" />
137
+ </CardFooter>
138
+ </Card>
139
+
140
+ <Card variant="primary">
141
+ <CardHeader isBold title="Tekken 8" />
142
+ <CardContent>
143
+ <div
144
+ style={{
145
+ display: 'flex',
146
+ flexDirection: 'column',
147
+ color: '#727272FF',
148
+ fontSize: '0.875rem',
149
+ fontWeight: '400',
150
+ }}
151
+ >
152
+ <span>PlayStation 5</span>
153
+ <div>
154
+ <span
155
+ style={{
156
+ color: '#444',
157
+ fontSize: '1rem',
158
+ fontWeight: '700',
159
+ }}
160
+ >
161
+ 79,99€&nbsp;
162
+ </span>
163
+ <span
164
+ style={{
165
+ color: '#444',
166
+ fontSize: '1rem',
167
+ fontWeight: '400',
168
+ }}
169
+ >
170
+ / unit
171
+ </span>
172
+ </div>
173
+ </div>
174
+ </CardContent>
175
+ <CardFooter>
176
+ <Button variant="primary-outlined" label="Buy" />
177
+ </CardFooter>
178
+ </Card>
179
+
180
+ <Card variant="primary">
181
+ <CardHeader isBold title="The Witcher 3" />
182
+ <CardContent>
183
+ <div
184
+ style={{
185
+ display: 'flex',
186
+ flexDirection: 'column',
187
+ color: '#727272FF',
188
+ fontSize: '0.875rem',
189
+ fontWeight: '400',
190
+ }}
191
+ >
192
+ <span>Nintendo Switch</span>
193
+ <div>
194
+ <span
195
+ style={{
196
+ color: '#444',
197
+ fontSize: '1rem',
198
+ fontWeight: '700',
199
+ }}
200
+ >
201
+ 19,99€&nbsp;
202
+ </span>
203
+ <span
204
+ style={{
205
+ color: '#444',
206
+ fontSize: '1rem',
207
+ fontWeight: '400',
208
+ }}
209
+ >
210
+ / unit
211
+ </span>
212
+ </div>
213
+ </div>
214
+ </CardContent>
215
+ <CardFooter>
216
+ <Button variant="primary-outlined" label="Buy" />
217
+ </CardFooter>
218
+ </Card>
219
+
220
+ <Card variant="primary">
221
+ <CardHeader isBold title="Super Mario RPG" />
222
+ <CardContent>
223
+ <div
224
+ style={{
225
+ display: 'flex',
226
+ flexDirection: 'column',
227
+ color: '#727272FF',
228
+ fontSize: '0.875rem',
229
+ fontWeight: '400',
230
+ }}
231
+ >
232
+ <span>Nintendo Switch</span>
233
+ <div>
234
+ <span
235
+ style={{
236
+ color: '#444',
237
+ fontSize: '1rem',
238
+ fontWeight: '700',
239
+ }}
240
+ >
241
+ 49,99€&nbsp;
242
+ </span>
243
+ <span
244
+ style={{
245
+ color: '#444',
246
+ fontSize: '1rem',
247
+ fontWeight: '400',
248
+ }}
249
+ >
250
+ / unit
251
+ </span>
252
+ </div>
253
+ </div>
254
+ </CardContent>
255
+ <CardFooter>
256
+ <Button variant="primary-outlined" label="Buy" />
257
+ </CardFooter>
258
+ </Card>
259
+
260
+ <Card variant="primary">
261
+ <CardHeader isBold title="Stray" />
262
+ <CardContent>
263
+ <div
264
+ style={{
265
+ display: 'flex',
266
+ flexDirection: 'column',
267
+ color: '#727272FF',
268
+ fontSize: '0.875rem',
269
+ fontWeight: '400',
270
+ }}
271
+ >
272
+ <span>PlayStation 4</span>
273
+ <div>
274
+ <span
275
+ style={{
276
+ color: '#444',
277
+ fontSize: '1rem',
278
+ fontWeight: '700',
279
+ }}
280
+ >
281
+ 15,99€&nbsp;
282
+ </span>
283
+ <span
284
+ style={{
285
+ color: '#444',
286
+ fontSize: '1rem',
287
+ fontWeight: '400',
288
+ }}
289
+ >
290
+ / unit
291
+ </span>
292
+ </div>
293
+ </div>
294
+ </CardContent>
295
+ <CardFooter>
296
+ <Button variant="primary-outlined" label="Buy" />
297
+ </CardFooter>
298
+ </Card>
299
+
300
+ <Card variant="primary">
301
+ <CardHeader isBold title="The Medium" />
302
+ <CardContent>
303
+ <div
304
+ style={{
305
+ display: 'flex',
306
+ flexDirection: 'column',
307
+ color: '#727272FF',
308
+ fontSize: '0.875rem',
309
+ fontWeight: '400',
310
+ }}
311
+ >
312
+ <span>PlayStation 5</span>
313
+ <div>
314
+ <span
315
+ style={{
316
+ color: '#444',
317
+ fontSize: '1rem',
318
+ fontWeight: '700',
319
+ }}
320
+ >
321
+ 45,99€&nbsp;
322
+ </span>
323
+ <span
324
+ style={{
325
+ color: '#444',
326
+ fontSize: '1rem',
327
+ fontWeight: '400',
328
+ }}
329
+ >
330
+ / unit
331
+ </span>
332
+ </div>
333
+ </div>
334
+ </CardContent>
335
+ <CardFooter>
336
+ <Button variant="primary-outlined" label="Buy" />
337
+ </CardFooter>
338
+ </Card>
339
+
340
+ <Card variant="primary">
341
+ <CardHeader isBold title="The Legend of Zelda: Tears of the Kingdom" />
342
+ <CardContent>
343
+ <div
344
+ style={{
345
+ display: 'flex',
346
+ flexDirection: 'column',
347
+ color: '#727272FF',
348
+ fontSize: '0.875rem',
349
+ fontWeight: '400',
350
+ }}
351
+ >
352
+ <span>Nintendo Switch</span>
353
+ <div>
354
+ <span
355
+ style={{
356
+ color: '#444',
357
+ fontSize: '1rem',
358
+ fontWeight: '700',
359
+ }}
360
+ >
361
+ 45,99€&nbsp;
362
+ </span>
363
+ <span
364
+ style={{
365
+ color: '#444',
366
+ fontSize: '1rem',
367
+ fontWeight: '400',
368
+ }}
369
+ >
370
+ / unit
371
+ </span>
372
+ </div>
373
+ </div>
374
+ </CardContent>
375
+ <CardFooter>
376
+ <Button variant="primary-outlined" label="Buy" />
377
+ </CardFooter>
378
+ </Card>
379
+ </div>
380
+ ),
381
+ }
382
+
383
+ export const Primary = {
384
+ render: () => (
385
+ <div style={{ display: 'flex' }}>
386
+ <Card variant="primary">
387
+ <CardHeader title="Tekken 8">
388
+ <IconButton
389
+ icon="Edit"
390
+ accessibilityLabel="Edit game"
391
+ href="link.com"
392
+ />
393
+ <IconButton
394
+ icon="Export"
395
+ accessibilityLabel="Export game"
396
+ href="link.com"
397
+ />
398
+ <IconButton
399
+ icon="Delete"
400
+ accessibilityLabel="Delete game"
401
+ href="link.com"
402
+ />
403
+ </CardHeader>
404
+ <CardContent>
405
+ <p>TEKKEN 8 will feature exciting new gameplay focused on “Aggressive” tactics. Retaining TEKKEN's unique fighting game identity, the game will provide both players and spectators with the series' most thrilling experience yet with visceral screen-jarring attacks and environments that are both dynamic and destructible.</p>
406
+ </CardContent>
407
+ <CardFooter>
408
+ <Button variant="primary-outlined" label="Add to wishlist" />
409
+ </CardFooter>
410
+ </Card>
411
+ </div>
412
+ ),
413
+ }
414
+
415
+ export const Disabled = {
416
+ render: () => (
417
+ <div style={{ display: 'flex' }}>
418
+ <Card isDisabled={true} variant="primary">
419
+ <CardHeader title="Tekken 8">
420
+ <IconButton disabled icon="Delete" accessibilityLabel="Delete game" />
421
+ </CardHeader>
422
+ <CardContent>
423
+ <p>TEKKEN 8 will feature exciting new gameplay focused on “Aggressive” tactics. Retaining TEKKEN's unique fighting game identity, the game will provide both players and spectators with the series' most thrilling experience yet with visceral screen-jarring attacks and environments that are both dynamic and destructible.</p>
424
+ </CardContent>
425
+ <CardFooter>
426
+ <Button variant="primary-outlined" disabled label="Add to wishlist" />
427
+ </CardFooter>
428
+ </Card>
429
+ </div>
430
+ ),
431
+ }
@@ -0,0 +1,103 @@
1
+ import React from 'react'
2
+
3
+ import { CardMenu, CardMenuOption } from '../atoms/CardMenu'
4
+
5
+ const figmaPrimaryDesign = {
6
+ design: {
7
+ type: 'figma',
8
+ url: 'https://www.figma.com/design/DN2ova21vWqCRvPspBXgI1/Design-System?node-id=2285-1811&m=dev',
9
+ },
10
+ }
11
+
12
+ const meta = {
13
+ title: 'Design System/Atoms/CardMenu',
14
+ component: CardMenuOption,
15
+ tags: ['autodocs'],
16
+ argTypes: {
17
+ id: {
18
+ description: 'Id for aria purposes',
19
+ },
20
+ icon: {
21
+ description: 'Component icon used',
22
+ },
23
+ variant: {
24
+ description: 'Component variant used',
25
+ },
26
+ title: {
27
+ description: 'Component title text',
28
+ },
29
+ description: {
30
+ description: 'Component description text',
31
+ },
32
+ isDisabled: {
33
+ description: 'Is the component disabled?',
34
+ },
35
+ onClick: {
36
+ description: 'Event triggered when the component is clicked',
37
+ },
38
+ },
39
+ parameters: figmaPrimaryDesign,
40
+ }
41
+
42
+ export default meta
43
+
44
+ export const Option = {
45
+ render: () => (
46
+ <CardMenuOption
47
+ id="first-menu-option"
48
+ icon="Info"
49
+ variant="primary"
50
+ title="It's dangerous to go alone!"
51
+ description="Take this 🗡️ and this 🛡️ and this 💣 and this 🏹 and this 🔪 and this 🐴 and this 🔫 and this 🔪"
52
+ isDisabled={false}
53
+ onClick={() => alert('click')}
54
+ />
55
+ ),
56
+ }
57
+
58
+ export const DisabledOption = {
59
+ render: () => (
60
+ <CardMenuOption
61
+ id="first-menu-option"
62
+ icon="Info"
63
+ variant="primary"
64
+ title="It's dangerous to go alone!"
65
+ description="Take this 🗡️"
66
+ disabled
67
+ />
68
+ ),
69
+ }
70
+
71
+ export const Menu = {
72
+ render: () => (
73
+ <CardMenu>
74
+ <CardMenuOption
75
+ id="first-menu-option"
76
+ icon="AddCircle"
77
+ variant="primary"
78
+ title="Title"
79
+ description="Name of the videogame"
80
+ isDisabled={false}
81
+ onClick={() => alert('click title')}
82
+ />
83
+ <CardMenuOption
84
+ id="second-menu-option"
85
+ icon="Edit"
86
+ variant="primary"
87
+ title="Address"
88
+ description="Videogame company address"
89
+ isDisabled={false}
90
+ onClick={() => alert('click address')}
91
+ />
92
+ <CardMenuOption
93
+ id="third-menu-option"
94
+ icon="Info"
95
+ variant="primary"
96
+ title="Email"
97
+ description="Videogame company email"
98
+ isDisabled={false}
99
+ onClick={() => alert('click email')}
100
+ />
101
+ </CardMenu>
102
+ ),
103
+ }
@@ -3,6 +3,13 @@ import { Meta } from "@storybook/addon-docs";
3
3
  <Meta title="Changelog" />
4
4
  # Changelog
5
5
 
6
+
7
+ ## 0.13.0
8
+ - Added CardMenuOption component to Storybook.
9
+
10
+ ## 0.12.0
11
+ - Card component is added to Storybook.
12
+
6
13
  ## 0.11.1
7
14
  - Input and Checkbox components `id` prop now it's optional.
8
15
  - Fixed TextArea export component.
@@ -0,0 +1,67 @@
1
+ import React from 'react'
2
+ import { render } from '@testing-library/react'
3
+ import { Card } from '@/atoms/Card'
4
+ import { CardHeader } from '@/atoms/CardHeader'
5
+ import { CardContent } from '@/atoms/CardContent'
6
+ import { CardFooter } from '@/atoms/CardFooter'
7
+ import { Button } from '@/atoms/Button'
8
+
9
+ describe('Product card', () => {
10
+ it('renders the expected structure and data', () => {
11
+ const { getByText, container } = render(
12
+ <Card>
13
+ <CardHeader
14
+ isBold
15
+ title="Metal Gear Solid 5: Ground Zeroes + The Phantom Pain"
16
+ />
17
+ <CardContent>
18
+ <div
19
+ style={{
20
+ display: 'flex',
21
+ flexDirection: 'column',
22
+ color: '#9B9B9B',
23
+ fontSize: '0.875rem',
24
+ fontWeight: '400',
25
+ }}
26
+ >
27
+ <span>PlayStation 4</span>
28
+ <div>
29
+ <span
30
+ style={{
31
+ color: '#444',
32
+ fontSize: '1rem',
33
+ fontWeight: '700',
34
+ }}
35
+ >
36
+ 6,99€&nbsp;
37
+ </span>
38
+ <span
39
+ style={{
40
+ color: '#444',
41
+ fontSize: '1rem',
42
+ fontWeight: '400',
43
+ }}
44
+ >
45
+ / unit
46
+ </span>
47
+ </div>
48
+ </div>
49
+ </CardContent>
50
+ <CardFooter>
51
+ <Button variant="primary-outlined" label="Buy" />
52
+ </CardFooter>
53
+ </Card>,
54
+ )
55
+
56
+ expect(container.getElementsByClassName('card').length).toBe(1)
57
+ expect(container.getElementsByClassName('primary').length).toBe(1)
58
+ expect(container.getElementsByClassName('header').length).toBe(1)
59
+ expect(container.getElementsByClassName('content').length).toBe(1)
60
+ expect(container.getElementsByClassName('footer').length).toBe(1)
61
+
62
+ expect(getByText(/Metal Gear Solid 5/i)).toBeInTheDocument()
63
+ expect(getByText(/PlayStation/i)).toBeInTheDocument()
64
+ expect(getByText(/6,99€/i)).toBeInTheDocument()
65
+ expect(getByText(/Buy/i)).toBeInTheDocument()
66
+ })
67
+ })
@@ -0,0 +1,21 @@
1
+ import React from 'react'
2
+ import { screen, render } from '@testing-library/react'
3
+ import { CardMenuOption } from '@/atoms/CardMenu/CardMenuOption'
4
+
5
+ describe('CardMenuOption', () => {
6
+ it('renders', () => {
7
+ const { getByRole, getByText, getAllByRole } = render(
8
+ <CardMenuOption
9
+ id="option-one"
10
+ icon="Info"
11
+ title="It's dangerous to go alone!"
12
+ description="Take this sword!"
13
+ />,
14
+ )
15
+
16
+ expect(getByRole('menuitem')).toHaveClass(`card-menu-option primary`)
17
+ expect(getByText(/dangerous to go alone/i)).toBeInTheDocument()
18
+ expect(getByText(/this sword/i)).toBeInTheDocument()
19
+ expect(getAllByRole('img')[0].title).toBe('Info')
20
+ })
21
+ })
package/tsconfig.json CHANGED
@@ -22,6 +22,6 @@
22
22
  "@/*": ["./src/*"]
23
23
  }
24
24
  },
25
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/stories/CardsTable.stories.js", "src/stories/Modal.stories.js", "src/stories/Typography.stories.mdx"],
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "src/stories/CardsTable.stories.js", "src/stories/Modal.stories.js", "src/stories/Typography.stories.mdx", "src/stories/Card.stories.js"],
26
26
  "exclude": ["node_modules"]
27
27
  }