playbook_ui 11.12.1.pre.alpha.charts1 → 11.12.1.pre.alpha.passphrase1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/index.js +1 -0
  3. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.jsx +111 -0
  4. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.jsx +151 -0
  5. data/app/pb_kits/playbook/pb_circle_chart/circle_chart.html.erb +21 -9
  6. data/app/pb_kits/playbook/pb_circle_chart/circle_chart.rb +47 -7
  7. data/app/pb_kits/playbook/pb_dashboard/{pbChartsDarkTheme.ts → pbChartsDarkTheme.js} +21 -6
  8. data/app/pb_kits/playbook/pb_dashboard/{pbChartsLightTheme.ts → pbChartsLightTheme.js} +21 -6
  9. data/app/pb_kits/playbook/pb_gauge/_gauge.jsx +112 -0
  10. data/app/pb_kits/playbook/pb_gauge/_gauge.scss +0 -4
  11. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.html.erb +1 -1
  12. data/app/pb_kits/playbook/pb_gauge/docs/_gauge_complex.jsx +8 -8
  13. data/app/pb_kits/playbook/pb_gauge/gauge.html.erb +11 -1
  14. data/app/pb_kits/playbook/pb_gauge/gauge.rb +8 -3
  15. data/app/pb_kits/playbook/pb_line_graph/_line_graph.jsx +113 -0
  16. data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +56 -97
  17. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.html.erb +145 -1
  18. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.jsx +127 -3
  19. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_breached.md +11 -2
  20. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.html.erb +136 -0
  21. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx +90 -8
  22. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.md +5 -0
  23. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.html.erb +51 -0
  24. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_confirmation.jsx +39 -0
  25. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb +0 -2
  26. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx +6 -20
  27. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb +2 -2
  28. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx +1 -1
  29. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +318 -5
  30. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +134 -48
  31. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md +11 -5
  32. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.html.erb +123 -0
  33. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx +96 -20
  34. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md +6 -2
  35. data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +4 -0
  36. data/app/pb_kits/playbook/pb_passphrase/docs/index.js +1 -0
  37. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -1
  38. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +5 -9
  39. data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +0 -47
  40. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.jsx +79 -0
  41. data/app/pb_kits/playbook/pb_treemap_chart/docs/_treemap_chart_tooltip.jsx +1 -1
  42. data/app/pb_kits/playbook/playbook-rails-react-bindings.js +0 -4
  43. data/app/pb_kits/playbook/playbook-rails.js +4 -0
  44. data/app/pb_kits/playbook/plugins/pb_chart.js +322 -0
  45. data/lib/playbook/version.rb +1 -1
  46. metadata +15 -16
  47. data/app/pb_kits/playbook/pb_bar_graph/_bar_graph.tsx +0 -145
  48. data/app/pb_kits/playbook/pb_circle_chart/ChartsTypes.ts +0 -2
  49. data/app/pb_kits/playbook/pb_circle_chart/_circle_chart.tsx +0 -216
  50. data/app/pb_kits/playbook/pb_dashboard/pbChartsColorsHelper.ts +0 -16
  51. data/app/pb_kits/playbook/pb_dashboard/themeTypes.ts +0 -16
  52. data/app/pb_kits/playbook/pb_gauge/_gauge.tsx +0 -213
  53. data/app/pb_kits/playbook/pb_line_graph/_line_graph.tsx +0 -148
  54. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md +0 -1
  55. data/app/pb_kits/playbook/pb_passphrase/passwordStrength.js +0 -55
  56. data/app/pb_kits/playbook/pb_passphrase/useHaveIBeenPwned.js +0 -52
  57. data/app/pb_kits/playbook/pb_passphrase/useZxcvbn.js +0 -58
  58. data/app/pb_kits/playbook/pb_treemap_chart/_treemap_chart.tsx +0 -111
@@ -1,34 +1,110 @@
1
1
  import React, { useState } from 'react'
2
+ import { useEffect } from 'react'
2
3
 
3
- import Passphrase from '../_passphrase'
4
-
5
- import TextInput from '../../pb_text_input/_text_input'
4
+ import { Caption, Passphrase, ProgressSimple, TextInput} from '../..'
5
+ import zxcvbn from 'zxcvbn'
6
6
 
