playbook_ui 9.5.0.alpha.rs.downgrade → 9.7.0.pre.alphawidth1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/app/pb_kits/playbook/_playbook.scss +1 -0
  3. data/app/pb_kits/playbook/data/menu.yml +1 -0
  4. data/app/pb_kits/playbook/index.js +4 -3
  5. data/app/pb_kits/playbook/pb_date/_date.jsx +3 -3
  6. data/app/pb_kits/playbook/pb_date/date.html.erb +2 -3
  7. data/app/pb_kits/playbook/pb_date/docs/_date_variants.html.erb +8 -0
  8. data/app/pb_kits/playbook/pb_date/docs/_date_variants.jsx +10 -0
  9. data/app/pb_kits/playbook/pb_dialog/dialog_header.rb +23 -24
  10. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.jsx +4 -2
  11. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/_fixed_confirmation_toast.scss +7 -0
  12. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line.html.erb +2 -1
  13. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line.jsx +2 -1
  14. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/docs/_fixed_confirmation_toast_multi_line.md +1 -1
  15. data/app/pb_kits/playbook/pb_fixed_confirmation_toast/fixed_confirmation_toast.rb +7 -1
  16. data/app/pb_kits/playbook/pb_flex/_flex_item.jsx +1 -1
  17. data/app/pb_kits/playbook/pb_form_group/_form_group.jsx +3 -1
  18. data/app/pb_kits/playbook/pb_form_group/_form_group.scss +8 -0
  19. data/app/pb_kits/playbook/pb_form_group/docs/_form_group_full_width.html.erb +13 -0
  20. data/app/pb_kits/playbook/pb_form_group/docs/_form_group_full_width.jsx +43 -0
  21. data/app/pb_kits/playbook/pb_form_group/docs/_form_group_full_width.md +1 -0
  22. data/app/pb_kits/playbook/pb_form_group/docs/example.yml +2 -0
  23. data/app/pb_kits/playbook/pb_form_group/docs/index.js +1 -1
  24. data/app/pb_kits/playbook/pb_form_group/form_group.rb +10 -1
  25. data/app/pb_kits/playbook/pb_nav/_vertical_nav.scss +1 -1
  26. data/app/pb_kits/playbook/pb_nav/docs/_block_nav.html.erb +41 -5
  27. data/app/pb_kits/playbook/pb_nav/docs/_block_nav.jsx +44 -6
  28. data/app/pb_kits/playbook/pb_passphrase/_passphrase.jsx +205 -0
  29. data/app/pb_kits/playbook/pb_passphrase/_passphrase.scss +73 -0
  30. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_common.jsx +33 -0
  31. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.html.erb +3 -0
  32. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.jsx +31 -0
  33. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_default.md +1 -0
  34. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.html.erb +16 -0
  35. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.jsx +56 -0
  36. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_input_props.md +1 -0
  37. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.html.erb +10 -0
  38. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.jsx +68 -0
  39. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_meter_settings.md +9 -0
  40. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.jsx +33 -0
  41. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_strength_change.md +3 -0
  42. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_tips.html.erb +26 -0
  43. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_tips.jsx +54 -0
  44. data/app/pb_kits/playbook/pb_passphrase/docs/_passphrase_tips.md +1 -0
  45. data/app/pb_kits/playbook/pb_passphrase/docs/example.yml +15 -0
  46. data/app/pb_kits/playbook/pb_passphrase/docs/index.js +6 -0
  47. data/app/pb_kits/playbook/pb_passphrase/passphrase.html.erb +1 -0
  48. data/app/pb_kits/playbook/pb_passphrase/passphrase.rb +36 -0
  49. data/app/pb_kits/playbook/pb_passphrase/passphrase.test.jsx +123 -0
  50. data/app/pb_kits/playbook/pb_passphrase/passwordStrength.js +55 -0
  51. data/app/pb_kits/playbook/pb_select/_select.jsx +10 -1
  52. data/app/pb_kits/playbook/pb_select/_select.scss +27 -30
  53. data/app/pb_kits/playbook/pb_select/select.rb +5 -1
  54. data/app/pb_kits/playbook/pb_typeahead/docs/_typeahead_default.html.erb +1 -1
  55. data/app/pb_kits/playbook/pb_typeahead/typeahead.html.erb +5 -1
  56. data/app/pb_kits/playbook/pb_typeahead/typeahead.rb +5 -13
  57. data/app/pb_kits/playbook/react_rails_kits.js +1 -0
  58. data/lib/playbook/version.rb +1 -1
  59. metadata +30 -3
