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

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 (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,3 +1,12 @@
1
- Use `checkPwned | checked_pwned` prop to enable checking against <a href='https://haveibeenpwned.com/Passwords'>HaveIBeenPwned's</a> API. As the passphrase is typed, it is checked against more than half a billion breached passwords, to help ensure its not compromised.
1
+ Use <a href='https://haveibeenpwned.com/Passwords'>HaveIBeenPwned's</a> API to check for breached passwords.
2
+
3
+ As the passphrase is typed, it is checked against more than half a billion breached passwords, to help ensure its not compromised.
2
4
  Should it fail, the feedback will express the passphrase is too common, prompting the user to change.
3
- This uses their k-Anonymity model, so only the first 5 characters of a hashed copy of the passphrase are sent.
5
+
6
+ This uses their k-Anonymity model, so only the first 5 characters of a hashed copy of the passphrase are sent.
7
+
8
+ <div class="pb_pill_kit_warning"><div class="pb_title_kit_size_4 pb_pill_text">Disclaimer</div></div>
9
+
10
+ This example depends on the `zxcvbn` library and `haveibeenpwned` API.
11
+
12
+ 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.
@@ -0,0 +1,136 @@
1
+ <%= pb_rails("body", props: {
2
+ margin_bottom: "md",
3
+ id: "body_common"
4
+ }) %>
5
+
6
+ <%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_common" }) %>
7
+
8
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_common" }) %>
9
+
10
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_common" }) %>
11
+
12
+
13
+ <%= javascript_tag do %>
14
+ window.addEventListener("DOMContentLoaded", () => {
15
+
16
+ const commonText = document.querySelector("#body_common")
17
+
18
+ // variables for the kits you are targeting
19
+ const passphrase = document.querySelector(".passphrase_common").querySelector("input")
20
+ const barVariant = document.getElementById("bar_common")
21
+ const barPercent = document.getElementById("bar_common").querySelector("div")
22
+ const caption = document.getElementById("caption_common")
23
+
24
+ // hide the bar and captions
25
+ barVariant.style.display = 'none';
26
+ barPercent.style.display = 'none';
27
+ caption.style.display = 'none';
28
+
29
+
30
+ const handleStrengthCalculation = (settings) => {
31
+ const {
32
+ passphrase = "",
33
+ common = false,
34
+ isPwned = false,
35
+ averageThreshold = 2,
36
+ minLength = 12,
37
+ strongThreshold = 3,
38
+ } = settings
39
+
40
+ const resultByScore = {
41
+ 0: {
42
+ variant: 'negative',
43
+ label: '',
44
+ percent: 0,
45
+ },
46
+ 1: {
47
+ variant: 'negative',
48
+ label: 'This passphrase is too common',
49
+ percent: 25,
50
+ },
51
+ 2: {
52
+ variant: 'negative',
53
+ label: 'Too weak',
54
+ percent: 25,
55
+ },
56
+ 3: {
57
+ variant: 'warning',
58
+ label: 'Almost there, keep going!',
59
+ percent: 50,
60
+ },
61
+ 4: {
62
+ variant: 'positive',
63
+ label: 'Success! Strong passphrase',
64
+ percent: 100,
65
+ }
66
+ }
67
+
68
+ const { score } = zxcvbn(passphrase);
69
+
70
+ const noPassphrase = passphrase.length <= 0
71
+ const commonPassphrase = common || isPwned
72
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
73
+ const averagePassphrase = score < strongThreshold
74
+ const strongPassphrase = score >= strongThreshold
75
+
76
+ if (noPassphrase) {
77
+ return {...resultByScore[0], score}
78
+ } else if (commonPassphrase) {
79
+ return {...resultByScore[1], score}
80
+ } else if (weakPassphrase) {
81
+ return {...resultByScore[2], score}
82
+ } else if (averagePassphrase){
83
+ return {...resultByScore[3], score}
84
+ } else if (strongPassphrase) {
85
+ return {...resultByScore[4], score}
86
+ }
87
+ }
88
+
89
+ // array that holds the common passwords you wish to target
90
+ const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd']
91
+
92
+ commonText.textContent = `Try typing any of the following: ${COMMON_PASSPHRASES.join(', ')}`
93
+
94
+ // function that checks if the user password is in the common password list
95
+ const isCommon = (passphrase) => {
96
+ if (COMMON_PASSPHRASES.includes(passphrase))
97
+ return true
98
+ return false
99
+ }
100
+
101
+ // event listeners attached to the input field
102
+ passphrase.addEventListener('input', (e) => {
103
+ const passphrase = e.target.value;
104
+
105
+ // pass in passphrase to the handleStrengthCalculation and set that equal to result variable
106
+ const result = handleStrengthCalculation({ passphrase: passphrase, common: isCommon(passphrase) })
107
+
108
+ // conditional statment to show or hide progress_simple bar and caption if user has entered a password
109
+ if (passphrase) {
110
+ barVariant.style.display = 'block';
111
+
112
+ barPercent.style.display = 'block';
113
+
114
+ caption.style.display = 'block';
115
+ } else {
116
+ barVariant.style.display = 'none';
117
+
118
+ barPercent.style.display = 'none';
119
+
120
+ caption.style.display = 'none';
121
+ }
122
+
123
+ // set the width of the progress_simple kit
124
+ barPercent.style.width = result.percent.toString()+ "%"
125
+
126
+
127
+ // set the variant of the progress_simple kit
128
+ barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
129
+
130
+
131
+ // set the text of the caption kit
132
+ caption.textContent = result.label
133
+ });
134
+
135
+ })
136
+ <% end %>
@@ -1,32 +1,114 @@
1
- import React, { useState } from 'react'
1
+ import React, { useState, useEffect } from 'react'
2
2
 
3
- import Passphrase from '../_passphrase'
4
- import Body from '../../pb_body/_body'
3
+ import {Body, Caption, Passphrase, ProgressSimple} from '../..'
4
+ import zxcvbn from 'zxcvbn'
5
5
 
6
6
  const PassphraseCommon = (props) => {
7
7
  const [input, setInput] = useState('')
8
-
8
+ const [checkStrength, setCheckStrength] = useState({
9
+ label: '',
10
+ percent: 0,
11
+ score: 0,
12
+ variant: ''
13
+ })
9
14
  const handleChange = (e) => setInput(e.target.value)
10
15
 
16
+ const handleStrengthCalculation = (settings) => {
17
+ const {
18
+ passphrase = "",
19
+ common = false,
20
+ isPwned = false,
21
+ averageThreshold = 2,
22
+ minLength = 12,
23
+ strongThreshold = 3,
24
+ } = settings
25
+
26
+ const resultByScore = {
27
+ 0: {
28
+ variant: 'negative',
29
+ label: '',
30
+ percent: 0,
31
+ },
32
+ 1: {
33
+ variant: 'negative',
34
+ label: 'This passphrase is too common',
35
+ percent: 25,
36
+ },
37
+ 2: {
38
+ variant: 'negative',
39
+ label: 'Too weak',
40
+ percent: 25,
41
+ },
42
+ 3: {
43
+ variant: 'warning',
44
+ label: 'Almost there, keep going!',
45
+ percent: 50,
46
+ },
47
+ 4: {
48
+ variant: 'positive',
49
+ label: 'Success! Strong passphrase',
50
+ percent: 100,
51
+ }
52
+ }
53
+
54
+ const { score } = zxcvbn(passphrase);
55
+
56
+ const noPassphrase = passphrase.length <= 0
57
+ const commonPassphrase = common || isPwned
58
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
59
+ const averagePassphrase = score < strongThreshold
60
+ const strongPassphrase = score >= strongThreshold
61
+
62
+ if (noPassphrase) {
63
+ return {...resultByScore[0], score}
64
+ } else if (commonPassphrase) {
65
+ return {...resultByScore[1], score}
66
+ } else if (weakPassphrase) {
67
+ return {...resultByScore[2], score}
68
+ } else if (averagePassphrase){
69
+ return {...resultByScore[3], score}
70
+ } else if (strongPassphrase) {
71
+ return {...resultByScore[4], score}
72
+ }
73
+ }
74
+
11
75
  const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd']
12
76
 
13
- const commonCheck = (passphrase) => {
77
+ const isCommon = (passphrase) => {
14
78
  if (COMMON_PASSPHRASES.includes(passphrase))
15
79
  return true
16
80
  return false
17
81
  }
18
82
 
83
+ useEffect(() => {
84
+ const result = handleStrengthCalculation({ passphrase: input, common: isCommon(input) });
85
+ setCheckStrength({ ...result })
86
+ }, [input])
87
+
88
+
19
89
  return (
20
90
  <>
21
91
  <div>
22
- <Body text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(' ')}`} />
23
- <br />
92
+ <Body
93
+ marginBottom='md'
94
+ text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(', ')}`} />
24
95
  <Passphrase
25
- common={commonCheck(input)}
26
96
  onChange={handleChange}
27
97
  value={input}
28
98
  {...props}
29
99
  />
100
+ {input.length > 0 && (
101
+ <>
102
+ <ProgressSimple
103
+ className={input.length === 0 ? "progress-empty-input" : null}
104
+ percent={checkStrength.percent}
105
+ variant={checkStrength.variant}
106
+ />
107
+ <Caption size='xs'
108
+ text={checkStrength.label}
109
+ />
110
+ </>
111
+ )}
30
112
  </div>
31
113
  </>
32
114
  )
@@ -0,0 +1,5 @@
1
+ <div class="pb_pill_kit_warning"><div class="pb_title_kit_size_4 pb_pill_text">Disclaimer</div></div>
2
+
3
+ This example depends on the `zxcvbn` library.
4
+
5
+ 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.
@@ -0,0 +1,51 @@
1
+ <%= pb_rails("passphrase", props: { classname: "pass_input_1" }) %>
2
+
3
+ <%= pb_rails("passphrase", props: { confirmation: true, classname: "pass_input_2"}) %>
4
+
5
+ <div id="match"> </div>
6
+
7
+ <%= javascript_tag do %>
8
+ window.addEventListener("DOMContentLoaded", () => {
9
+
10
+ const useState = (defaultValue) => {
11
+ let value = defaultValue;
12
+ const getValue = () => value
13
+ const setValue = (newValue) => {
14
+ return value = newValue
15
+ }
16
+ return [getValue, setValue];
17
+ }
18
+
19
+ const [input, setInput] = useState('')
20
+ const [confirmationInput, setConfirmationInput] = useState('')
21
+
22
+ const match = document.querySelector("#match")
23
+
24
+ const input1 = document.querySelector(".pass_input_1").querySelector("input")
25
+ const input2 = document.querySelector(".pass_input_2").querySelector("input")
26
+
27
+ input1.addEventListener('input', (e) => {
28
+ setInput(e.target.value)
29
+ setMatchText()
30
+ });
31
+
32
+ input2.addEventListener('input', (e) => {
33
+ setConfirmationInput(e.target.value)
34
+ setMatchText()
35
+ });
36
+
37
+ const setMatchText = () => {
38
+
39
+ if (input() && confirmationInput()) {
40
+ if (input() === confirmationInput()) {
41
+ match.textContent = "They match!"
42
+ } else {
43
+ match.textContent = "They don't match!"
44
+ }
45
+ } else {
46
+ match.textContent = ""
47
+ }
48
+
49
+ }
50
+ })
51
+ <% end %>
@@ -0,0 +1,39 @@
1
+ import React, { useState } from 'react'
2
+
3
+ import {Body, Passphrase} from '../..'
4
+
5
+ const PassphraseConfirmation = (props) => {
6
+ const [input, setInput] = useState('')
7
+ const [confirmationInput, setConfirmationInput] = useState('')
8
+
9
+ const handleChange = (e) => setInput(e.target.value)
10
+ const handleConfirmationChange = (e) => setConfirmationInput(e.target.value)
11
+
12
+ return (
13
+ <>
14
+ <div>
15
+ <Passphrase
16
+ onChange={handleChange}
17
+ value={input}
18
+ {...props}
19
+ />
20
+ <Passphrase
21
+ confirmation
22
+ onChange={handleConfirmationChange}
23
+ value={confirmationInput}
24
+ {...props}
25
+ />
26
+ {input && confirmationInput && (
27
+ <Body
28
+ text={
29
+ input === confirmationInput ? "They match!" : "They don't match!"
30
+ }
31
+ {...props}
32
+ />
33
+ )}
34
+ </div>
35
+ </>
36
+ );
37
+ }
38
+
39
+ export default PassphraseConfirmation
@@ -1,3 +1 @@
1
1
  <%= pb_rails("passphrase") %>
2
-
3
- <%= pb_rails("passphrase", props: { confirmation: true}) %>
@@ -6,27 +6,13 @@ const PassphraseDefault = (props) => {
6
6
  const [input, setInput] = useState('')
7
7
  const handleChange = (e) => setInput(e.target.value)
8
8
 
9
- const [confoInput, setConfoInput] = useState('')
10
- const handleConfoChange = (e) => setConfoInput(e.target.value)
11
-
12
9
  return (
13
- <>
14
- <div>
15
- <Passphrase
16
- id="my-passphrase"
17
- onChange={handleChange}
18
- value={input}
19
- {...props}
20
- />
21
- <Passphrase
22
- confirmation
23
- onChange={handleConfoChange}
24
- value={confoInput}
25
- {...props}
26
- />
27
- <span>{input === confoInput ? 'They match!' : 'They don\'t match!'}</span>
28
- </div>
29
- </>
10
+ <Passphrase
11
+ id="my-passphrase"
12
+ onChange={handleChange}
13
+ value={input}
14
+ {...props}
15
+ />
30
16
  )
31
17
  }
32
18
 
@@ -4,7 +4,7 @@
4
4
  id: "my-disabled-passphrase",
5
5
  name: "my-disabled-field",
6
6
  },
7
- label: "Input props passed directly to input kit"
7
+ label: "Pass props directly to input kit"
8
8
  }) %>
9
9
 
10
10
  <%= pb_rails("passphrase", props: {
@@ -12,5 +12,5 @@
12
12
  id: "my-custome-id",
13
13
  name: "my-value-name",
14
14
  },
15
- label: "Set name, id, etc for use in forms"
15
+ label: "Set name and ID for use in form libraries"
16
16
  }) %>
@@ -36,7 +36,7 @@ const PassphraseInputProps = (props) => {
36
36
  {...props}
37
37
  />
38
38
  <Passphrase
39
- inputProps={{ name: 'my-value-name', id: 'my-value-id' }}
39
+ inputProps={{ name: 'my-value-name', id: 'my-value-id-2' }}
40
40
  label="Set name and ID for use in form libraries"
41
41
  onChange={handleChange}
42
42
  value={input}