@popsure/dirty-swan 0.34.0 → 0.36.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 (129) hide show
  1. package/dist/cjs/index.d.ts +1 -1
  2. package/dist/cjs/index.js +159 -114
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/lib/components/badge/index.d.ts +10 -0
  5. package/dist/cjs/lib/components/badge/index.stories.d.ts +34 -0
  6. package/dist/cjs/lib/components/badge/index.test.d.ts +1 -0
  7. package/dist/cjs/lib/components/cards/cardWithLeftIcon/index.d.ts +6 -3
  8. package/dist/cjs/lib/components/cards/cardWithLeftIcon/index.stories.d.ts +13 -2
  9. package/dist/cjs/lib/components/chip/index.d.ts +2 -1
  10. package/dist/cjs/lib/components/informationBox/index.d.ts +12 -0
  11. package/dist/cjs/lib/components/informationBox/index.stories.d.ts +35 -0
  12. package/dist/cjs/lib/components/informationBox/index.test.d.ts +1 -0
  13. package/dist/cjs/lib/components/input/autoSuggestInput/index.d.ts +7 -7
  14. package/dist/cjs/lib/components/input/autoSuggestInput/index.stories.d.ts +84 -0
  15. package/dist/cjs/lib/components/input/autoSuggestMultiSelect/index.d.ts +7 -7
  16. package/dist/cjs/lib/components/input/autoSuggestMultiSelect/index.stories.d.ts +77 -0
  17. package/dist/cjs/lib/components/link/index.d.ts +2 -0
  18. package/dist/cjs/lib/components/link/index.stories.d.ts +26 -0
  19. package/dist/cjs/lib/index.d.ts +6 -3
  20. package/dist/esm/components/autocompleteAddress/index.test.js +1 -1
  21. package/dist/esm/components/badge/index.js +27 -0
  22. package/dist/esm/components/badge/index.js.map +1 -0
  23. package/dist/esm/components/badge/index.stories.js +39 -0
  24. package/dist/esm/components/badge/index.stories.js.map +1 -0
  25. package/dist/esm/components/badge/index.test.js +21 -0
  26. package/dist/esm/components/badge/index.test.js.map +1 -0
  27. package/dist/esm/components/cards/cardButton/index.js +2 -1
  28. package/dist/esm/components/cards/cardButton/index.js.map +1 -1
  29. package/dist/esm/components/cards/cardButton/index.stories.js +2 -1
  30. package/dist/esm/components/cards/cardButton/index.stories.js.map +1 -1
  31. package/dist/esm/components/cards/cardWithLeftIcon/index.js +2 -1
  32. package/dist/esm/components/cards/cardWithLeftIcon/index.js.map +1 -1
  33. package/dist/esm/components/cards/cardWithLeftIcon/index.stories.js +15 -3
  34. package/dist/esm/components/cards/cardWithLeftIcon/index.stories.js.map +1 -1
  35. package/dist/esm/components/cards/cardWithTopIcon/index.js +2 -1
  36. package/dist/esm/components/cards/cardWithTopIcon/index.js.map +1 -1
  37. package/dist/esm/components/cards/cardWithTopIcon/index.stories.js +2 -1
  38. package/dist/esm/components/cards/cardWithTopIcon/index.stories.js.map +1 -1
  39. package/dist/esm/components/cards/cardWithTopLeftIcon/index.js +2 -1
  40. package/dist/esm/components/cards/cardWithTopLeftIcon/index.js.map +1 -1
  41. package/dist/esm/components/cards/cardWithTopLeftIcon/index.stories.js +2 -1
  42. package/dist/esm/components/cards/cardWithTopLeftIcon/index.stories.js.map +1 -1
  43. package/dist/esm/components/cards/index.js +7 -5
  44. package/dist/esm/components/cards/index.js.map +1 -1
  45. package/dist/esm/components/cards/infoCard/index.js +2 -1
  46. package/dist/esm/components/cards/infoCard/index.js.map +1 -1
  47. package/dist/esm/components/cards/infoCard/index.stories.js +2 -1
  48. package/dist/esm/components/cards/infoCard/index.stories.js.map +1 -1
  49. package/dist/esm/components/chip/index.js +2 -2
  50. package/dist/esm/components/chip/index.js.map +1 -1
  51. package/dist/esm/components/comparisonTable/components/TableButton/index.test.js +2 -2
  52. package/dist/esm/components/comparisonTable/components/TableRowHeader/index.test.js +2 -2
  53. package/dist/esm/components/dateSelector/index.test.js +1 -1
  54. package/dist/esm/components/informationBox/index.js +19 -0
  55. package/dist/esm/components/informationBox/index.js.map +1 -0
  56. package/dist/esm/components/informationBox/index.stories.js +42 -0
  57. package/dist/esm/components/informationBox/index.stories.js.map +1 -0
  58. package/dist/esm/components/informationBox/index.test.js +49 -0
  59. package/dist/esm/components/informationBox/index.test.js.map +1 -0
  60. package/dist/esm/components/input/autoSuggestInput/index.js +3 -3
  61. package/dist/esm/components/input/autoSuggestInput/index.js.map +1 -1
  62. package/dist/esm/components/input/autoSuggestInput/index.stories.js +131 -0
  63. package/dist/esm/components/input/autoSuggestInput/index.stories.js.map +1 -0
  64. package/dist/esm/components/input/autoSuggestMultiSelect/index.js +17 -13
  65. package/dist/esm/components/input/autoSuggestMultiSelect/index.js.map +1 -1
  66. package/dist/esm/components/input/autoSuggestMultiSelect/index.stories.js +107 -0
  67. package/dist/esm/components/input/autoSuggestMultiSelect/index.stories.js.map +1 -0
  68. package/dist/esm/components/input/checkbox/index.test.js +1 -1
  69. package/dist/esm/components/input/currency/index.test.js +1 -1
  70. package/dist/esm/components/link/index.js +11 -0
  71. package/dist/esm/components/link/index.js.map +1 -0
  72. package/dist/esm/components/link/index.stories.js +33 -0
  73. package/dist/esm/components/link/index.stories.js.map +1 -0
  74. package/dist/esm/components/multiDropzone/index.test.js +2 -2
  75. package/dist/esm/components/segmentedControl/index.test.js +1 -1
  76. package/dist/esm/{customRender-4157fcff.js → customRender-20b5f7ec.js} +3 -3
  77. package/dist/esm/{customRender-4157fcff.js.map → customRender-20b5f7ec.js.map} +1 -1
  78. package/dist/esm/{extend-expect-46bdce4a.js → extend-expect-25e5049d.js} +2 -2
  79. package/dist/esm/{extend-expect-46bdce4a.js.map → extend-expect-25e5049d.js.map} +1 -1
  80. package/dist/esm/feather-logo-a3f07990.js +4 -0
  81. package/dist/esm/feather-logo-a3f07990.js.map +1 -0
  82. package/dist/esm/{index-47663d39.js → index-29ac387a.js} +3 -4
  83. package/dist/esm/index-29ac387a.js.map +1 -0
  84. package/dist/esm/index.d.ts +1 -1
  85. package/dist/esm/index.js +7 -3
  86. package/dist/esm/index.js.map +1 -1
  87. package/dist/esm/lib/components/badge/index.d.ts +10 -0
  88. package/dist/esm/lib/components/badge/index.stories.d.ts +34 -0
  89. package/dist/esm/lib/components/badge/index.test.d.ts +1 -0
  90. package/dist/esm/lib/components/cards/cardWithLeftIcon/index.d.ts +6 -3
  91. package/dist/esm/lib/components/cards/cardWithLeftIcon/index.stories.d.ts +13 -2
  92. package/dist/esm/lib/components/chip/index.d.ts +2 -1
  93. package/dist/esm/lib/components/informationBox/index.d.ts +12 -0
  94. package/dist/esm/lib/components/informationBox/index.stories.d.ts +35 -0
  95. package/dist/esm/lib/components/informationBox/index.test.d.ts +1 -0
  96. package/dist/esm/lib/components/input/autoSuggestInput/index.d.ts +7 -7
  97. package/dist/esm/lib/components/input/autoSuggestInput/index.stories.d.ts +84 -0
  98. package/dist/esm/lib/components/input/autoSuggestMultiSelect/index.d.ts +7 -7
  99. package/dist/esm/lib/components/input/autoSuggestMultiSelect/index.stories.d.ts +77 -0
  100. package/dist/esm/lib/components/link/index.d.ts +2 -0
  101. package/dist/esm/lib/components/link/index.stories.d.ts +26 -0
  102. package/dist/esm/lib/index.d.ts +6 -3
  103. package/dist/esm/util/testUtils/customRender.js +1 -1
  104. package/package.json +1 -1
  105. package/src/index.tsx +3 -0
  106. package/src/lib/components/badge/index.stories.tsx +45 -0
  107. package/src/lib/components/badge/index.test.tsx +11 -0
  108. package/src/lib/components/badge/index.tsx +54 -0
  109. package/src/lib/components/badge/style.module.scss +13 -0
  110. package/src/lib/components/cards/cardWithLeftIcon/index.stories.tsx +15 -0
  111. package/src/lib/components/cards/cardWithLeftIcon/index.tsx +19 -5
  112. package/src/lib/components/chip/index.tsx +3 -1
  113. package/src/lib/components/informationBox/index.stories.tsx +51 -0
  114. package/src/lib/components/informationBox/index.test.tsx +55 -0
  115. package/src/lib/components/informationBox/index.tsx +65 -0
  116. package/src/lib/components/informationBox/info.svg +11 -0
  117. package/src/lib/components/informationBox/style.module.scss +62 -0
  118. package/src/lib/components/input/autoSuggestInput/index.stories.tsx +162 -0
  119. package/src/lib/components/input/autoSuggestInput/index.tsx +15 -13
  120. package/src/lib/components/input/autoSuggestMultiSelect/index.stories.tsx +125 -0
  121. package/src/lib/components/input/autoSuggestMultiSelect/index.tsx +42 -29
  122. package/src/lib/components/input/autoSuggestMultiSelect/style.module.scss +6 -0
  123. package/src/lib/components/link/index.stories.tsx +29 -0
  124. package/src/lib/components/link/index.tsx +9 -0
  125. package/src/lib/index.tsx +8 -2
  126. package/dist/esm/index-47663d39.js.map +0 -1
  127. package/src/lib/components/input/autoSuggestInput/index.stories.mdx +0 -138
  128. package/src/lib/components/input/autoSuggestMultiSelect/index.stories.mdx +0 -115
  129. package/src/lib/scss/private/components/badge.stories.mdx +0 -43