7
7
  const PassphraseStrengthChange = (props) => {
8
8
  const [input, setInput] = useState('')
9
+ const [checkStrength, setCheckStrength] = useState({
10
+ label: '',
11
+ percent: 0,
12
+ score: 0,
13
+ variant: ''
14
+ })
9
15
 
10
16
  const handleChange = (e) => setInput(e.target.value)
11
17
 
12
- const [strength, setStrength] = useState(0)
13
- const handleStrengthChange = (str) => setStrength(str)
18
+ const handleStrengthCalculation = (settings) => {
19
+ const {
20
+ passphrase = "",
21
+ common = false,
22
+ isPwned = false,
23
+ averageThreshold = 2,
24
+ minLength = 12,
25
+ strongThreshold = 3,
26
+ } = settings
27
+
28
+ const resultByScore = {
29
+ 0: {
30
+ variant: 'negative',
31
+ label: '',
32
+ percent: 0,
33
+ },
34
+ 1: {
35
+ variant: 'negative',
36
+ label: 'This passphrase is too common',
37
+ percent: 25,
38
+ },
39
+ 2: {
40
+ variant: 'negative',
41
+ label: 'Too weak',
42
+ percent: 25,
43
+ },
44
+ 3: {
45
+ variant: 'warning',
46
+ label: 'Almost there, keep going!',
47
+ percent: 50,
48
+ },
49
+ 4: {
50
+ variant: 'positive',
51
+ label: 'Success! Strong passphrase',
52
+ percent: 100,
53
+ }
54
+ }
55
+
56
+ const { score } = zxcvbn(passphrase);
57
+
58
+ const noPassphrase = passphrase.length <= 0
59
+ const commonPassphrase = common || isPwned
60
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
61
+ const averagePassphrase = score < strongThreshold
62
+ const strongPassphrase = score >= strongThreshold
63
+
64
+ if (noPassphrase) {
65
+ return {...resultByScore[0], score}
66
+ } else if (commonPassphrase) {
67
+ return {...resultByScore[1], score}
68
+ } else if (weakPassphrase) {
69
+ return {...resultByScore[2], score}
70
+ } else if (averagePassphrase){
71
+ return {...resultByScore[3], score}
72
+ } else if (strongPassphrase) {
73
+ return {...resultByScore[4], score}
74
+ }
75
+ }
76
+
77
+ useEffect(() => {
78
+ const result = handleStrengthCalculation({ passphrase: input })
79
+ setCheckStrength({...result})
80
+ },[input])
14
81
 
15
82
  return (
16
83
  <>
17
- <div>
18
- <Passphrase
19
- label="Passphrase"
20
- onChange={handleChange}
21
- onStrengthChange={handleStrengthChange}
22
- value={input}
23
- {...props}
24
- />
25
- <TextInput
26
- disabled
27
- label="Passphrase Strength"
28
- readOnly
29
- value={strength}
30
- />
31
- </div>
84
+ <Passphrase
85
+ label="Passphrase"
86
+ onChange={handleChange}
87
+ value={input}
88
+ {...props}
89
+ />
90
+ {input.length > 0 && (
91
+ <>
92
+ <ProgressSimple
93
+ percent={checkStrength.percent}
94
+ variant={checkStrength.variant}
95
+ />
96
+ <Caption size='xs'
97
+ text={checkStrength.label}
98
+ />
99
+ </>
100
+ )}
101
+ <TextInput
102
+ disabled
103
+ label="Passphrase Strength"
104
+ marginTop="xl"
105
+ readOnly
106
+ value={checkStrength.score}
107
+ />
32
108
  </>
33
109
  )
34
110
  }
@@ -1,3 +1,7 @@
1
- As the strength of the entered passphrase changes, the optional `onStrengthChange` callback is called with the new strength value. This exposes the calculated strength.
1
+ Strength is calculated on a 0-4 scale by the <a href="https://github.com/dropbox/zxcvbn" target="_blank"> Zxcvbn package</a>.
2
2
 
3
- Strength is calculated on a 0-4 scale by the <a href="https://github.com/dropbox/zxcvbn" target="_blank"> Zxcvbn package</a>
3
+ <div class="pb_pill_kit_warning"><div class="pb_title_kit_size_4 pb_pill_text">Disclaimer</div></div>
4
+
5
+ This example depends on the `zxcvbn` library.
6
+
7
+ You can use any library to achieve the same result, this example only intends to show how to add more features to the `Passphrase` kit.
@@ -2,13 +2,17 @@ examples:
2
2
 
3
3
  rails:
4
4
  - passphrase_default: Default
5
+ - passphrase_confirmation: Confirmation
5
6
  - passphrase_meter_settings: Meter Settings
6
7
  - passphrase_input_props: Input Props
7
8
  - passphrase_tips: Tips