@@ -1,12 +1,12 @@
1
1
  import React from 'react'
2
- import { Nav } from '../../'
2
+ import { Nav, User } from '../../'
3
3
  import NavItem from '../_item.jsx'
4
4
 
5
5
  const BlockNav = (props) => {
6
6
  return (
7
7
  <Nav
8
8
  link="#"
9
- title="Menu"
9
+ title="Users"
10
10
  {...props}
11
11
  >
12
12
  <NavItem
@@ -14,11 +14,49 @@ const BlockNav = (props) => {
14
14
  link="#"
15
15
  {...props}
16
16
  >
17
- {'Photos'}
17
+ <User
18
+ align="left"
19
+ avatarUrl="https://randomuser.me/api/portraits/women/44.jpg"
20
+ name="Anna Black"
21
+ orientation="horizontal"
22
+ territory="PHL"
23
+ title="Remodeling Consultant"
24
+ {...props}
25
+ />
26
+ </NavItem>
27
+ <NavItem link="#">
28
+ <User
29
+ align="left"
30
+ avatarUrl="https://randomuser.me/api/portraits/women/45.jpg"
31
+ name="Julie Hamilton"
32
+ orientation="horizontal"
33
+ territory="PHL"
34
+ title="Inside Sales Agent"
35
+ {...props}
36
+ />
37
+ </NavItem>
38
+ <NavItem link="#">
39
+ <User
40
+ align="left"
41
+ avatarUrl="https://randomuser.me/api/portraits/men/44.jpg"
42
+ name="Dennis Wilks"
43
+ orientation="horizontal"
44
+ territory="PHL"
45
+ title="Senior Remodeling Consultant"
46
+ {...props}
47
+ />
48
+ </NavItem>
49
+ <NavItem link="#">
50
+ <User
51
+ align="left"
52
+ avatarUrl="https://randomuser.me/api/portraits/men/46.jpg"
53
+ name="Ronnie Martin"
54
+ orientation="horizontal"
55
+ territory="PHL"
56
+ title="Customer Development Representative"
57
+ {...props}
58
+ />
18
59
  </NavItem>
19
- <NavItem link="#">{'Music'}</NavItem>
20
- <NavItem link="#">{'Video'}</NavItem>
21
- <NavItem link="#">{'Files'}</NavItem>
22
60
  </Nav>
23
61
  )
24
62
  }
@@ -0,0 +1,205 @@
1
+
2
+ /* @flow */
3
+
4
+ import React, { useCallback, useEffect, useMemo, useState } from 'react'
5
+ import classnames from 'classnames'
6
+ import { buildAriaProps, buildCss, buildDataProps } from '../utilities/props'
7
+ import { globalProps } from '../utilities/globalProps.js'
8
+ import { zxcvbnPasswordScore } from './passwordStrength.js'
9
+ import { Body, Caption, Flex, Icon, PbReactPopover, ProgressSimple, TextInput } from '../'
10
+
11
+ type PassphraseProps = {
12
+ aria?: object,
13
+ averageThreshold?: number,
14
+ common?: boolean,
15
+ confirmation?: boolean,
16
+ className?: string,
17
+ data?: object,
18
+ dark?: boolean,
19
+ id?: string,
20
+ inputProps?: {},
21
+ label?: string,
22
+ minLength?: number,
23
+ onChange: (String) => void,
24
+ showTipsBelow?: 'always' | 'xs' | 'sm' | 'md' | 'lg' | 'xl',
25
+ onStrengthChange?: (number) => void,
26
+ strongThreshold?: number,
27
+ tips?: Array<string>,
28
+ uncontrolled?: boolean,
29
+ value: string,
30
+ }
31
+
32
+ const Passphrase = (props: PassphraseProps) => {
33
+ const {
34
+ aria = {},
35
+ averageThreshold = 2,
36
+ className,
37
+ common = false,
38
+ confirmation = false,
39
+ dark = false,
40
+ data = {},
41
+ id,
42
+ inputProps = {},
43
+ label = confirmation ? 'Confirm Passphrase' : 'Passphrase',
44
+ minLength,
45
+ onChange = () => {},
46
+ showTipsBelow = 'always',
47
+ onStrengthChange,
48
+ strongThreshold = 3,
49
+ tips = [],
50
+ uncontrolled = false,
51
+ value = '',
52
+ } = props
53
+
54
+ const [uncontrolledValue, setUncontrolledValue] = useState('')
55
+
56
+ const handleChange = useCallback(
57
+ (e) => uncontrolled ? setUncontrolledValue(e.target.value) : onChange(e),
58
+ [uncontrolled, onChange]
59
+ )
60
+
61
+ const displayValue = useMemo(
62
+ () => (uncontrolled ? uncontrolledValue : value),
63
+ [value, uncontrolledValue, uncontrolled],
64
+ )
65
+
66
+ const [showPopover, setShowPopover] = useState(false)
67
+ const toggleShowPopover = () => setShowPopover(!showPopover)
68
+ const [showPassphrase, setShowPassphrase] = useState(false)
69
+ const toggleShowPassphrase = () => setShowPassphrase(!showPassphrase)
70
+
71
+ const ariaProps = buildAriaProps(aria)
72
+ const dataProps = buildDataProps(data)
73
+ const classes = classnames(buildCss('pb_passphrase'), globalProps(props), className)
74
+
75
+ const calculator = useMemo(
76
+ () => confirmation ? { test: () => ({}) } : zxcvbnPasswordScore({ averageThreshold, strongThreshold, minLength }),
77
+ [averageThreshold, confirmation, strongThreshold, minLength]
78
+ )
79
+
80
+ const { percent: progressPercent, variant: progressVariant, text: strengthLabel, strength } = calculator.test(displayValue, common)
81
+
82
+ useEffect(() => {
83
+ if (typeof onStrengthChange === 'function') {
84
+ onStrengthChange(strength)
85
+ }
86
+ }, [strength])
87
+
88
+ const tipClass = classnames(
89
+ (dark ? 'dark' : null),
90
+ (showTipsBelow === 'always' ? null : `show-below-${showTipsBelow}`),
91
+ )
92
+
93
+ const popoverReference = (
94
+ <a
95
+ className={tipClass}
96
+ onClick={toggleShowPopover}
97
+ >
98
+ <Icon
99
+ dark={dark}
100
+ icon="info-circle"
101
+ size="xs"
102
+ variant="link"
103
+ />
104
+ </a>
105
+ )
106
+
107
+ return (
108
+ <div
109
+ {...ariaProps}
110
+ {...dataProps}
111
+ className={classes}
112
+ id={id}
113
+ >
114
+ <label>
115
+ <Flex align="baseline">
116
+ <Caption
117
+ className="passphrase-label"
118
+ text={label}
119
+ />
120
+ <If condition={tips.length > 0 && !confirmation}>
121
+ <PbReactPopover
122
+ placement="right"
123
+ reference={popoverReference}
124
+ show={showPopover}
125
+ >
126
+ <Flex
127
+ align="center"
128
+ orientation="column"
129
+ >
130
+ <Caption
131
+ marginBottom="xs"
132
+ text="Tips for a good passphrase"
133
+ />
134
+ <div>
135
+ {
136
+ tips.map((tip, i) => (
137
+ <Caption
138
+ key={i}
139
+ marginBottom="xs"
140
+ size="xs"
141
+ >
142
+ <Icon
143
+ icon="shield-check"
144
+ marginRight="xs"
145
+ />
146
+ {tip}
147
+ </Caption>
148
+ ))
149
+ }
150
+ </div>
151
+ </Flex>
152
+ </PbReactPopover>
153
+ </If>
154
+ </Flex>
155
+ <div className="passphrase-text-input-wrapper">
156
+ <TextInput
157
+ className="passphrase-text-input"
158
+ dark={dark}
159
+ marginBottom="xs"
160
+ onChange={handleChange}
161
+ placeholder="Enter a passphrase..."
162
+ type={showPassphrase ? 'text' : 'password'}
163
+ value={displayValue}
164
+ {...inputProps}
165
+ />
166
+ <span
167
+ className="show-passphrase-icon"
168
+ dark={dark}
169
+ onClick={toggleShowPassphrase}
170
+ >
171
+ <Body
172
+ className={showPassphrase ? 'hide-icon' : ''}
173
+ color="light"
174
+ dark={dark}
175
+ >
176
+ <Icon icon="eye-slash" />
177
+ </Body>
178
+ <Body
179
+ className={showPassphrase ? '' : 'hide-icon'}
180
+ color="light"
181
+ dark={dark}
182
+ >
183
+ <Icon icon="eye" />
184
+ </Body>
185
+ </span>
186
+ </div>
187
+ </label>
188
+ <If condition={!confirmation}>
189
+ <ProgressSimple
190
+ className={displayValue.length === 0 ? 'progress-empty-input' : null}
191
+ dark={dark}
192
+ percent={progressPercent}
193
+ variant={progressVariant}
194
+ />
195
+ <Caption
196
+ dark={dark}
197
+ size="xs"
198
+ text={strengthLabel}
199
+ />
200
+ </If>
201
+ </div>
202
+ )
203
+ }
204
+
205
+ export default Passphrase
@@ -0,0 +1,73 @@
1
+ @import "../tokens/colors";
2
+ @import "../tokens/spacing";
3
+ @import "../tokens/screen_sizes";
4
+
5
+ .pb_passphrase {
6
+ margin-bottom: $space_sm;
7
+
8
+ label {
9
+ display: inline;
10
+ }
11
+
12
+ a.dark {
13
+ color: $white;
14
+ }
15
+
16
+ a {
17
+
18
+ &[class*=show-below-] {
19
+ display: none;
20
+ }
21
+ @each $breakpoint_name, $breakpoint in $breakpoints {
22
+ &.show-below-#{$breakpoint_name} {
23
+ @include break_at($breakpoint) {
24
+ display: inline;
25
+ }
26
+ }
27
+ }
28
+ }
29
+
30
+ .passphrase-label {
31
+ margin-right: ($space_xs/2);
32
+ }
33
+
34
+ .passphrase-text-input-wrapper {
35
+ position: relative;
36
+
37
+ .pb_text_input_kit_label {
38
+ margin-bottom: ($space_xs/2);
39
+ }
40
+
41
+ .passphrase-text-input input {
42
+ padding-right: 42px;
43
+ }
44
+
45
+ .passphrase-text-input .text_input_wrapper {
46
+ margin-bottom: 0;
47
+ }
48
+
49
+ .show-passphrase-icon {
50
+ position: absolute;
51
+ right: 11px;
52
+ top: 11px;
53
+ cursor: pointer;
54
+ @media (hover:hover) {
55
+ &:hover .pb_body_kit_light {
56
+ color: $primary;
57
+ }
58
+ }
59
+
60
+ .hide-icon {
61
+ display: none;
62
+ }
63
+ }
64
+ }
65
+
66
+ .pb_progress_simple_wrapper, .pb_progress_simple_wrapper_dark {
67
+ margin-bottom: ($space_xs/2);
68
+
69
+ &.progress-empty-input {
70
+ visibility: hidden;
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,33 @@
1
+ import React, { useState } from 'react'
2
+ import { Body, Passphrase } from '../../'
3
+
4
+ const PassphraseCommon = (props) => {
5
+ const [input, setInput] = useState('')
6
+
7
+ const handleChange = (e) => setInput(e.target.value)
8
+
9
+ const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd']
10
+
11
+ const commonCheck = (passphrase) => {
12
+ if (COMMON_PASSPHRASES.includes(passphrase))
13
+ return true
14
+ return false
15
+ }
16
+
17
+ return (
18
+ <>
19
+ <div>
20
+ <Body text={`Try typing any of the following: ${COMMON_PASSPHRASES.join(' ')}`} />
21
+ <br />
22
+ <Passphrase
23
+ common={commonCheck(input)}
24
+ onChange={handleChange}
25
+ value={input}
26
+ {...props}
27
+ />
28
+ </div>
29
+ </>
30
+ )
31
+ }
32
+
33
+ export default PassphraseCommon
@@ -0,0 +1,3 @@
1
+ <%= pb_rails("passphrase") %>
2
+
3
+ <%= pb_rails("passphrase", props: { confirmation: true}) %>
@@ -0,0 +1,31 @@
1
+ import React, { useState } from 'react'
2
+ import { Passphrase } from '../../'
3
+
4
+ const PassphraseDefault = (props) => {
5
+ const [input, setInput] = useState('')
6
+ const handleChange = (e) => setInput(e.target.value)
7
+
8
+ const [confoInput, setConfoInput] = useState('')
9
+ const handleConfoChange = (e) => setConfoInput(e.target.value)
10
+
11
+ return (
12
+ <>
13
+ <div>
14
+ <Passphrase
15
+ onChange={handleChange}
16
+ value={input}
17
+ {...props}
18
+ />
19
+ <Passphrase
20
+ confirmation
21
+ onChange={handleConfoChange}
22
+ value={confoInput}
23
+ {...props}
24
+ />
25
+ <span>{input === confoInput ? 'They match!' : 'They don\'t match!'}</span>
26
+ </div>
27
+ </>
28
+ )
29
+ }
30
+
31
+ export default PassphraseDefault
@@ -0,0 +1 @@
1
+ Use the `confirmation` prop to only include the label and show/hide icon.
@@ -0,0 +1,16 @@
1
+ <%= pb_rails("passphrase", props: {
2
+ input_props: {
3
+ disabled: true,
4
+ id: "my-disabled-passphrase",
5
+ name: "my-disabled-field",
6
+ },
7
+ label: "Input props passed directly to input kit"
8
+ }) %>
9
+
10
+ <%= pb_rails("passphrase", props: {
11
+ input_props: {
12
+ id: "my-custome-id",
13
+ name: "my-value-name",
14
+ },
15
+ label: "Set name, id, etc for use in forms"
16
+ }) %>
@@ -0,0 +1,56 @@
1
+ import React, { useState } from 'react'
2
+ import { Passphrase } from '../../'
3
+
4
+ const PassphraseInputProps = (props) => {
5
+ const [input, setInput] = useState('')
6
+
7
+ const handleChange = (e) => setInput(e.target.value)
8
+
9
+ return (
10
+ <>
11
+ <div>
12
+ <Passphrase
13
+ inputProps={{
14
+ name: 'my-disabled-field',
15
+ id: 'my-value-id',
16
+ disabled: true,
17
+ }}
18
+ label="Pass props directly to input kit"
19
+ onChange={handleChange}
20
+ value={input}
21
+ {...props}
22
+ />
23
+ <Passphrase
24
+ inputProps={{
25
+ children: (
26
+ <input
27
+ onChange={handleChange}
28
+ type="password"
29
+ value={input}
30
+ />),
31
+ }}
32
+ label="Custom input"
33
+ onChange={handleChange}
34
+ value={input}
35
+ {...props}
36
+ />
37
+ <Passphrase
38
+ inputProps={{ name: 'my-value-name', id: 'my-value-id' }}
39
+ label="Set name and ID for use in form libraries"
40
+ onChange={handleChange}
41
+ value={input}
42
+ {...props}
43
+ />
44
+ <Passphrase
45
+ confirmation
46
+ inputProps={{ name: 'my-value-confirmation-name', id: 'my-value-confirmation-id' }}
47
+ onChange={handleChange}
48
+ value={input}
49
+ {...props}
50
+ />
51
+ </div>
52
+ </>
53
+ )
54
+ }
55
+
56
+ export default PassphraseInputProps