@@ -0,0 +1,54 @@
1
+ import { ReactNode } from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './style.module.scss';
4
+
5
+ type Variant =
6
+ | 'warning'
7
+ | 'error'
8
+ | 'success'
9
+ | 'information'
10
+ | 'neutral'
11
+ | 'neutral200'
12
+ | 'neutral300'
13
+ | 'primary'
14
+ | 'primary900';
15
+
16
+ export interface BadgeProps {
17
+ className?: string;
18
+ variant?: Variant;
19
+ size?: 'small' | 'medium' | 'large';
20
+ children: ReactNode;
21
+ }
22
+
23
+ const getVariantClassNames = (variant: Variant) => ({
24
+ information: 'bg-blue-100',
25
+ neutral: 'bg-white',
26
+ neutral200: 'bg-grey-200',
27
+ neutral300: 'bg-grey-300',
28
+ warning: 'bg-yellow-100',
29
+ error: 'bg-red-100',
30
+ success: 'bg-green-100',
31
+ primary: 'bg-purple-100',
32
+ primary900: 'bg-purple-900 tc-white',
33
+ }[variant])
34
+
35
+ const Badge = ({
36
+ className = '',
37
+ size = 'medium',
38
+ variant = 'information',
39
+ children,
40
+ }: BadgeProps) => (
41
+ <div
42
+ className={classNames(
43
+ className,
44
+ 'px16 br8 d-inline-block ai-center fw-bold p-p',
45
+ { 'p-p--small': size === 'small' },
46
+ styles[`badge--${size}`],
47
+ getVariantClassNames(variant)
48
+ )}
49
+ >
50
+ {children}
51
+ </div>
52
+ );
53
+
54
+ export { Badge };
@@ -0,0 +1,13 @@
1
+
2
+ .badge {
3
+ &--small,
4
+ &--medium {
5
+ padding-bottom: 6px;
6
+ padding-top: 6px;
7
+ }
8
+
9
+ &--large {
10
+ padding-bottom: 8px;
11
+ padding-top: 8px;
12
+ }
13
+ }
@@ -9,6 +9,10 @@ const story = {
9
9
  defaultValue: 'Lorem Ipsum',
10
10
  description: 'Title text that needs to be displayed',
11
11
  },
