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,10 +1,323 @@
1
+ <%= pb_rails("passphrase", props: { label: "Default Settings", classname: "def_passphrase" }) %>
1
2
 
2
- <%= pb_rails("passphrase", props: { label: "Default Settings"}) %>
3
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "def_bar" }) %>
3
4
 
4
- <%= pb_rails("passphrase", props: { label: "Min length = 5", min_length: 5}) %>
5
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "def_caption" }) %>
5
6
 
6
- <%= pb_rails("passphrase", props: { label: "Min length = 30", min_length: 30}) %>
7
+ <%= pb_rails("text_input", props: { label: "Calculated Strength", value: "0", disabled: true, id: "calc_strength" }) %>
7
8
 
8
- <%= pb_rails("passphrase", props: { average_threshold: 1, label: "Average Threshold = 1"}) %>
9
+ <%= pb_rails("passphrase", props: { label: "Min length = 5", classname: "min_5" }) %>
9
10
 
10
- <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", strong_threshold: 4}) %>
11
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "min_5_bar" }) %>
12
+
13
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_5_caption" }) %>
14
+
15
+ <%= pb_rails("passphrase", props: { label: "Min length = 30", classname: "min_30" }) %>
16
+
17
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "min_30_bar" }) %>
18
+
19
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_30_caption" }) %>
20
+
21
+ <%= pb_rails("passphrase", props: { label: "Average Threshold = 1", classname: "avg_1" }) %>
22
+
23
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "avg_1_bar" }) %>
24
+
25
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "avg_1_caption" }) %>
26
+
27
+ <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", classname: "strong_4" }) %>
28
+
29
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "strong_4_bar" }) %>
30
+
31
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "strong_4_caption" }) %>
32
+
33
+
34
+
35
+ <%= javascript_tag do %>
36
+ window.addEventListener("DOMContentLoaded", () => {
37
+
38
+
39
+ // variables for the passphrase kits you are targeting
40
+ const defPassphrase = document.querySelector(".def_passphrase").querySelector("input")
41
+ const min5 = document.querySelector(".min_5").querySelector("input")
42
+ const min30 = document.querySelector(".min_30").querySelector("input")
43
+ const avg1 = document.querySelector(".avg_1").querySelector("input")
44
+ const strong4 = document.querySelector(".strong_4").querySelector("input")
45
+
46
+ // variable for the text_input kit you are targeting
47
+ const calcStrength = document.querySelector("#calc_strength")
48
+
49
+ // variables for the progress_simple kits you are targeting
50
+ const defBarVariant = document.getElementById("def_bar")
51
+ const defBarPercent = document.getElementById("def_bar").querySelector("div")
52
+ const min5BarVariant = document.getElementById("min_5_bar")
53
+ const min5BarPercent = document.getElementById("min_5_bar").querySelector("div")
54
+ const min30BarVariant = document.getElementById("min_30_bar")
55
+ const min30BarPercent = document.getElementById("min_30_bar").querySelector("div")
56
+ const avg1BarVariant = document.getElementById("avg_1_bar")
57
+ const avg1BarPercent = document.getElementById("avg_1_bar").querySelector("div")
58
+ const strong4BarVariant = document.getElementById("strong_4_bar")
59
+ const strong4BarPercent = document.getElementById("strong_4_bar").querySelector("div")
60
+
61
+ // hide all the progress_simple bars
62
+ defBarVariant.style.display = 'none';
63
+ defBarPercent.style.display = 'none';
64
+ min5BarVariant.style.display = 'none';
65
+ min5BarPercent.style.display = 'none';
66
+ min30BarVariant.style.display = 'none';
67
+ min30BarPercent.style.display = 'none';
68
+ avg1BarVariant.style.display = 'none';
69
+ avg1BarPercent.style.display = 'none';
70
+ strong4BarVariant.style.display = 'none';
71
+ strong4BarPercent.style.display = 'none';
72
+
73
+ // variables for the caption kits you are targeting
74
+ const defCaption = document.getElementById("def_caption")
75
+ const min5Caption = document.getElementById("min_5_caption")
76
+ const min30Caption = document.getElementById("min_30_caption")
77
+ const avg1Caption = document.getElementById("avg_1_caption")
78
+ const strong4Caption = document.getElementById("strong_4_caption")
79
+
80
+ // hide all the captions
81
+ defCaption.style.display = 'none';
82
+ min5Caption.style.display = 'none';
83
+ min30Caption.style.display = 'none';
84
+ avg1Caption.style.display = 'none';
85
+ strong4Caption.style.display = 'none';
86
+
87
+ // funtion that determines strenght of user passowrd using zxcvbn
88
+ const handleStrengthCalculation = (settings) => {
89
+
90
+ // define the settings object with its defaults
91
+ const {
92
+ passphrase = "",
93
+ common = false,
94
+ isPwned = false,
95
+ averageThreshold = 2,
96
+ minLength = 12,
97
+ strongThreshold = 3,
98
+ } = settings
99
+
100
+ // define the resultsByScore objects, these return an object with a variant and percentage,
101
+ // depending on the score of the password
102
+ const resultByScore = {
103
+ 0: {
104
+ variant: 'negative',
105
+ label: '',
106
+ percent: 0,
107
+ },
108
+ 1: {
109
+ variant: 'negative',
110
+ label: 'This passphrase is too common',
111
+ percent: 25,
112
+ },
113
+ 2: {
114
+ variant: 'negative',
115
+ label: 'Too weak',
116
+ percent: 25,
117
+ },
118
+ 3: {
119
+ variant: 'warning',
120
+ label: 'Almost there, keep going!',
121
+ percent: 50,
122
+ },
123
+ 4: {
124
+ variant: 'positive',
125
+ label: 'Success! Strong passphrase',
126
+ percent: 100,
127
+ }
128
+ }
129
+
130
+ const { score } = zxcvbn(passphrase);
131
+
132
+ const noPassphrase = passphrase.length <= 0
133
+ const commonPassphrase = common || isPwned
134
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
135
+ const averagePassphrase = score < strongThreshold
136
+ const strongPassphrase = score >= strongThreshold
137
+
138
+ // conditional that returns the score of the password, along with the resultByScore object
139
+ // so we can change the percantage and variant of the progress_simple kit
140
+ if (noPassphrase) {
141
+ return {...resultByScore[0], score}
142
+ } else if (commonPassphrase) {
143
+ return {...resultByScore[1], score}
144
+ } else if (weakPassphrase) {
145
+ return {...resultByScore[2], score}
146
+ } else if (averagePassphrase){
147
+ return {...resultByScore[3], score}
148
+ } else if (strongPassphrase) {
149
+ return {...resultByScore[4], score}
150
+ }
151
+ }
152
+
153
+
154
+ // event listeners attached to the input field
155
+ min5.addEventListener('input', (e) => {
156
+ const passphrase = e.target.value;
157
+
158
+ // defining setting object to spread into handleStrengthCalculation
159
+ setting = {
160
+ minLength: 5,
161
+ }
162
+
163
+ // pass in passphrase and setting object to handleStrengthCalculation and set that equal to result variable
164
+ const result = handleStrengthCalculation({passphrase, ...setting})
165
+
166
+ // set the value of the text_input to the score
167
+ calcStrength.value = result.score
168
+
169
+ // conditional statment to show or hide progress_simple bar and caption if user has entered a password
170
+ if (passphrase) {
171
+ min5BarVariant.style.display = 'block';
172
+
173
+ min5BarPercent.style.display = 'block';
174
+
175
+ min5Caption.style.display = 'block';
176
+ } else {
177
+ min5BarVariant.style.display = 'none';
178
+
179
+ min5BarPercent.style.display = 'none';
180
+
181
+ min5Caption.style.display = 'none';
182
+ }
183
+
184
+ // set the width of the progress_simple kit
185
+ min5BarPercent.style.width = result.percent.toString()+ "%"
186
+
187
+
188
+ // set the variant of the progress_simple kit
189
+ min5BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
190
+
191
+
192
+ // set the text of the caption kit
193
+ min5Caption.textContent = result.label
194
+ });
195
+
196
+ defPassphrase.addEventListener('input', (e) => {
197
+ const passphrase = e.target.value;
198
+
199
+ const result = handleStrengthCalculation({passphrase})
200
+
201
+ calcStrength.value = result.score
202
+
203
+ if (passphrase) {
204
+ defBarVariant.style.display = 'block';
205
+
206
+ defBarPercent.style.display = 'block';
207
+
208
+ defCaption.style.display = 'block';
209
+ } else {
210
+ defBarVariant.style.display = 'none';
211
+
212
+ defBarPercent.style.display = 'none';
213
+
214
+ defCaption.style.display = 'none';
215
+ }
216
+
217
+ defBarPercent.style.width = result.percent.toString()+ "%"
218
+
219
+ defBarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
220
+
221
+ defCaption.textContent = result.label
222
+
223
+ });
224
+
225
+ min30.addEventListener('input', (e) => {
226
+ const passphrase = e.target.value;
227
+
228
+ setting = {
229
+ minLength: 30,
230
+ }
231
+
232
+ const result = handleStrengthCalculation({passphrase, ...setting})
233
+
234
+ calcStrength.value = result.score
235
+
236
+ if (passphrase) {
237
+ min30BarVariant.style.display = 'block';
238
+
239
+ min30BarPercent.style.display = 'block';
240
+
241
+ min30Caption.style.display = 'block';
242
+ } else {
243
+ min30BarVariant.style.display = 'none';
244
+
245
+ min30BarPercent.style.display = 'none';
246
+
247
+ min30Caption.style.display = 'none';
248
+ }
249
+
250
+ min30BarPercent.style.width = result.percent.toString()+ "%"
251
+
252
+ min30BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
253
+
254
+ min30Caption.textContent = result.label
255
+ });
256
+
257
+ avg1.addEventListener('input', (e) => {
258
+ const passphrase = e.target.value;
259
+
260
+ setting = {
261
+ averageThreshold: 1,
262
+ }
263
+
264
+ const result = handleStrengthCalculation({passphrase, ...setting})
265
+
266
+ calcStrength.value = result.score
267
+
268
+ if (passphrase) {
269
+ avg1BarVariant.style.display = 'block';
270
+
271
+ avg1BarPercent.style.display = 'block';
272
+
273
+ avg1Caption.style.display = 'block';
274
+ } else {
275
+ avg1BarVariant.style.display = 'none';
276
+
277
+ avg1BarPercent.style.display = 'none';
278
+
279
+ avg1Caption.style.display = 'none';
280
+ }
281
+
282
+ avg1BarPercent.style.width = result.percent.toString()+ "%"
283
+
284
+ avg1BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
285
+
286
+ avg1Caption.textContent = result.label
287
+ });
288
+
289
+ strong4.addEventListener('input', (e) => {
290
+ const passphrase = e.target.value;
291
+
292
+ setting = {
293
+ strongThreshold: 4,
294
+ }
295
+
296
+ const result = handleStrengthCalculation({passphrase, ...setting})
297
+
298
+ calcStrength.value = result.score
299
+
300
+ if (passphrase) {
301
+ strong4BarVariant.style.display = 'block';
302
+
303
+ strong4BarPercent.style.display = 'block';
304
+
305
+ strong4Caption.style.display = 'block';
306
+ } else {
307
+ strong4BarVariant.style.display = 'none';
308
+
309
+ strong4BarPercent.style.display = 'none';
310
+
311
+ strong4Caption.style.display = 'none';
312
+ }
313
+
314
+ strong4BarPercent.style.width = result.percent.toString()+ "%"
315
+
316
+ strong4BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
317
+
318
+ strong4Caption.textContent = result.label
319
+ });
320
+
321
+
322
+ })
323
+ <% end %>
@@ -1,71 +1,157 @@
1
1
  import React, { useState } from 'react'