9
+ - passphrase_strength_change: Strength Change
10
+ - passphrase_common: Common Passphrases
8
11
  - passphrase_breached: Breached Passphrases
9
12
 
10
13
  react:
11
14
  - passphrase_default: Default
15
+ - passphrase_confirmation: Confirmation
12
16
  - passphrase_meter_settings: Meter Settings
13
17
  - passphrase_input_props: Input Props
14
18
  - passphrase_tips: Tips
@@ -1,4 +1,5 @@
1
1
  export { default as PassphraseDefault } from './_passphrase_default.jsx'
2
+ export { default as PassphraseConfirmation } from './_passphrase_confirmation.jsx'
2
3
  export { default as PassphraseMeterSettings } from './_passphrase_meter_settings'
3
4
  export { default as PassphraseInputProps } from './_passphrase_input_props'
4
5
  export { default as PassphraseTips } from './_passphrase_tips'
@@ -1 +1 @@
1
- <%= react_component('Passphrase', object.passphrase_options) %>
1
+ <%= react_component('Passphrase', object.passphrase_options, class: object.classname,) %>
@@ -3,15 +3,14 @@
3
3
  module Playbook
4
4
  module PbPassphrase
5
5
  class Passphrase < Playbook::KitBase
6
- prop :average_threshold
7
- prop :check_pwned
8
6
  prop :confirmation, type: Playbook::Props::Boolean, default: false
9
7
  prop :input_props, type: Playbook::Props::Hash, default: {}
10
8
  prop :label
11
- prop :min_length
12
- prop :show_tips_below
13
- prop :strong_threshold
9
+ prop :show_tips_below, type: Playbook::Props::Enum,
10
+ values: %w[always xs sm md lg xl],
11
+ default: "always"
14
12
  prop :tips, type: Playbook::Props::Array, default: []
13
+ prop :value, type: Playbook::Props::String
15
14
 
16
15
  def classname
17
16
  generate_classname("pb_passphrase")
@@ -19,18 +18,15 @@ module Playbook
19
18
 
20
19
  def passphrase_options
21
20
  {
22
- checkPwned: check_pwned,
23
21
  dark: dark,
24
22
  id: id,
25
- averageThreshold: average_threshold,
26
23
  confirmation: confirmation,
27
24
  inputProps: input_props,
28
25
  label: label,
29
- minLength: min_length,
30
26
  showTipsBelow: show_tips_below,
31
- strongThreshold: strong_threshold,
32
27
  tips: tips,
33
28
  uncontrolled: true,
29
+ value: value,
34
30
  }.compact
35
31
  end
36
32
  end
@@ -64,41 +64,6 @@ test('passes input props to input element', () => {
64
64
  expect(input).toBeDisabled()
65
65
  })
66
66
 