12
+ subtitle: {
13
+ defaultValue: 'Lorem Ipsum dolorem',
14
+ description: 'Subitle text that needs to be displayed',
15
+ },
12
16
  children: {
13
17
  type: 'text',
14
18
  defaultValue: 'Mountain or rock climbing, Bouldering, Martial arts, Extreme sports, Scuba diving, Sky diving, Bungee jumping, Mountain or rock climbing, Bouldering, Martial arts,',
@@ -25,6 +29,13 @@ const story = {
25
29
  },
26
30
  description: 'Icon displayed on the left of the card.',
27
31
  },
32
+ leftIconSize: {
33
+ defaultValue: {
34
+ width: 48,
35
+ height: 48
36
+ },
37
+ description: 'Size of the left icon',
38
+ },
28
39
  rightIcon: {
29
40
  defaultValue: {
30
41
  src: images.washingMachine,
@@ -51,11 +62,13 @@ const story = {
51
62
 
52
63
  export const CardWithLeftIconStory = ({
53
64
  title,
65
+ subtitle,
54
66
  dropshadow,
55
67
  children,
56
68
  className,
57
69
  cardSize,
58
70
  leftIcon,
71
+ leftIconSize,
59
72
  rightIcon,
60
73
  state,
61
74
  }: CardWithLeftIconProps) => {
@@ -66,8 +79,10 @@ export const CardWithLeftIconStory = ({
66
79
  dropshadow={dropshadow}
67
80
  state={state}
68
81
  leftIcon={leftIcon}
82
+ leftIconSize={leftIconSize}
69
83
  rightIcon={rightIcon}
70
84
  title={title}
85
+ subtitle={subtitle}
71
86
  >
72
87
  {children}
73
88
  </CardWithLeftIcon>
@@ -1,5 +1,5 @@
1
1
  import { associatedClassForCardState, CardProps, headingForCardSize } from '..';
2
- import { Icon, arrowRight } from '../icons';
2
+ import { Icon, IconSize, arrowRight } from '../icons';
3
3
 
4
4
  import styles from './style.module.scss';
5
5
 
@@ -30,21 +30,26 @@ const cardTextStyleFromCardSize = (
30
30
  }
31
31
  };
32
32
 
33
- export type CardWithLeftIconProps = CardProps & {
33
+ export type CardWithLeftIconProps = Omit<CardProps, 'title'> & {
34
34
  cardSize?: 'xsmall' | 'small' | 'medium' | 'big';
35
35
  leftIcon?: Icon;
36
36
  rightIcon?: 'arrow' | Icon;
37
+ leftIconSize?: IconSize;
38
+ title?: string;
39
+ subtitle?: string;
37
40
  }
38
41
 
39
42
  export const CardWithLeftIcon = ({
40
43
  className = '',
41
44
  title,
45
+ subtitle,
42
46
  cardSize = 'medium',
43
47
  children,
44
48
  leftIcon,
45
49
  rightIcon,
46
50
  state = 'actionable',
47
51
  dropshadow = true,
52
+ leftIconSize,
48
53
  ...props
49
54
  }: CardWithLeftIconProps) => {
50
55
  const cardStyle = `d-flex ai-center ${className} ${associatedClassForCardState(
@@ -62,8 +67,8 @@ export const CardWithLeftIcon = ({
62
67
  <div className={cardStyle} {...props}>
63
68
  {leftIcon && (
64
69
  <img
65
- width="48px"
66
- height="48px"
70
+ width={`${leftIconSize?.width || 48}px`}
71
+ height={`${leftIconSize?.height || 48}px`}
67
72
  className={iconStyle}
68
73
  src={leftIcon.src}
69
74
  alt={leftIcon.alt}
@@ -71,7 +76,16 @@ export const CardWithLeftIcon = ({
71
76
  )}
72
77
  <div>
73
78
  <div className="d-flex">
74
- <div className={headingStyle}>{title}</div>
79
+ {(title || subtitle) && (
80
+ <div>
81
+ {title && (
82
+ <div className={headingStyle}>{title}</div>
83
+ )}
84
+ {subtitle && (
85
+ <div className={`tc-grey-500 ${headingStyle}`}>{subtitle}</div>
86
+ )}
87
+ </div>
88
+ )}
75
89
  {rightIcon && (
76
90
  <img
77
91
  className="ml-auto"
@@ -4,13 +4,15 @@ import removeButtonHighlightedIcon from './icons/remove-button-highlighted.svg';
4
4
  import { Option } from '../../models/autoSuggestInput';
5
5
 
6
6
  export default ({
7
+ className,
7
8
  value,
8
9
  onRemove,
9
10
  }: {
10
11
  value: Option;
11
12
  onRemove: (value: Option) => void;
13
+ className?: string;
12
14
  }) => (
13
- <div className={`p-p mr8 mb8 d-flex ${styles['chip']}`}>
15
+ <div className={`p-p mr8 mb8 d-flex ${className} ${styles['chip']}`}>
14
16
  {value.leftIcon && (
15
17
  <img
16
18
  className={`mr8 ${styles['chip-image']}`}
@@ -0,0 +1,51 @@
1
+ import { InformationBox, InformationBoxProps } from '.';
2
+
3
+ const story = {
4
+ title: 'JSX/InformationBox',
5
+ component: InformationBox,
6
+ argTypes: {
7
+ children: {
8
+ control: { type: 'text' },
9
+ defaultValue: 'It seems that you already have an account with us! Sign in now',
10
+ description: 'Content that is displayed inside the information box',
11
+ },
12
+ title: {
13
+ defaultValue: 'Log in to your account',
14
+ description: 'Title of the information box',
15
+ },
16
+ showIcon: {
17
+ defaultValue: false,
18
+ description: 'Whether or not to show the info icon',
19
+ },
20
+ size: {
21
+ defaultValue: 'default',
22
+ description: 'Size to display the component',
23
+ },
24
+ variant: {
25
+ defaultValue: 'information',
26
+ description: 'Variant that defines the style of the InformationBox',
27
+ },
28
+ }
29
+ };
30
+
31
+ export const InformationBoxStory = ({
32
+ children,
33
+ showIcon,
34
+ title,
35
+ size,
36
+ variant,
37
+ }: InformationBoxProps) => (
38
+ <div className='wmx6'>
39
+ <InformationBox
40
+ children={children}
41
+ showIcon={showIcon}
42
+ title={title}
43
+ size={size}
44
+ variant={variant}
45
+ />
46
+ </div>
47
+ );
48
+
49
+ InformationBoxStory.storyName = "InformationBox";
50
+
51
+ export default story;
@@ -0,0 +1,55 @@
1
+ import { render, screen } from '../../util/testUtils';
2
+
3
+ import { InformationBox } from '.';
4
+
5
+ describe('InformationBox component', () => {
6
+ it('Should render title', async () => {
7
+ render(
8
+ <InformationBox title={'Title'}>
9
+ Content
10
+ </InformationBox>
11
+ )
12
+
13
+ expect(screen.getByText('Title')).toBeInTheDocument();
14
+ });
15
+
16
+ it('Should not render title when title prop is not passed', async () => {
17
+ render(
18
+ <InformationBox>
19
+ Content
20
+ </InformationBox>
21
+ )
22
+
23
+ expect(screen.queryByTestId('information-box-title')).not.toBeInTheDocument();
24
+ });
25
+
26
+ it('Should render content', async () => {
27
+ render(
28
+ <InformationBox>
29
+ Content
30
+ </InformationBox>
31
+ )
32
+
33
+ expect(screen.getByText('Content')).toBeInTheDocument();
34
+ });
35
+
36
+ it('Should show icon when showIcon is true', async () => {
37
+ render(
38
+ <InformationBox showIcon>
39
+ Content
40
+ </InformationBox>
41
+ )
42
+
43
+ expect(screen.getByTestId('information-box-icon')).toBeInTheDocument();
44
+ });
45
+
46
+ it('Should not show icon when showIcon is false', async () => {
47
+ render(
48
+ <InformationBox showIcon={false}>
49
+ Content
50
+ </InformationBox>
51
+ )
52
+
53
+ expect(screen.queryByTestId('information-box-icon')).not.toBeInTheDocument();
54
+ });
55
+ });
@@ -0,0 +1,65 @@
1
+ import { ReactNode } from 'react';
2
+ import classNames from 'classnames';
3
+ import styles from './style.module.scss';
4
+
5
+ type Variant = 'warning' | 'error' | 'success' | 'information' | 'neutral';
6
+
7
+ export interface InformationBoxProps {
8
+ className?: string;
9
+ variant?: Variant;
10
+ title?: string;
11
+ children: ReactNode;
12
+ showIcon?: boolean;
13
+ size?: 'default' | 'small';
14
+ }
15
+
16
+ const InformationBox = ({
17
+ className = '',
18
+ variant = 'information',
19
+ title,
20
+ children,
21
+ showIcon,
22
+ size = 'default'
23
+ }: InformationBoxProps) => (
24
+ <div
25
+ className={classNames(
26
+ className,
27
+ 'p16 br8 color-black',
28
+ styles.informationBox,
29
+ styles[`informationBox--${variant}`]
30
+ )}
31
+ role="alert"
32
+ >
33
+ <div className='d-flex'>
34
+ {showIcon &&
35
+ <span
36
+ data-testid="information-box-icon"
37
+ className={classNames(
38
+ styles.icon,
39
+ styles[`icon--${variant}`],
40
+ 'mr8'
41
+ )}
42
+ />
43
+ }
44
+ <div>
45
+ {title && (
46
+ <h4
47
+ data-testid="information-box-title"
48
+ className={classNames(
49
+ size === 'default'? 'p-h4' : 'p-h5',
50
+ 'mb8'
51
+ )}
52
+ >
53
+ {title}
54
+ </h4>
55
+ )}
56
+
57
+ <p className={size === 'default' ? 'p-p' : 'p-p--small'}>
58
+ {children}
59
+ </p>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ );
64
+
65
+ export { InformationBox };
@@ -0,0 +1,11 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none">
2
+ <g clip-path="url(#a)">
3
+ <path stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10ZM12 16v-4"/>
4
+ <circle cx="12" cy="8" r="1" fill="#000"/>
5
+ </g>
6
+ <defs>
7
+ <clipPath id="a">
8
+ <path fill="#fff" d="M0 0h24v24H0z"/>
9
+ </clipPath>
10
+ </defs>
11
+ </svg>
@@ -0,0 +1,62 @@
1
+
2
+ @use "../../scss/public/colors" as *;
3
+
4
+ .informationBox {
5
+ border: 1px solid;
6
+
7
+ &--information {
8
+ background-color: $ds-blue-100;
9
+ border-color: $ds-blue-500;
10
+ }
11
+
12
+ &--error {
13
+ background-color: $ds-red-100;
14
+ border-color: $ds-red-500;
15
+ }
16
+
17
+ &--warning {
18
+ background-color: $ds-yellow-100;
19
+ border-color: $ds-yellow-500;
20
+ }
21
+
22
+ &--success {
23
+ background-color: $ds-green-100;
24
+ border-color: $ds-green-500;
25
+ }
26
+
27
+ &--neutral {
28
+ background-color: $ds-white;
29
+ border-color: $ds-white;
30
+ }
31
+ }
32
+
33
+ .icon {
34
+ display: inline-block;
35
+ width: 24px;
36
+ height: 24px;
37
+
38
+ mask-image: url('./info.svg');
39
+ mask-size: contain;
40
+ mask-repeat: no-repeat;
41
+ mask-position: center;
42
+
43
+ &--information {
44
+ background-color: $ds-blue-500;
45
+ }
46
+
47
+ &--error {
48
+ background-color: $ds-red-500;
49
+ }
50
+
51
+ &--warning {
52
+ background-color: $ds-yellow-500;
53
+ }
54
+
55
+ &--success {
56
+ background-color: $ds-green-500;
57
+ }
58
+
59
+ &--neutral {
60
+ background-color: $ds-primary-500;
61
+ }
62
+ }
@@ -0,0 +1,162 @@
1
+ import { useState } from 'react';
2
+ import { AutoSuggestInput, AutoSuggestInputProps } from '.';
3
+ import { Option } from '../../../models/autoSuggestInput';
4
+ import featherLogo from '../../cards/icons/feather-logo.svg';
5
+
6
+ const story = {
7
+ title: 'JSX/Inputs/AutoSuggestInput',
8
+ component: AutoSuggestInput,
9
+ argTypes: {
10
+ suggestions: {
11
+ description: 'List of suggestions that should be displayed to the respective input',
12
+ defaultValue: [
13
+ { value: 'feather', leftIcon: featherLogo },
14
+ { value: 'feather2', leftIcon: featherLogo },
15
+ {
16
+ value: 'feather3',
17
+ leftIcon: featherLogo,
18
+ },
19
+ {
20
+ value: 'dirtyswan',
21
+ leftIcon: featherLogo,
22
+ },
23
+ {
24
+ value: 'test value',
25
+ leftIcon: featherLogo,
26
+ },
27
+ ]
28
+ },
29
+ currentOption: {
30
+ defaultValue: 'feather',
31
+ description: 'Current input of the component by user',
32
+ },
33
+ placeholder: {
34
+ defaultValue: 'Placeholder',
35
+ description: 'Placeholder for DirtySwan Input component'
36
+ },
37
+ className: {
38
+ defaultValue: '',
39
+ description: 'Class name for the most parent element',
40
+ control: { type: 'text' }
41
+ },
42
+ wrapText: {
43
+ defaultValue: false,
44
+ description: 'Wether or not wrap the entries in the dropdown or hide overflown text',
45
+ },
46
+ inputProps: {
47
+ defaultValue: {},
48
+ description: 'Pass through arbitrary props to the input.',
49
+ control: { type: 'object' },
50
+ table: {
51
+ type: {
52
+ summary: 'InputHTMLAttributes'
53
+ },
54
+ },
55
+ },
56
+ handleSuggestionSelected: {
57
+ description: 'Function that runs when a suggestion is selected from the dropdown',
58
+ action: true,
59
+ table: {
60
+ category: 'Callbacks',
61
+ },
62
+ },
63
+ onChange: {
64
+ description: 'Function that is called when value of current input changes',
65
+ action: true,
66
+ table: {
67
+ category: 'Callbacks',
68
+ },
69
+ },
70
+ handleSuggestionFetchRequest: {
71
+ description: 'Function that allows control of which suggestions should be displayed',
72
+ action: true,
73
+ table: {
74
+ category: 'Callbacks',
75
+ },
76
+ },
77
+ handleSuggestionClearRequest: {
78
+ description: 'Function that runs when suggestions are cleared (eg. input removal, selecting suggestion)',
79
+ action: true,
80
+ table: {
81
+ category: 'Callbacks',
82
+ },
83
+ },
84
+ },
85
+ parameters: {
86
+ componentSubtitle: 'This component allows quick search via the input field to find an option for selection',
87
+ customTypes: {
88
+ Option: `interface Option {
89
+ value: string; // value of option to be stored and displayed on UI
90
+ leftIcon?: string; // image of the provided option to be displayed on UI
91
+ }`
92
+ }
93
+ },
94
+ };
95
+
96
+ export const AutoSuggestInputStory = ({
97
+ currentOption = '',
98
+ suggestions,
99
+ handleSuggestionSelected,
100
+ onChange,
101
+ handleSuggestionFetchRequest,
102
+ handleSuggestionClearRequest,
103
+ placeholder,
104
+ className,
105
+ wrapText,
106
+ inputProps,
107
+ }: AutoSuggestInputProps) => {
108
+
109
+ const [selectedValues, setSelectedValues] = useState<Option[]>([]);
110
+ const [selectedOption, setSelectedOption] = useState(currentOption);
111
+ const [options, setOptions] = useState([]);
112
+
113
+ const handleSelected = (value: Option) => {
114
+ handleSuggestionSelected(value);
115
+
116
+ const newSelectedOptions = [...selectedValues, value];
117
+ setSelectedValues(newSelectedOptions);
118
+ setSelectedOption(value.value);
119
+ };
120
+
121
+ const handleFetchRequest = (value: Option) => {
122
+ handleSuggestionFetchRequest(value);
123
+
124
+ const filteredOptions = options.filter((option: Option) =>
125
+ option.value.toLowerCase().startsWith(option.value.toLowerCase())
126
+ );
127
+ setSelectedValues(filteredOptions);
128
+ };
129
+
130
+ const handleClearSuggestions = () => {
131
+ handleSuggestionClearRequest();
132
+
133
+ setOptions([]);
134
+ };
135
+
136
+ const handleOnChange = (value: string) => {
137
+ onChange(value);
138
+
139
+ setSelectedOption(value);
140
+ };
141
+
142
+ return (
143
+ <div style={{ minHeight: '300px' }}>
144
+ <AutoSuggestInput
145
+ currentOption={selectedOption}
146
+ suggestions={suggestions}
147
+ handleSuggestionSelected={handleSelected}
148
+ onChange={handleOnChange}
149
+ handleSuggestionFetchRequest={handleFetchRequest}
150
+ handleSuggestionClearRequest={handleClearSuggestions}
151
+ placeholder={placeholder}
152
+ className={className}
153
+ wrapText={wrapText}
154
+ inputProps={inputProps}
155
+ />
156
+ </div>
157
+ );
158
+ };
159
+
160
+ AutoSuggestInputStory.storyName = "AutoSuggestInput";
161
+
162
+ export default story;
@@ -5,18 +5,7 @@ import styles from './style.module.scss';
5
5
  import { Option } from '../../../models/autoSuggestInput';
6
6
  import { Input, InputProps } from '../index';
7
7
 
8
- export default ({
9
- currentOption,
10
- suggestions,
11
- handleSuggestionSelected,
12
- onChange,
13
- handleSuggestionFetchRequest,
14
- handleSuggestionClearRequest,
15
- placeholder,
16
- className,
17
- wrapText,
18
- inputProps
19
- }: {
8
+ export interface AutoSuggestInputProps {
20
9
  currentOption: string;
21
10
  suggestions: Option[];
22
11
  handleSuggestionSelected: (value: Option) => void;
@@ -27,7 +16,20 @@ export default ({
27
16
  className?: string;
28
17
  wrapText?: boolean;
29
18
  inputProps?: Omit<RenderInputComponentProps, 'value' | 'onChange'>;
30
- }) => {
19
+ }
20
+
21
+ export const AutoSuggestInput = ({
22
+ currentOption,
23
+ suggestions,
24
+ handleSuggestionSelected,
25
+ onChange,
26
+ handleSuggestionFetchRequest,
27
+ handleSuggestionClearRequest,
28
+ placeholder,
29
+ className,
30
+ wrapText,
31
+ inputProps
32
+ }: AutoSuggestInputProps) => {
31
33
  const renderSuggestion = (suggestion: Option) => (
32
34
  <div className={`${styles['suggestion-option']}`}>
33
35
  {suggestion.leftIcon && (