2
2
 
3
- import Body from '../../pb_body/_body'
4
- import Passphrase from '../../pb_passphrase/_passphrase'
5
- import TextInput from '../../pb_text_input/_text_input'
3
+ import { Body, Caption, Passphrase, ProgressSimple, TextInput } from '../..'
4
+ import zxcvbn from 'zxcvbn'
5
+
6
6
 
7
7
  const PassphraseMeterSettings = (props) => {
8
8
  const [input, setInput] = useState('')
9
+ const [result, setResult] = useState({})
10
+ const [calculatedStrength, setCalculatedStrength] = useState(0)
11
+
12
+ const meterSettings = [
13
+ {
14
+ label: "Default settings"
15
+ },
16
+ {
17
+ minLength: 5,
18
+ label: "Min length = 5",
19
+ },
20
+ {
21
+ minLength: 30,
22
+ label: "Min length = 30",
23
+ },
24
+ {
25
+ label: "Average threshold = 1",
26
+ averageThreshold: 1,
27
+ },
28
+ {
29
+ label: "Strong Threshold = 4",
30
+ strongThreshold: 4,
31
+ },
32
+ ]
33
+
34
+ const handleStrengthCalculation = (settings) => {
35
+ const {
36
+ passphrase = "",
37
+ common = false,
38
+ isPwned = false,
39
+ averageThreshold = 2,
40
+ minLength = 12,
41
+ strongThreshold = 3,
42
+ } = settings
43
+
44
+ const resultByScore = {
45
+ 0: {
46
+ variant: 'negative',
47
+ label: '',
48
+ percent: 0,
49
+ },
50
+ 1: {
51
+ variant: 'negative',
52
+ label: 'This passphrase is too common',
53
+ percent: 25,
54
+ },
55
+ 2: {
56
+ variant: 'negative',
57
+ label: 'Too weak',
58
+ percent: 25,
59
+ },
60
+ 3: {
61
+ variant: 'warning',
62
+ label: 'Almost there, keep going!',
63
+ percent: 50,
64
+ },
65
+ 4: {
66
+ variant: 'positive',
67
+ label: 'Success! Strong passphrase',
68
+ percent: 100,
69
+ }
70
+ }
71
+
72
+ const { score } = zxcvbn(passphrase);
73
+
74
+ const noPassphrase = passphrase.length <= 0
75
+ const commonPassphrase = common || isPwned
76
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
77
+ const averagePassphrase = score < strongThreshold
78
+ const strongPassphrase = score >= strongThreshold
79
+
80
+ if (noPassphrase) {
81
+ return {...resultByScore[0], score}
82
+ } else if (commonPassphrase) {
83
+ return {...resultByScore[1], score}
84
+ } else if (weakPassphrase) {
85
+ return {...resultByScore[2], score}
86
+ } else if (averagePassphrase){
87
+ return {...resultByScore[3], score}
88
+ } else if (strongPassphrase) {
89
+ return {...resultByScore[4], score}
90
+ }
91
+ }
9
92
 
10
- const handleChange = (e) => setInput(e.target.value)
93
+
94
+ const handleChange = (e) => {
95
+ const passphrase = e.target.value;
96
+
97
+ setInput(passphrase)
98
+
99
+ const calculated = []
100
+
101
+ meterSettings.forEach((setting, index) => {
102
+ const results = handleStrengthCalculation({passphrase, ...setting})
103
+ if (index == 0) setCalculatedStrength(results.score)
104
+ calculated.push(results)
105
+ })
106
+
107
+ setResult(calculated)
108
+ }
11
109
 
12
- const [strength, setStrength] = useState(0)
13
- const handleStrengthChange = (str) => setStrength(str)
14
110
  return (
15
111
  <>
16
112
  <div>
17
113
  <Body>
18
- {'These examples will all share the same input value. Type in any of the inputs to see how the strength meter changes in response to different settings.'}
114
+ {
115
+ "These examples will all share the same input value. Type in any of the inputs to see how the strength meter changes in response to different settings."
116
+ }
19
117
  </Body>
20
- <br />
21
- <TextInput
22
- disabled
23
- label="Calculated Strength"
24
- readOnly
25
- value={strength}
26
- />
27
-
28
- <Passphrase
29
- label="Default settings"
30
- onChange={handleChange}
31
- onStrengthChange={handleStrengthChange}
32
- value={input}
33
- {...props}
34
- />
35
-
36
- <Passphrase
37
- label="Min length = 5"
38
- minLength={5}
39
- onChange={handleChange}
40
- value={input}
41
- {...props}
42
- />
43
118
  <Passphrase
44
- label="Min length = 30"
45
- minLength={30}
119
+ label={"Type your passphrase"}
46
120
  onChange={handleChange}
47
121
  value={input}
48
122
  {...props}
49
123
  />
50
-
51
- <Passphrase
52
- averageThreshold={1}
53
- label="Average threshold = 1"
54
- onChange={handleChange}
55
- value={input}
56
- {...props}
57
- />
58
-
59
- <Passphrase
60
- label="Strong Threshold = 4"
61
- onChange={handleChange}
62
- strongThreshold={4}
63
- value={input}
64
- {...props}
124
+ <TextInput
125
+ disabled
126
+ label="Calculated Strength"
127
+ readOnly
128
+ value={calculatedStrength}
65
129
  />
130
+ {meterSettings.map((settings, index) => (
131
+ <div key={index}>
132
+ <Passphrase
133
+ label={settings.label}
134
+ onChange={handleChange}
135
+ value={input}
136
+ {...props}
137
+ />
138
+ {input.length > 0 && (
139
+ <>
140
+ <ProgressSimple
141
+ percent={result[index].percent}
142
+ variant={result[index].variant}
143
+ />
144
+ <Caption size='xs'
145
+ text={result[index].label}
146
+ />
147
+ </>
148
+ )}
149
+ </div>
150
+ ))}
151
+
66
152
  </div>
67
153
  </>
68
- )
154
+ );
69
155
  }