67
- test('progress bar is invisible when value is empty', () => {
68
- render(
69
- <Passphrase
70
- data={{ testid: testId }}
71
- />
72
- )
73
-
74
- const kit = screen.getByTestId(testId)
75
- expect(kit.querySelector('[class^=pb_progress_simple_wrapper]')).toHaveClass('progress-empty-input')
76
- })
77
-
78
- test('progress bar is visible when value is not empty', () => {
79
- render(
80
- <Passphrase
81
- data={{ testid: testId }}
82
- value="test_password_input"
83
- />
84
- )
85
-
86
- const kit = screen.getByTestId(testId)
87
- expect(kit.querySelector('[class^=pb_progress_simple_wrapper]')).not.toHaveClass('progress-empty-input')
88
- })
89
-
90
- test('no progress bar is show when confirmation is true', () => {
91
- render(
92
- <Passphrase
93
- confirmation
94
- data={{ testid: testId }}
95
- />
96
- )
97
-
98
- const kit = screen.getByTestId(testId)
99
- expect(kit.querySelector('[class^=pb_progress_simple_wrapper]')).toBeNull()
100
- })
101
-
102
67
  test('popover target shows when tips are given', () => {
103
68
  render(
104
69
  <Passphrase
@@ -121,15 +86,3 @@ test('popover target does not show when tips are not given', () => {
121
86
  const kit = screen.getByTestId(testId)
122
87
  expect(kit.querySelector('[class^=pb_popover_reference_wrapper]')).toBeNull()
123
88
  })
124
-
125
- test('data-strength attribute exposes strength of password', () => {
126
- render(
127
- <Passphrase
128
- data={{ testid: testId }}
129
- value="correct horse battery staple"
130
- />
131
- )
132
-
133
- const kit = screen.getByTestId(testId)
134
- expect(parseInt(kit.getAttribute('data-strength'))).toBeGreaterThan(0)
135
- })
@@ -0,0 +1,79 @@
1
+ /* @flow */
2
+
3
+ import React from 'react'
4
+ import classnames from 'classnames'
5
+
6
+ import { globalProps } from '../utilities/globalProps'
7
+ import pbChart from '../plugins/pb_chart'
8
+
9
+ type TreemapChartProps = {
10
+ chartData: array<{
11
+ name: string,
12
+ parent?: string | number,
13
+ value: number,
14
+ color?: string,
15
+ id?: string | number,
16
+ }>,
17
+ className?: string,
18
+ colors: array,
19
+ dark?: boolean,
20
+ drillable: boolean,
21
+ grouped: boolean,
22
+ height?: string,
23
+ id: number,
24
+ title: string,
25
+ tooltipHtml: string,
26
+ type?: string,
27
+ }
28
+
29
+ export default class TreemapChart extends React.Component<TreemapChartProps> {
30
+ static defaultProps = {
31
+ className: 'pb_treemap_chart',
32
+ dark: false,
33
+ drillable: false,
34
+ grouped: false,
35
+ type: 'treemap',
36
+ }
37
+
38
+ componentDidMount() {
39
+ const {
40
+ chartData,
41
+ className,
42
+ colors = [],
43
+ dark,
44
+ drillable,
45
+ grouped,
46
+ height,
47
+ id,
48
+ title = "",
49
+ tooltipHtml = '<span style="font-weight: bold; color:{point.color};">&#9679; </span>{point.name}: <b>{point.value}</b>',
50
+ type,
51
+ } = this.props
52
+
53
+ new pbChart(`.${className}`, {
54
+ chartData: chartData,
55
+ colors: colors,
56
+ dark,
57
+ drillable,
58
+ grouped,
59
+ height: height,
60
+ id: id,
61
+ title: title,
62
+ tooltipHtml,
63
+ type,
64
+ })
65
+ }
66
+
67
+ props: TreemapChartProps
68
+
69
+ render() {
70
+ const { className, id } = this.props
71
+
72
+ return (
73
+ <div
74
+ className={classnames(globalProps(this.props), className)}
75
+ id={id}
76
+ />
77
+ )
78
+ }
79
+ }
@@ -39,7 +39,7 @@ const TreemapChartTooltip = (props) => (
39
39
  chartData={chartData}
40
40
  id="treemap-tooltip"
41
41
  title="Favored Pizza Toppings"
42
- tooltipHtml= '<p>Custom tooltip for {point.name} <br/>with value: {point.value}</p>'
42
+ tooltipHtml={"<p>Custom tooltip for {point.name} <br/>with value: {point.value}</p>"}
43
43
  {...props}
44
44
  />
45
45
  </div>
@@ -4,13 +4,11 @@ import WebpackerReact from 'webpacker-react'
4
4
  import ujs from 'webpacker-react/ujs'
5
5
 
6
6
  import BarGraph from './pb_bar_graph/_bar_graph'
7
- import CircleChart from './pb_circle_chart/_circle_chart'
8
7
  import Dialog from './pb_dialog/_dialog'
9
8
  import DialogBody from './pb_dialog/child_kits/_dialog_body'
10
9
  import DialogFooter from './pb_dialog/child_kits/_dialog_footer'
11
10
  import DialogHeader from './pb_dialog/child_kits/_dialog_header'
12
11
  import DistributionBar from './pb_distribution_bar/_distribution_bar'
13
- import Gauge from './pb_gauge/_gauge'
14
12
  import Legend from './pb_legend/_legend'
15
13
  import LineGraph from './pb_line_graph/_line_graph'
16
14
  import Passphrase from './pb_passphrase/_passphrase'
@@ -20,7 +18,6 @@ import Typeahead from './pb_typeahead/_typeahead'
20
18
 
21
19
  WebpackerReact.registerComponents({
22
20
  BarGraph,
23
- CircleChart,
24
21
  Dialog,
25
22
  DialogBody,
26
23
  DialogFooter,
@@ -32,7 +29,6 @@ WebpackerReact.registerComponents({
32
29
  RichTextEditor,
33
30
  TreemapChart,
34
31
  Typeahead,
35
- Gauge,
36
32
  })
37
33
 
38
34
  ujs.setup(
@@ -1,3 +1,7 @@
1
+ // Charts
2
+ import pbChart from './plugins/pb_chart'
3
+ window.pbChart = pbChart
4
+
1
5
  // Forms
2
6
  import './pb_form/pb_form_validation'
3
7