playbook_ui 9.10.0.pre.alpha1 → 9.12.0.pre.text.addon
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_button/_button.jsx +8 -19
- data/app/pb_kits/playbook/pb_button/button.rb +5 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_accessibility.html.erb +1 -1
- data/app/pb_kits/playbook/pb_button/docs/_button_accessibility.jsx +1 -1
- data/app/pb_kits/playbook/pb_button/docs/_button_link.html.erb +3 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_link.jsx +3 -0
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.html.erb +3 -3
- data/app/pb_kits/playbook/pb_button/docs/_button_loading.jsx +3 -0
- data/app/pb_kits/playbook/pb_passphrase/useZxcvbn.js +3 -3
- data/app/pb_kits/playbook/pb_table/docs/_table_side_highlight.md +1 -1
- data/app/pb_kits/playbook/pb_text_input/_text_input.jsx +80 -31
- data/app/pb_kits/playbook/pb_text_input/_text_input.scss +98 -0
- data/app/pb_kits/playbook/pb_text_input/add_on.html.erb +13 -0
- data/app/pb_kits/playbook/pb_text_input/add_on.rb +30 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_add_on.html.erb +24 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_add_on.jsx +82 -0
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_custom.html.erb +1 -1
- data/app/pb_kits/playbook/pb_text_input/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_text_input/docs/index.js +1 -0
- data/app/pb_kits/playbook/pb_text_input/text_input.html.erb +7 -16
- data/app/pb_kits/playbook/pb_text_input/text_input.rb +36 -2
- data/lib/playbook/props.rb +1 -0
- data/lib/playbook/props/nested_props.rb +23 -0
- data/lib/playbook/version.rb +1 -1
- metadata +24 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f94c4155e43cfcdf17c58b5afce6b032c570576aff59506dc1751cb4f0763010
|
4
|
+
data.tar.gz: 24b67df04fa47777d4c4f8ec6d43c648e61e7b1f2325c15acd4b125045d45012
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5bd3d916766662441b2e5ca737747554866e2ee519669bdb557da95faccab27a5dcaf1f28b8fa1764cdf5b5687f9972739323e2b97e8aa1bc3516893eb1e4a1
|
7
|
+
data.tar.gz: c4ae6e848dbea60dcc6e6b990579223d65c10fb6fc1b30ceb22769e3d4c95d24338b4086cde2464743db270be9330fc4950cc3b801d0671894e8dac87f1a25e5
|
@@ -2,16 +2,14 @@
|
|
2
2
|
|
3
3
|
import React from 'react'
|
4
4
|
import classnames from 'classnames'
|
5
|
-
import { buildDataProps } from '../utilities/props'
|
5
|
+
import { buildAriaProps, buildDataProps } from '../utilities/props'
|
6
6
|
import { globalProps } from '../utilities/globalProps.js'
|
7
7
|
|
8
8
|
import Icon from '../pb_icon/_icon.jsx'
|
9
9
|
|
10
10
|
type EventHandler = (SyntheticInputEvent<HTMLInputElement>) => void
|
11
11
|
type ButtonPropTypes = {
|
12
|
-
aria?:
|
13
|
-
label: string,
|
14
|
-
},
|
12
|
+
aria?: object,
|
15
13
|
children?: array<React.ReactChild>,
|
16
14
|
className?: string | array<string>,
|
17
15
|
data?: object,
|
@@ -55,20 +53,9 @@ const buttonClassName = (props: ButtonPropTypes) => {
|
|
55
53
|
return className
|
56
54
|
}
|
57
55
|
|
58
|
-
const buttonAriaProps = (props: ButtonPropTypes) => {
|
59
|
-
const { aria } = props
|
60
|
-
if (typeof aria !== 'object') return {}
|
61
|
-
const { label } = aria
|
62
|
-
|
63
|
-
const ariaProps = {}
|
64
|
-
|
65
|
-
if (label !== null) ariaProps['aria-label'] = label
|
66
|
-
|
67
|
-
return ariaProps
|
68
|
-
}
|
69
|
-
|
70
56
|
const Button = (props: ButtonPropTypes) => {
|
71
57
|
const {
|
58
|
+
aria = {},
|
72
59
|
children,
|
73
60
|
className,
|
74
61
|
data = {},
|
@@ -84,7 +71,7 @@ const Button = (props: ButtonPropTypes) => {
|
|
84
71
|
value,
|
85
72
|
} = props
|
86
73
|
|
87
|
-
const
|
74
|
+
const ariaProps = buildAriaProps(aria)
|
88
75
|
const dataProps = buildDataProps(data)
|
89
76
|
const css = classnames(
|
90
77
|
buttonClassName(props),
|
@@ -114,11 +101,12 @@ const Button = (props: ButtonPropTypes) => {
|
|
114
101
|
return (
|
115
102
|
<If condition={link !== null}>
|
116
103
|
<a
|
117
|
-
{...
|
104
|
+
{...ariaProps}
|
118
105
|
{...dataProps}
|
119
106
|
className={css}
|
120
107
|
href={link}
|
121
108
|
id={id}
|
109
|
+
role="link"
|
122
110
|
target={newWindow ? '_blank' : null}
|
123
111
|
>
|
124
112
|
<If condition={loading}>{loadingIcon}</If>
|
@@ -126,12 +114,13 @@ const Button = (props: ButtonPropTypes) => {
|
|
126
114
|
</a>
|
127
115
|
<Else />
|
128
116
|
<button
|
129
|
-
{...
|
117
|
+
{...ariaProps}
|
130
118
|
{...dataProps}
|
131
119
|
className={css}
|
132
120
|
disabled={disabled}
|
133
121
|
id={id}
|
134
122
|
onClick={onClick}
|
123
|
+
role="button"
|
135
124
|
type={htmlType}
|
136
125
|
value={value}
|
137
126
|
>
|
@@ -21,11 +21,12 @@ module Playbook
|
|
21
21
|
|
22
22
|
def options
|
23
23
|
{
|
24
|
-
|
25
|
-
data: data,
|
24
|
+
aria: aria,
|
26
25
|
class: classname,
|
26
|
+
data: data,
|
27
27
|
disabled: disabled,
|
28
|
-
|
28
|
+
id: id,
|
29
|
+
role: "button",
|
29
30
|
type: type,
|
30
31
|
value: value,
|
31
32
|
}.compact
|
@@ -34,6 +35,7 @@ module Playbook
|
|
34
35
|
def link_options
|
35
36
|
options.merge(
|
36
37
|
href: link,
|
38
|
+
role: "link",
|
37
39
|
target: new_window ? "_blank" : "_self"
|
38
40
|
)
|
39
41
|
end
|
@@ -1 +1 @@
|
|
1
|
-
<%= pb_rails("button", props: { text: "Button with ARIA", aria: {label: "
|
1
|
+
<%= pb_rails("button", props: { text: "Button with ARIA", aria: {label: "Go to Google"}, tag: "a", link: "http://google.com" }) %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= pb_rails("button", props: { text: "A Tag Button", tag: "a", link: "http://google.com" }) %>
|
2
|
-
<%= pb_rails("button", props: { text: "Open in new Window", new_window: true, link: "http://google.com" }) %>
|
3
|
-
<%= pb_rails("button", props: { text: "A Tag Button Disabled", disabled: true, link: "http://google.com" }) %>
|
1
|
+
<%= pb_rails("button", props: { text: "A Tag Button", aria: { label: "Link to Google" }, tag: "a", link: "http://google.com" }) %>
|
2
|
+
<%= pb_rails("button", props: { text: "Open in new Window", aria: { label: "Link to Google in new window" }, new_window: true, link: "http://google.com" }) %>
|
3
|
+
<%= pb_rails("button", props: { text: "A Tag Button Disabled", aria: { label: "Disabled link to Google" }, disabled: true, link: "http://google.com" }) %>
|
@@ -4,12 +4,14 @@ import { Button } from '../../'
|
|
4
4
|
const ButtonLink = (props) => (
|
5
5
|
<div>
|
6
6
|
<Button
|
7
|
+
aria={{ label: 'Link to Google' }}
|
7
8
|
link="https://google.com"
|
8
9
|
text="A Tag Button"
|
9
10
|
{...props}
|
10
11
|
/>
|
11
12
|
{' '}
|
12
13
|
<Button
|
14
|
+
aria={{ label: 'Link to Google in new window' }}
|
13
15
|
link="https://google.com"
|
14
16
|
newWindow
|
15
17
|
text="Open in New Window"
|
@@ -17,6 +19,7 @@ const ButtonLink = (props) => (
|
|
17
19
|
/>
|
18
20
|
{' '}
|
19
21
|
<Button
|
22
|
+
aria={{ label: 'Disabled link to Google' }}
|
20
23
|
disabled
|
21
24
|
link="https://google.com"
|
22
25
|
text="A Tag Button Disabled"
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= pb_rails("button", props: { text: "Button Primary", loading: true }) %>
|
2
|
-
<%= pb_rails("button", props: { text: "Button Primary", variant: "secondary", loading: true }) %>
|
3
|
-
<%= pb_rails("button", props: { text: "Button Primary", variant: "link", loading: true }) %>
|
1
|
+
<%= pb_rails("button", props: { aria: { label: "Loading" }, text: "Button Primary", loading: true }) %>
|
2
|
+
<%= pb_rails("button", props: { aria: { label: "Loading" }, text: "Button Primary", variant: "secondary", loading: true }) %>
|
3
|
+
<%= pb_rails("button", props: { aria: { label: "Loading" }, text: "Button Primary", variant: "link", loading: true }) %>
|
@@ -4,12 +4,14 @@ import { Button } from '../../'
|
|
4
4
|
const ButtonLoading = (props) => (
|
5
5
|
<div>
|
6
6
|
<Button
|
7
|
+
aria={{ label: 'Loading' }}
|
7
8
|
loading
|
8
9
|
text="Button Primary"
|
9
10
|
{...props}
|
10
11
|
/>
|
11
12
|
{' '}
|
12
13
|
<Button
|
14
|
+
aria={{ label: 'Loading' }}
|
13
15
|
loading
|
14
16
|
text="Button Secondary"
|
15
17
|
variant="secondary"
|
@@ -17,6 +19,7 @@ const ButtonLoading = (props) => (
|
|
17
19
|
/>
|
18
20
|
{' '}
|
19
21
|
<Button
|
22
|
+
aria={{ label: 'Loading' }}
|
20
23
|
loading
|
21
24
|
text="A Tag Button Disabled"
|
22
25
|
variant="link"
|
@@ -15,9 +15,9 @@ export default function useZxcvbn(options) {
|
|
15
15
|
|
16
16
|
useEffect(() => {
|
17
17
|
if (confirmation) return
|
18
|
-
|
19
|
-
setResult(
|
20
|
-
const str =
|
18
|
+
const newResult = calculator(passphrase)
|
19
|
+
setResult(newResult)
|
20
|
+
const str = newResult.score
|
21
21
|
|
22
22
|
const noPassphrase = passphrase.length <= 0
|
23
23
|
const commonPassphrase = common || isPwned
|
@@ -1,3 +1,3 @@
|
|
1
|
-
Side highlight can take product, status, and category colors. To view full list of colors, visit <a href="https://playbook.powerapp.cloud/
|
1
|
+
Side highlight can take product, status, and category colors. To view full list of colors, visit <a href="https://playbook.powerapp.cloud/visual_guidelines" target="_blank">token colors</a>.
|
2
2
|
|
3
3
|
Note: Only use category colors for categories. Do not mix it with product or status colors.
|
@@ -1,13 +1,10 @@
|
|
1
1
|
/* @flow */
|
2
2
|
import React, { forwardRef } from 'react'
|
3
3
|
import classnames from 'classnames'
|
4
|
-
import { Body, Caption } from '../'
|
4
|
+
import { Body, Caption, Card, Flex, Icon } from '../'
|
5
5
|
import { globalProps } from '../utilities/globalProps.js'
|
6
6
|
|
7
|
-
import {
|
8
|
-
buildAriaProps,
|
9
|
-
buildDataProps,
|
10
|
-
} from '../utilities/props'
|
7
|
+
import { buildAriaProps, buildDataProps } from '../utilities/props'
|
11
8
|
|
12
9
|
type TextInputProps = {
|
13
10
|
aria?: object,
|
@@ -25,12 +22,14 @@ type TextInputProps = {
|
|
25
22
|
type: string,
|
26
23
|
value: string | number,
|
27
24
|
children: Node,
|
25
|
+
addOn?: {
|
26
|
+
icon?: string,
|
27
|
+
alignment?: "right" | "left",
|
28
|
+
border?: boolean,
|
29
|
+
},
|
28
30
|
}
|
29
31
|
|
30
|
-
const TextInput = (
|
31
|
-
props: TextInputProps,
|
32
|
-
ref: React.ElementRef<"input">
|
33
|
-
) => {
|
32
|
+
const TextInput = (props: TextInputProps, ref: React.ElementRef<"input">) => {
|
34
33
|
const {
|
35
34
|
aria = {},
|
36
35
|
className,
|
@@ -47,16 +46,78 @@ const TextInput = (
|
|
47
46
|
type = 'text',
|
48
47
|
value = '',
|
49
48
|
children = null,
|
49
|
+
addOn = { icon: null, alignment: 'right', border: true },
|
50
50
|
} = props
|
51
51
|
|
52
52
|
const ariaProps = buildAriaProps(aria)
|
53
53
|
const dataProps = buildDataProps(data)
|
54
|
+
|
55
|
+
const { alignment, border, icon } = addOn
|
56
|
+
const addOnAlignment = alignment === 'left' ? 'left' : 'right'
|
57
|
+
const borderToChange = addOnAlignment === 'left' ? 'right' : 'left'
|
58
|
+
const borderToggle = border === false ? 'off' : 'on'
|
59
|
+
const borderCss = `border_${borderToChange}_${borderToggle}`
|
60
|
+
|
61
|
+
const shouldShowAddOn = icon !== null
|
62
|
+
const addOnCss = shouldShowAddOn ? 'text_input_wrapper_add_on' : null
|
63
|
+
const addOnDarkModeCardCss = (shouldShowAddOn && dark) ? 'add-on-card-dark' : null
|
54
64
|
const css = classnames([
|
55
65
|
'pb_text_input_kit',
|
56
66
|
error ? 'error' : null,
|
57
67
|
globalProps(props),
|
58
68
|
className,
|
59
69
|
])
|
70
|
+
const addOnIcon = (
|
71
|
+
<Icon
|
72
|
+
className="add-on-icon"
|
73
|
+
dark={dark}
|
74
|
+
fixedWidth={false}
|
75
|
+
icon={icon}
|
76
|
+
/>
|
77
|
+
)
|
78
|
+
const textInput = (
|
79
|
+
<input
|
80
|
+
{...props}
|
81
|
+
className="text_input"
|
82
|
+
disabled={disabled}
|
83
|
+
id={id}
|
84
|
+
name={name}
|
85
|
+
onChange={onChange}
|
86
|
+
placeholder={placeholder}
|
87
|
+
ref={ref}
|
88
|
+
required={required}
|
89
|
+
type={type}
|
90
|
+
value={value}
|
91
|
+
/>
|
92
|
+
)
|
93
|
+
|
94
|
+
const addOnInput = (
|
95
|
+
<React.Fragment>
|
96
|
+
<Flex
|
97
|
+
className={`add-on-${addOnAlignment} ${borderCss}`}
|
98
|
+
inline="flex-container"
|
99
|
+
vertical="center"
|
100
|
+
>
|
101
|
+
<If condition={addOnAlignment == 'left'}>
|
102
|
+
<Card
|
103
|
+
className={`${addOnDarkModeCardCss} add-on-card card-left-aligned`}
|
104
|
+
dark={dark}
|
105
|
+
>
|
106
|
+
{addOnIcon}
|
107
|
+
</Card>
|
108
|
+
{textInput}
|
109
|
+
<Else />
|
110
|
+
{textInput}
|
111
|
+
<Card
|
112
|
+
className={`${addOnDarkModeCardCss} add-on-card card-right-aligned`}
|
113
|
+
dark={dark}
|
114
|
+
>
|
115
|
+
{addOnIcon}
|
116
|
+
</Card>
|
117
|
+
</If>
|
118
|
+
</Flex>
|
119
|
+
</React.Fragment>
|
120
|
+
)
|
60
121
|
|
61
122
|
return (
|
62
123
|
<div
|
@@ -69,29 +130,17 @@ const TextInput = (
|
|
69
130
|
dark={dark}
|
70
131
|
text={label}
|
71
132
|
/>
|
72
|
-
<div className=
|
73
|
-
<
|
74
|
-
{children}
|
75
|
-
<
|
76
|
-
<
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
onChange={onChange}
|
83
|
-
placeholder={placeholder}
|
84
|
-
ref={ref}
|
85
|
-
required={required}
|
86
|
-
type={type}
|
87
|
-
value={value}
|
133
|
+
<div className={`${addOnCss} text_input_wrapper`}>
|
134
|
+
<Choose>
|
135
|
+
<When condition={children}>{children}</When>
|
136
|
+
<When condition={shouldShowAddOn}>{addOnInput}</When>
|
137
|
+
<Otherwise>{textInput}</Otherwise>
|
138
|
+
</Choose>
|
139
|
+
<If condition={error}>
|
140
|
+
<Body
|
141
|
+
status="negative"
|
142
|
+
text={error}
|
88
143
|
/>
|
89
|
-
<If condition={error}>
|
90
|
-
<Body
|
91
|
-
status="negative"
|
92
|
-
text={error}
|
93
|
-
/>
|
94
|
-
</If>
|
95
144
|
</If>
|
96
145
|
</div>
|
97
146
|
</div>
|
@@ -36,6 +36,16 @@
|
|
36
36
|
}
|
37
37
|
}
|
38
38
|
&.dark {
|
39
|
+
.add_on_left {
|
40
|
+
.text_input {
|
41
|
+
border-left: 0;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
.add_on_right {
|
45
|
+
.text_input {
|
46
|
+
border-right: 0;
|
47
|
+
}
|
48
|
+
}
|
39
49
|
.text_input_wrapper {
|
40
50
|
margin-bottom: 1rem;
|
41
51
|
input::placeholder,
|
@@ -80,3 +90,91 @@
|
|
80
90
|
}
|
81
91
|
}
|
82
92
|
}
|
93
|
+
|
94
|
+
.text_input_wrapper_add_on {
|
95
|
+
& > [class^=pb_text_input_kit]:not(:last-child) {
|
96
|
+
.text_input_wrapper_add_on input, [class^=pb_text_input_kit] .text_input_wrapper_add_on .text_input {
|
97
|
+
border-bottom-right-radius: 0;
|
98
|
+
border-top-right-radius: 0;
|
99
|
+
border-right-width: 0;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
.section-separator span {
|
103
|
+
padding: 0;
|
104
|
+
}
|
105
|
+
|
106
|
+
.add-on {
|
107
|
+
&-card {
|
108
|
+
height: 45px;
|
109
|
+
margin: 0;
|
110
|
+
padding: 0 !important;
|
111
|
+
align-items: center;
|
112
|
+
justify-content: center;
|
113
|
+
width: 45px;
|
114
|
+
}
|
115
|
+
&-icon {
|
116
|
+
color: $text_lt_lighter;
|
117
|
+
}
|
118
|
+
&-card-dark {
|
119
|
+
background-color: $bg-dark;
|
120
|
+
}
|
121
|
+
&-left {
|
122
|
+
.text_input {
|
123
|
+
border-top-left-radius: 0 !important;
|
124
|
+
border-bottom-left-radius: 0 !important;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
&-right {
|
129
|
+
.text_input{
|
130
|
+
border-top-right-radius: 0 !important;
|
131
|
+
border-bottom-right-radius: 0 !important;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
}
|
135
|
+
.text_input:focus ~ .add-on-card-dark {
|
136
|
+
background-color: $focus_input_dark;
|
137
|
+
border-width: 0px;
|
138
|
+
}
|
139
|
+
|
140
|
+
.card-left-aligned {
|
141
|
+
border-top-right-radius: 0 !important;
|
142
|
+
border-bottom-right-radius: 0 !important;
|
143
|
+
}
|
144
|
+
|
145
|
+
.card-right-aligned {
|
146
|
+
border-top-left-radius: 0 !important;
|
147
|
+
border-bottom-left-radius: 0 !important;
|
148
|
+
}
|
149
|
+
|
150
|
+
.border {
|
151
|
+
&_right_off {
|
152
|
+
.card-left-aligned {
|
153
|
+
border-right: 0;
|
154
|
+
}
|
155
|
+
.text_input {
|
156
|
+
border-left: 0 !important;
|
157
|
+
padding-left: 0 !important;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
&_left_on {
|
161
|
+
.card-right-aligned {
|
162
|
+
border-left: 0;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
&_right_on {
|
166
|
+
.card-left-aligned {
|
167
|
+
border-right: 0;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
&_left_off {
|
171
|
+
.card-right-aligned {
|
172
|
+
border-left: 0;
|
173
|
+
}
|
174
|
+
.text_input {
|
175
|
+
border-right: 0 !important;
|
176
|
+
padding-right: 0 !important;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= pb_rails("flex", props: { classname: "add-on-#{alignment} #{border_css}", vertical: "center"}) do %>
|
2
|
+
<% if left_aligned? %>
|
3
|
+
<%= pb_rails("card", props: {classname: "#{dark_mode_css} add-on-card card-left-aligned", dark: dark}) do %>
|
4
|
+
<%= pb_rails("icon", props: { icon: icon, classname: "add-on-icon", fixed_width: false, dark: dark }) %>
|
5
|
+
<% end %>
|
6
|
+
<%= content %>
|
7
|
+
<% else %>
|
8
|
+
<%= content %>
|
9
|
+
<%= pb_rails("card", props: {classname: "#{dark_mode_css} add-on-card card-right-aligned", dark: dark}) do %>
|
10
|
+
<%= pb_rails("icon", props: { icon: icon, classname: "add-on-icon", fixed_width: false, dark: dark }) %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module PbTextInput
|
5
|
+
class AddOn < Playbook::KitBase
|
6
|
+
prop :icon, type: Playbook::Props::String, required: true
|
7
|
+
prop :alignment, type: Playbook::Props::Enum, values: %w[right left], default: "right"
|
8
|
+
prop :border, type: Playbook::Props::Boolean, default: true
|
9
|
+
|
10
|
+
def border_css
|
11
|
+
border_toggle = border ? "on" : "off"
|
12
|
+
border_to_change = if alignment == "left"
|
13
|
+
"right"
|
14
|
+
else
|
15
|
+
"left"
|
16
|
+
end
|
17
|
+
|
18
|
+
"border_#{border_to_change}_#{border_toggle}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def left_aligned?
|
22
|
+
alignment == "left"
|
23
|
+
end
|
24
|
+
|
25
|
+
def dark_mode_css
|
26
|
+
dark ? "add-on-card-dark" : nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= pb_rails("text_input", props: {
|
2
|
+
label: "Add On With Defaults",
|
3
|
+
add_on: { icon: "bat" }
|
4
|
+
}) %>
|
5
|
+
|
6
|
+
<%= pb_rails("text_input", props: {
|
7
|
+
label: "Right-Aligned Add On With Border",
|
8
|
+
add_on: { icon: "user", alignment: 'right', border: true }
|
9
|
+
}) %>
|
10
|
+
|
11
|
+
<%= pb_rails("text_input", props: {
|
12
|
+
label: "Left-Aligned Add On With No Border",
|
13
|
+
add_on: { icon: "percent", alignment: 'left', border: false }
|
14
|
+
}) %>
|
15
|
+
|
16
|
+
<%= pb_rails("text_input", props: {
|
17
|
+
label: "Left-Aligned Add On With Border",
|
18
|
+
add_on: { icon: "user", alignment: 'left', border: true }
|
19
|
+
}) %>
|
20
|
+
|
21
|
+
<%= pb_rails("text_input", props: {
|
22
|
+
label: "Right-Aligned Add On With No Border",
|
23
|
+
add_on: { icon: "percent", alignment: 'right', border: false }
|
24
|
+
}) %>
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import React, { useState } from 'react'
|
2
|
+
import { TextInput } from '../../'
|
3
|
+
|
4
|
+
const TextInputAddOn = (props) => {
|
5
|
+
const [defaultInput, setDefaultInput] = useState('')
|
6
|
+
const [firstInput, setFirstInput] = useState('')
|
7
|
+
const [secondInput, setSecondInput] = useState('')
|
8
|
+
const [thirdInput, setThirdInput] = useState('')
|
9
|
+
const [fourthInput, setFourthInput] = useState('')
|
10
|
+
|
11
|
+
const handleUpdateDefaultInput = ({ target }) => {
|
12
|
+
setDefaultInput(target.value)
|
13
|
+
}
|
14
|
+
|
15
|
+
const handleUpdateFirstInput = ({ target }) => {
|
16
|
+
setFirstInput(target.value)
|
17
|
+
}
|
18
|
+
|
19
|
+
const handleUpdateSecondInput = ({ target }) => {
|
20
|
+
setSecondInput(target.value)
|
21
|
+
}
|
22
|
+
|
23
|
+
const handleUpdateThirdInput = ({ target }) => {
|
24
|
+
setThirdInput(target.value)
|
25
|
+
}
|
26
|
+
|
27
|
+
const handleUpdateFourthInput = ({ target }) => {
|
28
|
+
setFourthInput(target.value)
|
29
|
+
}
|
30
|
+
|
31
|
+
return (
|
32
|
+
<>
|
33
|
+
<div>
|
34
|
+
<TextInput
|
35
|
+
addOn={{ icon: 'bat' }}
|
36
|
+
label="Add On With Defaults"
|
37
|
+
onChange={handleUpdateDefaultInput}
|
38
|
+
value={defaultInput}
|
39
|
+
{...props}
|
40
|
+
/>
|
41
|
+
</div>
|
42
|
+
<div>
|
43
|
+
<TextInput
|
44
|
+
addOn={{ icon: 'user', alignment: 'right', border: true }}
|
45
|
+
label="Right-Aligned Add On With Border"
|
46
|
+
onChange={handleUpdateFirstInput}
|
47
|
+
value={firstInput}
|
48
|
+
{...props}
|
49
|
+
/>
|
50
|
+
</div>
|
51
|
+
<div>
|
52
|
+
<TextInput
|
53
|
+
addOn={{ icon: 'percent', alignment: 'left', border: false }}
|
54
|
+
label="Left-Aligned Add On With No Border"
|
55
|
+
onChange={handleUpdateSecondInput}
|
56
|
+
value={secondInput}
|
57
|
+
{...props}
|
58
|
+
/>
|
59
|
+
</div>
|
60
|
+
<div>
|
61
|
+
<TextInput
|
62
|
+
addOn={{ icon: 'percent', alignment: 'right', border: false }}
|
63
|
+
label="Right-Aligned Add On With No Border"
|
64
|
+
onChange={handleUpdateThirdInput}
|
65
|
+
value={thirdInput}
|
66
|
+
{...props}
|
67
|
+
/>
|
68
|
+
</div>
|
69
|
+
<div>
|
70
|
+
<TextInput
|
71
|
+
addOn={{ icon: 'percent', alignment: 'left', border: true }}
|
72
|
+
label="Left-Aligned Add On With Border"
|
73
|
+
onChange={handleUpdateFourthInput}
|
74
|
+
value={fourthInput}
|
75
|
+
{...props}
|
76
|
+
/>
|
77
|
+
</div>
|
78
|
+
</>
|
79
|
+
)
|
80
|
+
}
|
81
|
+
|
82
|
+
export default TextInputAddOn
|
@@ -4,8 +4,10 @@ examples:
|
|
4
4
|
- text_input_error: With Error
|
5
5
|
- text_input_custom: Custom
|
6
6
|
- text_input_disabled: Disabled
|
7
|
+
- text_input_add_on: Add On
|
7
8
|
react:
|
8
9
|
- text_input_default: Default
|
9
10
|
- text_input_error: With Error
|
10
11
|
- text_input_custom: Custom
|
11
12
|
- text_input_disabled: Disabled
|
13
|
+
- text_input_add_on: Add On
|
@@ -2,3 +2,4 @@ export { default as TextInputDefault } from './_text_input_default.jsx'
|
|
2
2
|
export { default as TextInputCustom } from './_text_input_custom.jsx'
|
3
3
|
export { default as TextInputError } from './_text_input_error.jsx'
|
4
4
|
export { default as TextInputDisabled } from './_text_input_disabled.jsx'
|
5
|
+
export { default as TextInputAddOn } from './_text_input_add_on.jsx'
|
@@ -5,25 +5,16 @@
|
|
5
5
|
<% if object.label.present? %>
|
6
6
|
<%= pb_rails("caption", props: { text: object.label, dark: object.dark, classname: "pb_text_input_kit_label" }) %>
|
7
7
|
<% end %>
|
8
|
-
<%= content_tag(:div, class: "text_input_wrapper") do %>
|
8
|
+
<%= content_tag(:div, class: "#{add_on_class} text_input_wrapper") do %>
|
9
9
|
<% if content.present? %>
|
10
10
|
<%= content %>
|
11
|
+
<% elsif has_add_on? %>
|
12
|
+
<%= pb_rails("text_input/add_on", props: object.add_on_props) do %>
|
13
|
+
<%= input_tag %>
|
14
|
+
<% end %>
|
11
15
|
<% else %>
|
12
|
-
<%=
|
13
|
-
autocomplete: object.autocomplete ? nil : "off",
|
14
|
-
class: "text_input",
|
15
|
-
data: object.validation_data,
|
16
|
-
disabled: object.disabled,
|
17
|
-
id: object.id,
|
18
|
-
name: object.name,
|
19
|
-
pattern: object.validation_pattern,
|
20
|
-
placeholder: object.placeholder,
|
21
|
-
required: object.required,
|
22
|
-
type: object.type,
|
23
|
-
value: object.value) %>
|
24
|
-
<% end %>
|
25
|
-
<% if object.error %>
|
26
|
-
<%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error}) %>
|
16
|
+
<%= input_tag %>
|
27
17
|
<% end %>
|
18
|
+
<%= pb_rails("body", props: {dark: object.dark, status: "negative", text: object.error}) if object.error %>
|
28
19
|
<% end %>
|
29
20
|
<% end %>
|
@@ -17,11 +17,47 @@ module Playbook
|
|
17
17
|
prop :validation, type: Playbook::Props::Hash,
|
18
18
|
default: {}
|
19
19
|
prop :value
|
20
|
+
prop :add_on, type: Playbook::Props::NestedProps,
|
21
|
+
nested_kit: Playbook::PbTextInput::AddOn
|
20
22
|
|
21
23
|
def classname
|
22
24
|
generate_classname("pb_text_input_kit") + error_class
|
23
25
|
end
|
24
26
|
|
27
|
+
def input_tag
|
28
|
+
tag(:input, input_options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_add_on?
|
32
|
+
add_on.present?
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_on_class
|
36
|
+
has_add_on? ? 'text_input_wrapper_add_on' : nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_on_props
|
40
|
+
{ dark: dark }.merge(add_on || {})
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def input_options
|
46
|
+
{
|
47
|
+
autocomplete: autocomplete ? nil : "off",
|
48
|
+
class: "text_input",
|
49
|
+
data: validation_data,
|
50
|
+
disabled: disabled,
|
51
|
+
id: id,
|
52
|
+
name: name,
|
53
|
+
pattern: validation_pattern,
|
54
|
+
placeholder: placeholder,
|
55
|
+
required: required,
|
56
|
+
type: type,
|
57
|
+
value: value
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
25
61
|
def validation_message
|
26
62
|
validation[:message] || ""
|
27
63
|
end
|
@@ -36,8 +72,6 @@ module Playbook
|
|
36
72
|
fields
|
37
73
|
end
|
38
74
|
|
39
|
-
private
|
40
|
-
|
41
75
|
def error_class
|
42
76
|
error ? " error" : ""
|
43
77
|
end
|
data/lib/playbook/props.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Playbook
|
4
|
+
module Props
|
5
|
+
class NestedProps < Playbook::Props::Base
|
6
|
+
def initialize(nested_kit:, **kwargs)
|
7
|
+
super **kwargs
|
8
|
+
@nested_kit = nested_kit
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate(values)
|
12
|
+
return true if values.nil?
|
13
|
+
|
14
|
+
@nested_kit.props.each do |prop_key, definition|
|
15
|
+
definition.validate! definition.value(values[prop_key])
|
16
|
+
end
|
17
|
+
true
|
18
|
+
rescue Playbook::Props::Error
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/playbook/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playbook_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.
|
4
|
+
version: 9.12.0.pre.text.addon
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Power UX
|
8
8
|
- Power Devs
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-05-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -17,7 +17,7 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 5.2.4.
|
20
|
+
version: 5.2.4.5
|
21
21
|
- - "<"
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: '7.0'
|
@@ -27,7 +27,7 @@ dependencies:
|
|
27
27
|
requirements:
|
28
28
|
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
|
-
version: 5.2.4.
|
30
|
+
version: 5.2.4.5
|
31
31
|
- - "<"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '7.0'
|
@@ -37,7 +37,7 @@ dependencies:
|
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 5.2.4.
|
40
|
+
version: 5.2.4.5
|
41
41
|
- - "<"
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '7.0'
|
@@ -47,7 +47,7 @@ dependencies:
|
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 5.2.4.
|
50
|
+
version: 5.2.4.5
|
51
51
|
- - "<"
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '7.0'
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 5.2.4.
|
60
|
+
version: 5.2.4.5
|
61
61
|
- - "<"
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: '7.0'
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
requirements:
|
68
68
|
- - ">="
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 5.2.4.
|
70
|
+
version: 5.2.4.5
|
71
71
|
- - "<"
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '7.0'
|
@@ -299,22 +299,22 @@ dependencies:
|
|
299
299
|
name: rspec-rails
|
300
300
|
requirement: !ruby/object:Gem::Requirement
|
301
301
|
requirements:
|
302
|
-
- - ">="
|
303
|
-
- !ruby/object:Gem::Version
|
304
|
-
version: 3.8.0
|
305
302
|
- - "~>"
|
306
303
|
- !ruby/object:Gem::Version
|
307
304
|
version: '3.8'
|
305
|
+
- - ">="
|
306
|
+
- !ruby/object:Gem::Version
|
307
|
+
version: 3.8.0
|
308
308
|
type: :development
|
309
309
|
prerelease: false
|
310
310
|
version_requirements: !ruby/object:Gem::Requirement
|
311
311
|
requirements:
|
312
|
-
- - ">="
|
313
|
-
- !ruby/object:Gem::Version
|
314
|
-
version: 3.8.0
|
315
312
|
- - "~>"
|
316
313
|
- !ruby/object:Gem::Version
|
317
314
|
version: '3.8'
|
315
|
+
- - ">="
|
316
|
+
- !ruby/object:Gem::Version
|
317
|
+
version: 3.8.0
|
318
318
|
- !ruby/object:Gem::Dependency
|
319
319
|
name: rubocop
|
320
320
|
requirement: !ruby/object:Gem::Requirement
|
@@ -1792,8 +1792,12 @@ files:
|
|
1792
1792
|
- app/pb_kits/playbook/pb_table/table_row.rb
|
1793
1793
|
- app/pb_kits/playbook/pb_text_input/_text_input.jsx
|
1794
1794
|
- app/pb_kits/playbook/pb_text_input/_text_input.scss
|
1795
|
+
- app/pb_kits/playbook/pb_text_input/add_on.html.erb
|
1796
|
+
- app/pb_kits/playbook/pb_text_input/add_on.rb
|
1795
1797
|
- app/pb_kits/playbook/pb_text_input/docs/_description.md
|
1796
1798
|
- app/pb_kits/playbook/pb_text_input/docs/_footer.md
|
1799
|
+
- app/pb_kits/playbook/pb_text_input/docs/_text_input_add_on.html.erb
|
1800
|
+
- app/pb_kits/playbook/pb_text_input/docs/_text_input_add_on.jsx
|
1797
1801
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_custom.html.erb
|
1798
1802
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_custom.jsx
|
1799
1803
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_default.html.erb
|
@@ -2109,6 +2113,7 @@ files:
|
|
2109
2113
|
- lib/playbook/props/enum.rb
|
2110
2114
|
- lib/playbook/props/hash.rb
|
2111
2115
|
- lib/playbook/props/hash_array.rb
|
2116
|
+
- lib/playbook/props/nested_props.rb
|
2112
2117
|
- lib/playbook/props/number.rb
|
2113
2118
|
- lib/playbook/props/number_array.rb
|
2114
2119
|
- lib/playbook/props/numeric.rb
|
@@ -2123,7 +2128,7 @@ homepage: http://playbook.powerapp.cloud
|
|
2123
2128
|
licenses:
|
2124
2129
|
- MIT
|
2125
2130
|
metadata: {}
|
2126
|
-
post_install_message:
|
2131
|
+
post_install_message:
|
2127
2132
|
rdoc_options: []
|
2128
2133
|
require_paths:
|
2129
2134
|
- lib
|
@@ -2138,8 +2143,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
2138
2143
|
- !ruby/object:Gem::Version
|
2139
2144
|
version: 1.3.1
|
2140
2145
|
requirements: []
|
2141
|
-
|
2142
|
-
|
2146
|
+
rubyforge_project:
|
2147
|
+
rubygems_version: 2.7.3
|
2148
|
+
signing_key:
|
2143
2149
|
specification_version: 4
|
2144
2150
|
summary: Playbook Design System
|
2145
2151
|
test_files: []
|