@devtron-labs/devtron-fe-common-lib 0.0.7 → 0.0.9-beta-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 (86) hide show
  1. package/dist/Common/BreadCrumb/BreadCrumb.d.ts +1 -29
  2. package/dist/Common/BreadCrumb/Types.d.ts +28 -0
  3. package/dist/Common/CIPipeline.Types.d.ts +263 -0
  4. package/dist/Common/Checkbox.d.ts +1 -14
  5. package/dist/Common/Constants.d.ts +18 -0
  6. package/dist/Common/CustomTagSelector/ResizableTagTextArea.d.ts +1 -1
  7. package/dist/Common/CustomTagSelector/TagLabelValueSelector.d.ts +1 -1
  8. package/dist/Common/CustomTagSelector/Types.d.ts +11 -3
  9. package/dist/Common/CustomTagSelector/ValidationRules.d.ts +1 -1
  10. package/dist/Common/DeleteComponentModal/DeleteComponent.d.ts +4 -0
  11. package/dist/Common/DeleteComponentModal/types.d.ts +15 -0
  12. package/dist/Common/Dialogs/ConfirmationDialog.d.ts +5 -16
  13. package/dist/Common/Dialogs/DialogForm.d.ts +1 -9
  14. package/dist/Common/Dialogs/Types.d.ts +28 -0
  15. package/dist/Common/EmptyState/EmptyState.d.ts +2 -1
  16. package/dist/Common/EmptyState/GenericEmptyState.d.ts +5 -0
  17. package/dist/Common/Error.d.ts +2 -2
  18. package/dist/Common/Helper.d.ts +31 -1
  19. package/dist/Common/InfoColorBar/InfoColourbar.d.ts +2 -15
  20. package/dist/Common/Modals/Modal.d.ts +2 -9
  21. package/dist/Common/MultiSelectCustomization.d.ts +1 -2
  22. package/dist/Common/PopupMenu.d.ts +4 -21
  23. package/dist/Common/Progressing.d.ts +4 -13
  24. package/dist/Common/RadioGroup/RadioGroup.d.ts +17 -0
  25. package/dist/Common/RadioGroup.d.ts +1 -10
  26. package/dist/Common/Reload.d.ts +2 -4
  27. package/dist/Common/Security/ScanVulnerabilitiesTable.d.ts +4 -0
  28. package/dist/Common/TippyCustomized.d.ts +2 -30
  29. package/dist/Common/Toggle/Toggle.d.ts +12 -0
  30. package/dist/Common/Types.d.ts +293 -0
  31. package/dist/Common/index.d.ts +7 -1
  32. package/dist/index.js +2472 -1948
  33. package/package.json +2 -2
  34. package/rollup.config.js +3 -3
  35. package/src/Assets/Icon/ic-help.svg +3 -0
  36. package/src/Assets/Icon/ic-info-filled.svg +7 -0
  37. package/src/Assets/Icon/ic-warning.svg +7 -0
  38. package/src/Assets/Img/app-not-deployed.png +0 -0
  39. package/src/Common/Api.ts +7 -1
  40. package/src/Common/BreadCrumb/BreadCrumb.tsx +1 -30
  41. package/src/Common/BreadCrumb/Types.ts +30 -0
  42. package/src/Common/CIPipeline.Types.ts +275 -0
  43. package/src/Common/Checkbox.tsx +3 -16
  44. package/src/Common/Constants.ts +21 -0
  45. package/src/Common/CustomTagSelector/ResizableTagTextArea.tsx +6 -4
  46. package/src/Common/CustomTagSelector/TagDetails.tsx +15 -2
  47. package/src/Common/CustomTagSelector/TagLabelSelect.tsx +7 -3
  48. package/src/Common/CustomTagSelector/TagLabelValueSelector.tsx +66 -26
  49. package/src/Common/CustomTagSelector/Types.ts +11 -3
  50. package/src/Common/CustomTagSelector/ValidationRules.ts +21 -18
  51. package/src/Common/DeleteComponentModal/DeleteComponent.tsx +95 -0
  52. package/src/Common/DeleteComponentModal/types.ts +15 -0
  53. package/src/Common/Dialogs/ConfirmationDialog.tsx +6 -4
  54. package/src/Common/Dialogs/DeleteDialog.tsx +45 -27
  55. package/src/Common/Dialogs/DialogForm.tsx +2 -11
  56. package/src/Common/Dialogs/Types.ts +29 -0
  57. package/src/Common/Drawer/Drawer.scss +12 -11
  58. package/src/Common/EmptyState/EmptyState.tsx +5 -5
  59. package/src/Common/EmptyState/GenericEmptyState.tsx +41 -0
  60. package/src/Common/EmptyState/emptyState.scss +4 -15
  61. package/src/Common/Error.tsx +13 -16
  62. package/src/Common/ErrorScreenNotFound.tsx +23 -30
  63. package/src/Common/Helper.tsx +258 -2
  64. package/src/Common/InfoColorBar/InfoColourbar.tsx +6 -18
  65. package/src/Common/Modals/Modal.tsx +7 -1
  66. package/src/Common/Modals/OpaqueModal.tsx +2 -2
  67. package/src/Common/Modals/VisibleModal.tsx +1 -1
  68. package/src/Common/Modals/VisibleModal2.tsx +1 -1
  69. package/src/Common/MultiSelectCustomization.tsx +3 -3
  70. package/src/Common/PopupMenu.tsx +23 -6
  71. package/src/Common/Progressing.tsx +8 -15
  72. package/src/Common/RadioGroup/RadioGroup.tsx +88 -0
  73. package/src/Common/RadioGroup/radioGroup.scss +46 -0
  74. package/src/Common/RadioGroup.tsx +3 -13
  75. package/src/Common/Reload.tsx +15 -10
  76. package/src/Common/Security/ScanVulnerabilitiesTable.tsx +55 -0
  77. package/src/Common/Security/scanVulnerabilities.css +67 -0
  78. package/src/Common/TippyCustomized.tsx +29 -31
  79. package/src/Common/Toggle/Toggle.scss +70 -0
  80. package/src/Common/Toggle/Toggle.tsx +38 -0
  81. package/src/Common/Types.ts +319 -0
  82. package/src/Common/index.ts +7 -1
  83. package/dist/27bfa7a87d0b7039.png +0 -0
  84. package/dist/b5d52f036bdcd3ed.png +0 -0
  85. package/src/Assets/Icon/ic-close.svg +0 -9
  86. /package/src/Assets/Img/{warning-medium.svg → delete-medium.svg} +0 -0