70
156
 
71
157
  export default PassphraseMeterSettings
@@ -1,9 +1,15 @@
1
- By default, the minimum length is 12 and the strength meter will show a strength of 1 if not met. Notice the bar won't change from red until the minimum is met
2
- Use the `minLength` prop to adjust.
1
+ This example shows how to enhance the passphrase strenght by setting diferent thresholds and lengths.
3
2
 
3
+ The `meterSettings` array contains different settings for each rendered input. The `handleStrengthCalculation` handles the strength calculation using those settings, showing different results for the same `passphrase` input.
4
4
 
5
- The meter also response to `averageThreshold` and `strongTreshold` props. `averageThresold` defaults to 2, and `strongThreshold` defaults to 3.
6
- This means that the bar will turn yellow when the strength of the passphrase is calculated to be 2 on a 0-4 scale, and green when 3.
5
+ By default, `minLength` is 12. Try typing any value in the `Default Example` input. Notice that the bar won't change from red until the minimum is met.
7
6
 
8
7
  Adjust these props to tune the sensitivity of the bar.
9
- Note: minimum length trumps strength and will set the bar to a red color, despite whatever strength is calculated.
8
+
9
+ Note: minimum length trumps strength and will set the bar to a red color, despite whatever strength is calculated.
10
+
11
+ <div class="pb_pill_kit_warning"><div class="pb_title_kit_size_4 pb_pill_text">Disclaimer</div></div>
12
+
13
+ This example depends on the `zxcvbn` library.
14
+
15
+ 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,123 @@
1
+ <%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_change" }) %>
2
+
3
+ <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_change" }) %>
4
+
5
+ <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_change" }) %>
6
+
7
+ <%= pb_rails("text_input", props: { label: "Passphrase Strength", value: "0", disabled: true, id: "calc_strength_change" }) %>
8
+
9
+
10
+ <%= javascript_tag do %>
11
+ window.addEventListener("DOMContentLoaded", () => {
12
+
13
+ // variables for the kits you are targeting
14
+ const passphrase = document.querySelector(".passphrase_change").querySelector("input")
15
+ const calcStrength = document.querySelector("#calc_strength_change")
16
+ const barVariant = document.getElementById("bar_change")
17
+ const barPercent = document.getElementById("bar_change").querySelector("div")
18
+ const caption = document.getElementById("caption_change")
19
+
20
+ // hide the bar and captions
21
+ barVariant.style.display = 'none';
22
+ barPercent.style.display = 'none';
23
+ caption.style.display = 'none';
24
+
25
+
26
+ const handleStrengthCalculation = (settings) => {
27
+ const {
28
+ passphrase = "",
29
+ common = false,
30
+ isPwned = false,
31
+ averageThreshold = 2,
32
+ minLength = 12,
33
+ strongThreshold = 3,
34
+ } = settings
35
+
36
+ const resultByScore = {
37
+ 0: {
38
+ variant: 'negative',
39
+ label: '',
40
+ percent: 0,
41
+ },
42
+ 1: {
43
+ variant: 'negative',
44
+ label: 'This passphrase is too common',
45
+ percent: 25,
46
+ },
47
+ 2: {
48
+ variant: 'negative',
49
+ label: 'Too weak',
50
+ percent: 25,
51
+ },
52
+ 3: {
53
+ variant: 'warning',
54
+ label: 'Almost there, keep going!',
55
+ percent: 50,
56
+ },
57
+ 4: {
58
+ variant: 'positive',
59
+ label: 'Success! Strong passphrase',
60
+ percent: 100,
61
+ }
62
+ }
63
+
64
+ const { score } = zxcvbn(passphrase);
65
+
66
+ const noPassphrase = passphrase.length <= 0
67
+ const commonPassphrase = common || isPwned
68
+ const weakPassphrase = passphrase.length < minLength || score < averageThreshold
69
+ const averagePassphrase = score < strongThreshold
70
+ const strongPassphrase = score >= strongThreshold
71
+
72
+ if (noPassphrase) {
73
+ return {...resultByScore[0], score}
74
+ } else if (commonPassphrase) {
75
+ return {...resultByScore[1], score}
76
+ } else if (weakPassphrase) {
77
+ return {...resultByScore[2], score}
78
+ } else if (averagePassphrase){
79
+ return {...resultByScore[3], score}
80
+ } else if (strongPassphrase) {
81
+ return {...resultByScore[4], score}
82
+ }
83
+ }
84
+
85
+ // event listeners attached to the input field
86
+ passphrase.addEventListener('input', (e) => {
87
+ const passphrase = e.target.value;
88
+
89
+ // pass in passphrase to the handleStrengthCalculation and set that equal to result variable
90
+ const result = handleStrengthCalculation({passphrase: passphrase})
91
+
92
+ // set the value of the text_input to the score
93
+ calcStrength.value = result.score
94
+
95
+ // conditional statment to show or hide progress_simple bar and caption if user has entered a password
96
+ if (passphrase) {
97
+ barVariant.style.display = 'block';
98
+
99
+ barPercent.style.display = 'block';
100
+
101
+ caption.style.display = 'block';
102
+ } else {
103
+ barVariant.style.display = 'none';
104
+
105
+ barPercent.style.display = 'none';
106
+
107
+ caption.style.display = 'none';
108
+ }
109
+
110
+ // set the width of the progress_simple kit
111
+ barPercent.style.width = result.percent.toString()+ "%"
112
+
113
+
114
+ // set the variant of the progress_simple kit
115
+ barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left");
116
+
117
+
118
+ // set the text of the caption kit
119
+ caption.textContent = result.label
120
+ });
121
+
122
+ })
123
+ <% end %>