@@ -1,6 +1,8 @@
1
- import React, { useEffect } from 'react';
2
- import {Modal} from './Modals/Modal';
3
- const PopupContext = React.createContext(null);
1
+ import React, { useEffect } from 'react'
2
+ import { Modal } from './Modals/Modal'
3
+ import { PopupMenuBodyType, PopupMenuButtonType, PopupMenuType } from './Types'
4
+
5
+ const PopupContext = React.createContext(null)
4
6
 
5
7
  function usePopupContext() {
6
8
  const context = React.useContext(PopupContext)
@@ -10,7 +12,12 @@ function usePopupContext() {
10
12
  return context
11
13
  }
12
14
 
13
- function PopupMenu({ children = null, onToggleCallback = null, autoClose = false, autoPosition = false }) {
15
+ function PopupMenu({
16
+ children = null,
17
+ onToggleCallback = null,
18
+ autoClose = false,
19
+ autoPosition = false,
20
+ }: PopupMenuType) {
14
21
  const [popupPosition, setPopupPosition] = React.useState(null)
15
22
  const [opacity, setOpacity] = React.useState(0)
16
23
  const observer = React.useRef<IntersectionObserver | null>(null)
@@ -135,7 +142,8 @@ function Button({
135
142
  tabIndex = 0,
136
143
  onHover = false,
137
144
  isKebab = false,
138
- }) {
145
+ dataTestId = "",
146
+ }: PopupMenuButtonType) {
139
147
  const { handleOpen, popupPosition, buttonRef, initialiseButtonWidth } = usePopupContext()
140
148
  return (
141
149
  <button
@@ -148,13 +156,21 @@ function Button({
148
156
  }`}
149
157
  onMouseEnter={onHover ? (disabled ? null : handleOpen) : () => {}}
150
158
  onClick={disabled ? null : handleOpen}
159
+ data-testid={dataTestId}
151
160
  >
152
161
  {children}
153
162
  </button>
154
163
  )
155
164
  }
156
165
 
157
- function Body({ children = null, rootClassName = '', style = {}, autoWidth = false, preventWheelDisable = false }) {
166
+ function Body({
167
+ children = null,
168
+ rootClassName = '',
169
+ style = {},
170
+ autoWidth = false,
171
+ preventWheelDisable = false,
172
+ noBackDrop,
173
+ }: PopupMenuBodyType) {
158
174
  const { handleClose, popupPosition, opacity, callbackRef, buttonWidth } = usePopupContext()
159
175
  return popupPosition ? (
160
176
  <Modal
@@ -170,6 +186,7 @@ function Body({ children = null, rootClassName = '', style = {}, autoWidth = fal
170
186
  opacity: opacity,
171
187
  }}
172
188
  preventWheelDisable={preventWheelDisable}
189
+ noBackDrop={noBackDrop}
173
190
  >
174
191
  {children}
175
192
  </Modal>
@@ -1,19 +1,10 @@
1
1
  import React from 'react'
2
+ import { ProgressingProps } from './Types'
2
3
 
3
- interface ProgressingProps {
4
- pageLoader?: boolean
5
- loadingText?: string
6
- size?: number
7
- fullHeight?: boolean
8
- theme?: 'white' | 'default'
9
- styles?: React.CSSProperties
10
- children?: React.ReactNode
11
- }
12
-
13
- export function Progressing({ pageLoader, size, theme, styles }: ProgressingProps): JSX.Element {
4
+ export function Progressing({ pageLoader, size, theme, styles, fillColor }: ProgressingProps): JSX.Element {
14
5
  const loaderSize = size ? `${size}px` : pageLoader ? '48px' : '20px'
15
6
  return (
16
- <div className={`loader ${theme || 'default'}-background`} style={styles}>
7
+ <div className={`loader ${theme || 'default'}-background`} style={styles} data-testid="progressing">
17
8
  <div style={{ width: loaderSize, height: loaderSize }}>
18
9
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" className="loader__svg">
19
10
  <g fill="none" fillRule="evenodd" strokeLinecap="round">
@@ -27,7 +18,7 @@ export function Progressing({ pageLoader, size, theme, styles }: ProgressingProp
27
18
  type="rotate"
28
19
  />
29
20
  <path
30
- fill="#06C"
21
+ fill={fillColor || '#06C'}
31
22
  fillRule="nonzero"
32
23
  d="M12 2.5A9.5 9.5 0 1 1 2.5 12a1.5 1.5 0 0 1 3 0A6.5 6.5 0 1 0 12 5.5a1.5 1.5 0 0 1 0-3z"
33
24
  />
@@ -42,16 +33,18 @@ export function DetailsProgressing({
42
33
  loadingText,
43
34
  size = 24,
44
35
  fullHeight = false,
45
- children,
46
36
  styles,
37
+ fillColor,
38
+ children,
47
39
  }: ProgressingProps): JSX.Element {
48
40
  return (
49
41
  <div
50
42
  className={`details-loader bcn-0 flex column fs-14 fw-6 ${fullHeight ? 'h-100' : 'details-loader-height'}`}
51
43
  style={styles}
44
+ data-testid="details-progressing"
52
45
  >
53
46
  <span style={{ width: `${size}px`, height: `${size}px` }}>
54
- <Progressing size={size} />
47
+ <Progressing size={size} fillColor={fillColor} />
55
48
  </span>
56
49
  {loadingText && <span className="mt-10">{loadingText}</span>}
57
50
  {children}
@@ -0,0 +1,88 @@
1
+ import Tippy from '@tippyjs/react'
2
+ import React, { useState, useEffect } from 'react'
3
+ import { ConditionalWrap } from '../Helper'
4
+ import './radioGroup.scss'
5
+
6
+ const RadioContext = React.createContext(null)
7
+
8
+ function useRadioContext() {
9
+ const context = React.useContext(RadioContext)
10
+ if (!context) {
11
+ throw new Error(`Radio compound components cannot be rendered outside the Toggle component`)
12
+ }
13
+ return context
14
+ }
15
+
16
+ interface RadioGroupInterface {
17
+ name: string
18
+ onChange: any
19
+ className?: string
20
+ initialTab: string
21
+ disabled: boolean
22
+ showTippy?: boolean
23
+ tippyContent?: any
24
+ dataTestId?: string
25
+ }
26
+
27
+ interface RadioGroupComposition {
28
+ Radio?: React.FC<any>
29
+ }
30
+
31
+ const RadioGroup: React.FC<RadioGroupInterface> & RadioGroupComposition = React.memo(function RadioGroup({
32
+ name,
33
+ onChange,
34
+ children,
35
+ className = '',
36
+ initialTab,
37
+ disabled = false,
38
+ dataTestId
39
+ }) {
40
+ const [selected, select] = useState(null)
41
+
42
+ useEffect(() => {
43
+ if (initialTab === selected) return
44
+ select(initialTab)
45
+ }, [initialTab])
46
+
47
+ return (
48
+ <RadioContext.Provider value={{ name, selected, select, disabled, onChange }}>
49
+ <div className={`${className} radio-group`}>{children}</div>
50
+ </RadioContext.Provider>
51
+ )
52
+ })
53
+
54
+ function Radio({ value, children, className = '', showTippy = false, tippyContent = '', canSelect = true, isDisabled = false, tippyClass = '', dataTestId }) {
55
+ const { name, selected, select, disabled, onChange } = useRadioContext()
56
+ return (
57
+ <ConditionalWrap
58
+ condition={showTippy}
59
+ wrap={(children) => (
60
+ <Tippy className={`default-tt w-250 ${tippyClass}`} arrow={false} placement="bottom" content={tippyContent}>
61
+ {children}
62
+ </Tippy>
63
+ )}
64
+ >
65
+ <label className={`${className} radio ${(isDisabled || disabled)? 'disabled': ''}`}>
66
+ <input
67
+ type="checkbox"
68
+ value={value}
69
+ name={name}
70
+
71
+ checked={value === selected}
72
+ onChange={(e) => {
73
+ e.persist()
74
+ if (canSelect) {
75
+ select(e.target.value)
76
+ }
77
+ onChange(e)
78
+ }}
79
+ disabled={isDisabled || disabled}
80
+ />
81
+ <span className="radio__item-label" data-testid={dataTestId}>{children}</span>
82
+ </label>
83
+ </ConditionalWrap>
84
+ )
85
+ }
86
+
87
+ RadioGroup.Radio = Radio
88
+ export default RadioGroup
@@ -0,0 +1,46 @@
1
+ .radio-group {
2
+ .label,
3
+ .radio,
4
+ .checkbox {
5
+ margin: 0;
6
+ }
7
+ height: 30px;
8
+ background: white;
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ padding: 4px;
13
+ border-radius: 4px;
14
+ .radio {
15
+ height: 100%;
16
+ width: auto;
17
+ color: var(--N400);
18
+ display: flex;
19
+ align-items: center;
20
+ }
21
+ .radio+.radio {
22
+ margin-top: 0;
23
+ }
24
+ input[type=checkbox] {
25
+ display: contents;
26
+ overflow: hidden;
27
+ max-width: 0px;
28
+ height: 0;
29
+ opacity: 0;
30
+ margin: unset;
31
+ }
32
+ input+.radio__item-label {
33
+ padding: 4px 6px;
34
+ height: 100%;
35
+ width: 100%;
36
+ display: flex;
37
+ align-items: center;
38
+ transition: all 0.5s;
39
+ cursor: pointer;
40
+ }
41
+ input[type=checkbox]:checked+.radio__item-label {
42
+ background: #2c3354;
43
+ color: white;
44
+ border-radius: 4px;
45
+ }
46
+ }
@@ -1,10 +1,7 @@
1
1
  import React, { Component, createContext } from 'react'
2
+ import { RadioGroupItemProps, RadioGroupProps } from './Types'
2
3
  const RadioGroupContext = createContext({ name: '', value: '', disabled: false, onChange: (event) => {} })
3
4
 
4
- export interface RadioGroupItemProps {
5
- value: string
6
- }
7
-
8
5
  export class RadioGroupItem extends Component<RadioGroupItemProps> {
9
6
  render() {
10
7
  return (
@@ -21,8 +18,9 @@ export class RadioGroupItem extends Component<RadioGroupItemProps> {
21
18
  onChange={context.onChange}
22
19
  value={this.props.value}
23
20
  checked={context.value === this.props.value}
21
+ data-testid={this.props.dataTestId}
24
22
  />
25
- <span className="form__radio-item-content">
23
+ <span className="form__radio-item-content" data-testid={`${this.props.dataTestId}-span`}>
26
24
  <span className="radio__button"></span>
27
25
  <span className="radio__title">{this.props.children}</span>
28
26
  </span>
@@ -35,14 +33,6 @@ export class RadioGroupItem extends Component<RadioGroupItemProps> {
35
33
  }
36
34
  }
37
35
 
38
- export interface RadioGroupProps {
39
- value: string
40
- name: string
41
- disabled?: boolean
42
- onChange: (event) => void
43
- className?: string
44
- }
45
-
46
36
  export class RadioGroup extends Component<RadioGroupProps> {
47
37
  render() {
48
38
  return (
@@ -1,18 +1,23 @@
1
1
  import React from 'react'
2
- import loadingFailure from '../Assets/Img/ic-loading-failure.png';
2
+ import loadingFailure from '../Assets/Img/ic-loading-failure.png'
3
+ import { ReloadType } from './Types'
3
4
 
4
- export default function Reload({ reload = null, className = '' }) {
5
- function refresh(e){
6
- window.location.reload();
5
+ export default function Reload({ reload, className = '' }: ReloadType) {
6
+ function refresh(e) {
7
+ window.location.reload()
7
8
  }
8
9
  return (
9
- <article className={`flex ${className}`} style={{ width: '100%', height: '100%' }}>
10
- <div className="flex column" style={{ width: '250px', textAlign: 'center' }}>
11
- <img src={loadingFailure} style={{ width: '100%', height: 'auto', marginBottom: '12px' }} alt="load-error" />
10
+ <article className={`flex w-100 h-100 ${className}`}>
11
+ <div className="flex column w-250 dc__align-center" data-testid="reload">
12
+ <img src={loadingFailure} style={{ height: 'auto' }} className="w-100 mb-12" alt="load-error" />
12
13
  <h3 className="title dc__bold">Failed to load</h3>
13
- <div className="dc__empty__subtitle" style={{ marginBottom: '20px' }}>We could not load this page. Please give us another try.</div>
14
- <button type="button" className="cta ghosted" onClick={typeof reload === 'function' ? reload : refresh}>Retry</button>
14
+ <div className="dc__empty__subtitle mb-20">
15
+ We could not load this page. Please give us another try.
16
+ </div>
17
+ <button type="button" className="cta ghosted" onClick={typeof reload === 'function' ? reload : refresh}>
18
+ Retry
19
+ </button>
15
20
  </div>
16
21
  </article>
17
22
  )
18
- }
23
+ }
@@ -0,0 +1,55 @@
1
+ import React from 'react'
2
+ import { ScanVulnerabilitiesTableProps, VulnerabilityType } from '../Types'
3
+ import './scanVulnerabilities.css'
4
+
5
+ export default function ScanVulnerabilitiesTable({ vulnerabilities }: ScanVulnerabilitiesTableProps) {
6
+ const renderRow = (vulnerability: VulnerabilityType) => {
7
+ return (
8
+ <tr
9
+ className="dc__security-tab__table-row cursor"
10
+ onClick={(e) => {
11
+ window.open(`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${vulnerability.name}`, '_blank')
12
+ }}
13
+ >
14
+ <td className="security-tab__cell-cve dc__cve-cell">
15
+ <a
16
+ href={`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${vulnerability.name}`}
17
+ rel="noopener noreferrer"
18
+ target="_blank"
19
+ >
20
+ {vulnerability.name}
21
+ </a>
22
+ </td>
23
+ <td className="security-tab__cell-severity">
24
+ <span className={`fill-${vulnerability.severity?.toLowerCase()}`}>{vulnerability.severity}</span>
25
+ </td>
26
+ <td className="security-tab__cell-package">{vulnerability.package}</td>
27
+ <td className="security-tab__cell-current-ver">{vulnerability.version}</td>
28
+ <td className="security-tab__cell-fixed-ver">{vulnerability.fixedVersion}</td>
29
+ <td
30
+ className={`security-tab__cell-policy security-tab__cell-policy--${vulnerability.policy?.toLowerCase()}`}
31
+ >
32
+ {vulnerability.policy?.toLowerCase()}
33
+ </td>
34
+ </tr>
35
+ )
36
+ }
37
+
38
+ return (
39
+ <table className="security-tab__table">
40
+ <tbody>
41
+ <tr className="security-tab__table-header">
42
+ <th className="security-cell-header security-tab__cell-cve">CVE</th>
43
+ <th className="security-cell-header security-tab__cell-severity">Severity</th>
44
+ <th className="security-cell-header security-tab__cell-package">Package</th>
45
+ <th className="security-cell-header security-tab__cell-current-ver">Current Version</th>
46
+ <th className="security-cell-header security-tab__cell-fixed-ver">Fixed In Version</th>
47
+ <th className="security-cell-header security-tab__cell-policy">Policy</th>
48
+ </tr>
49
+ {vulnerabilities.map((vulnerability) => {
50
+ return renderRow(vulnerability)
51
+ })}
52
+ </tbody>
53
+ </table>
54
+ )
55
+ }
@@ -0,0 +1,67 @@
1
+ .modal-body--scan-details {
2
+ position: fixed;
3
+ top: 0;
4
+ right: 0;
5
+ background: var(--N000);
6
+ width: 800px;
7
+ }
8
+
9
+ .security-tab__table {
10
+ width: 100%;
11
+ }
12
+
13
+ .security-tab__table-header {
14
+ border-bottom: solid 1px var(--N200);
15
+ }
16
+
17
+ .security-cell-header {
18
+ font-size: 12px;
19
+ font-weight: 600;
20
+ line-height: 1.5;
21
+ letter-spacing: normal;
22
+ text-transform: uppercase;
23
+ color: var(--N500);
24
+ }
25
+
26
+ .dc__security-tab__table-row {
27
+ font-size: 13px;
28
+ font-weight: normal;
29
+ line-height: 1.54;
30
+ letter-spacing: normal;
31
+ color: var(--N900);
32
+ box-shadow: inset 0 -1px 0 0 #f5f5f5;
33
+ }
34
+
35
+ .security-tab__cell-cve,
36
+ .security-tab__cell-severity,
37
+ .security-tab__cell-package,
38
+ .security-tab__cell-current-ver,
39
+ .security-tab__cell-fixed-ver,
40
+ .security-tab__cell-policy {
41
+ padding: 10px;
42
+ }
43
+
44
+ .security-tab__cell-cve {
45
+ padding-left: 0px;
46
+ text-align: left;
47
+ width: 20%;
48
+ }
49
+
50
+ .security-tab__cell-policy {
51
+ padding-right: 0px;
52
+ }
53
+
54
+ .security-tab__cell-policy--whitelist,
55
+ .security-tab__cell-policy--whitelisted {
56
+ color: var(--G500);
57
+ text-transform: capitalize;
58
+ }
59
+
60
+ .security-tab__cell-policy--block {
61
+ color: var(--R500);
62
+ text-transform: capitalize;
63
+ }
64
+
65
+ .scanned-object__results {
66
+ margin: 0 20px;
67
+ }
@@ -1,41 +1,16 @@
1
- import React, { ReactNode, useRef } from 'react'
1
+ import React, { useRef, useState } from 'react'
2
2
  import Tippy from '@tippyjs/react'
3
- import { Placement } from 'tippy.js'
4
3
  import { ReactComponent as CloseIcon } from '../Assets/Icon/ic-cross.svg'
4
+ import { ReactComponent as QuestionFilled } from '../Assets/Icon/ic-help.svg'
5
5
  import 'tippy.js/animations/shift-toward-subtle.css'
6
- import { TippyTheme } from './Types'
7
-
8
- interface TippyCustomizedProps {
9
- theme: TippyTheme
10
- visible?: boolean
11
- heading?: string
12
- infoTextHeading?: string
13
- placement: Placement
14
- className?: string
15
- Icon?: React.FunctionComponent<React.SVGProps<SVGSVGElement>>
16
- iconPath?: string
17
- iconClass?: string
18
- iconSize?: number // E.g. 16, 20, etc.. Currently, there are around 12 sizes supported. Check `icons.css` or `base.scss` for supported sizes or add new size (class names starts with `icon-dim-`).
19
- onImageLoadError?: (e) => void
20
- onClose?: () => void
21
- infoText?: string
22
- showCloseButton?: boolean
23
- arrow?: boolean
24
- interactive?: boolean
25
- showOnCreate?: boolean
26
- trigger?: string
27
- animation?: string
28
- duration?: number
29
- additionalContent?: ReactNode
30
- documentationLink?: string
31
- documentationLinkText?: string
32
- children: React.ReactElement<any>
33
- }
6
+ import { TippyCustomizedProps, TippyTheme } from './Types'
7
+ import { not } from './Helper'
34
8
 
35
9
  // This component will handle some of the new tippy designs and interactions
36
10
  // So this can be updated to support further for new features or interactions
37
11
  export function TippyCustomized(props: TippyCustomizedProps) {
38
12
  const tippyRef = useRef(null)
13
+ const [showHeadingInfo, setShowHeadingInfo] = useState(false)
39
14
  const isWhiteTheme = props.theme === TippyTheme.white
40
15
 
41
16
  const onTippyMount = (tippyInstance) => {
@@ -52,6 +27,7 @@ export function TippyCustomized(props: TippyCustomizedProps) {
52
27
  props.onClose()
53
28
  }
54
29
  }
30
+ setShowHeadingInfo(false)
55
31
  }
56
32
 
57
33
  const closeOnEsc = (e) => {
@@ -60,6 +36,10 @@ export function TippyCustomized(props: TippyCustomizedProps) {
60
36
  }
61
37
  }
62
38
 
39
+ const toggleHeadingInfo = (e) => {
40
+ setShowHeadingInfo(not)
41
+ }
42
+
63
43
  const getTippyContent = () => {
64
44
  const {
65
45
  Icon,
@@ -68,6 +48,7 @@ export function TippyCustomized(props: TippyCustomizedProps) {
68
48
  iconSize,
69
49
  onImageLoadError,
70
50
  heading,
51
+ headingInfo,
71
52
  infoTextHeading,
72
53
  infoText,
73
54
  showCloseButton,
@@ -86,7 +67,7 @@ export function TippyCustomized(props: TippyCustomizedProps) {
86
67
  <img
87
68
  className={`icon-dim-${iconSize || 20} mr-6 ${iconClass || ''}`}
88
69
  src={iconPath}
89
- alt={heading}
70
+ alt="Heading"
90
71
  onError={onImageLoadError}
91
72
  />
92
73
  ) : (
@@ -97,6 +78,11 @@ export function TippyCustomized(props: TippyCustomizedProps) {
97
78
  )
98
79
  )}
99
80
  {heading && <span className={`fs-14 fw-6 lh-20 ${showCloseButton ? 'mr-6' : ''}`}>{heading}</span>}
81
+ {headingInfo && (
82
+ <div className="icon-dim-20 cursor" onClick={toggleHeadingInfo}>
83
+ <QuestionFilled className="icon-dim-20" />
84
+ </div>
85
+ )}
100
86
  {showCloseButton && (
101
87
  <div className="icon-dim-16 ml-auto">
102
88
  <CloseIcon
@@ -106,6 +92,18 @@ export function TippyCustomized(props: TippyCustomizedProps) {
106
92
  </div>
107
93
  )}
108
94
  </div>
95
+ {showHeadingInfo && (
96
+ <div
97
+ className={`flex left bcv-1 fs-13 fw-4 lh-20 pt-8 pb-8 ${
98
+ isWhiteTheme ? 'pl-12 pr-12' : 'pl-20 pr-20'
99
+ }`}
100
+ >
101
+ <div className="icon-dim-20 mr-8">
102
+ <QuestionFilled className="icon-dim-20 fcv-5" />
103
+ </div>
104
+ <div className="dc__word-break dc__hyphens-auto">{headingInfo}</div>
105
+ </div>
106
+ )}
109
107
  {infoTextHeading && (
110
108
  <div
111
109
  className={`dc__word-break dc__hyphens-auto fs-14 fw-6 lh-20 ${
@@ -0,0 +1,70 @@
1
+ .toggle__switch {
2
+ position: relative;
3
+ display: inline-block;
4
+ width: 100%;
5
+ height: 100%;
6
+
7
+ &.disabled{
8
+ cursor: not-allowed;
9
+ .toggle__slider{
10
+ cursor: not-allowed;
11
+ }
12
+ }
13
+ }
14
+
15
+
16
+ /* Hide default HTML checkbox */
17
+
18
+ .toggle__switch input {
19
+ opacity: 0;
20
+ width: 0;
21
+ height: 0;
22
+ }
23
+
24
+
25
+ /* The slider */
26
+
27
+ .toggle__slider {
28
+ position: absolute;
29
+ cursor: pointer;
30
+ top: 0;
31
+ left: 0;
32
+ right: 0;
33
+ bottom: 0;
34
+ background-color: #ccc;
35
+ transition: all .4s ease;
36
+ }
37
+
38
+ .toggle__slider:before {
39
+ position: absolute;
40
+ content: "";
41
+ height: calc( 100% - 8px);
42
+ width: calc( 50% - 4px);
43
+ left: 4px;
44
+ bottom: 4px;
45
+ background-color: white;
46
+ transition: all 0.4s ease;
47
+ }
48
+
49
+ input:checked+.toggle__slider {
50
+ background-color: var(--color);
51
+ }
52
+
53
+ input:focus+.toggle__slider {
54
+ box-shadow: 0 0 1px var(--color);
55
+ }
56
+
57
+ input:checked+.toggle__slider:before {
58
+ transform: translateX(calc( 100%));
59
+ }
60
+
61
+
62
+ /* Rounded sliders */
63
+
64
+ .toggle__slider.round {
65
+ border-radius: 34px;
66
+ }
67
+
68
+ .toggle__slider.round:before {
69
+ border-radius: 50%;
70
+ }
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import { useEffectAfterMount } from '../Helper';
3
+ import './Toggle.scss'
4
+
5
+ const Toggle = ({selected=false, onSelect=null, color="#36b37e", rootClassName="", disabled=false, dataTestId="handle-toggle-button", ...props})=>{
6
+ const [active, setActive] = React.useState(selected);
7
+
8
+ useEffectAfterMount(()=>{
9
+ if(typeof onSelect === 'function'){
10
+ if(active !== selected){
11
+ onSelect(active)
12
+ }
13
+ }
14
+ },[active])
15
+
16
+ useEffectAfterMount(() => {
17
+ setActive(selected)
18
+ }, [selected])
19
+
20
+ function handleClick(e){
21
+ if(!disabled){
22
+ setActive(active=>!active)
23
+ }
24
+ }
25
+
26
+ return (
27
+ <label
28
+ {...props}
29
+ className={`${rootClassName} toggle__switch ${disabled ? 'disabled' : ''}`}
30
+ style={{ ['--color' as any]: color }}
31
+ >
32
+ <input type="checkbox" checked={!!active} onChange={handleClick} className="toggle__input" />
33
+ <span className="toggle__slider round" data-testid={dataTestId}></span>
34
+ </label>
35
+ )
36
+ }
37
+
38
+ export default Toggle