<%= pb_rails("passphrase", props: { classname: "pass_input_1" }) %> <%= pb_rails("passphrase", props: { confirmation: true, classname: "pass_input_2"}) %> <div id="match"> </div> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { const useState = (defaultValue) => { let value = defaultValue; const getValue = () => value const setValue = (newValue) => { return value = newValue } return [getValue, setValue]; } const [input, setInput] = useState('') const [confirmationInput, setConfirmationInput] = useState('') const match = document.querySelector("#match") const input1 = document.querySelector(".pass_input_1").querySelector("input") const input2 = document.querySelector(".pass_input_2").querySelector("input") input1.addEventListener('input', (e) => { setInput(e.target.value) setMatchText() }); input2.addEventListener('input', (e) => { setConfirmationInput(e.target.value) setMatchText() }); const setMatchText = () => { if (input() && confirmationInput()) { if (input() === confirmationInput()) { match.textContent = "They match!" } else { match.textContent = "They don't match!" } } else { match.textContent = "" } } }) <% end %>
This example shows how to enhance the passphrase strenght by setting diferent thresholds and lengths.
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.
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.
Adjust these props to tune the sensitivity of the bar.
Note: minimum length trumps strength and will set the bar to a red color, despite whatever strength is calculated.
This example depends on the zxcvbn
library.
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.
<%= pb_rails("passphrase", props: { label: "Default Settings", classname: "def_passphrase" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "def_bar" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "def_caption" }) %> <%= pb_rails("text_input", props: { label: "Calculated Strength", value: "0", disabled: true, id: "calc_strength" }) %> <%= pb_rails("passphrase", props: { label: "Min length = 5", classname: "min_5" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "min_5_bar" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_5_caption" }) %> <%= pb_rails("passphrase", props: { label: "Min length = 30", classname: "min_30" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "min_30_bar" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "min_30_caption" }) %> <%= pb_rails("passphrase", props: { label: "Average Threshold = 1", classname: "avg_1" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "avg_1_bar" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "avg_1_caption" }) %> <%= pb_rails("passphrase", props: { label: "Strong Threshold = 4", classname: "strong_4" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "strong_4_bar" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "strong_4_caption" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { // variables for the passphrase kits you are targeting const defPassphrase = document.querySelector(".def_passphrase").querySelector("input") const min5 = document.querySelector(".min_5").querySelector("input") const min30 = document.querySelector(".min_30").querySelector("input") const avg1 = document.querySelector(".avg_1").querySelector("input") const strong4 = document.querySelector(".strong_4").querySelector("input") // variable for the text_input kit you are targeting const calcStrength = document.querySelector("#calc_strength") // variables for the progress_simple kits you are targeting const defBarVariant = document.getElementById("def_bar") const defBarPercent = document.getElementById("def_bar").querySelector("div") const min5BarVariant = document.getElementById("min_5_bar") const min5BarPercent = document.getElementById("min_5_bar").querySelector("div") const min30BarVariant = document.getElementById("min_30_bar") const min30BarPercent = document.getElementById("min_30_bar").querySelector("div") const avg1BarVariant = document.getElementById("avg_1_bar") const avg1BarPercent = document.getElementById("avg_1_bar").querySelector("div") const strong4BarVariant = document.getElementById("strong_4_bar") const strong4BarPercent = document.getElementById("strong_4_bar").querySelector("div") // hide all the progress_simple bars defBarVariant.style.display = 'none'; defBarPercent.style.display = 'none'; min5BarVariant.style.display = 'none'; min5BarPercent.style.display = 'none'; min30BarVariant.style.display = 'none'; min30BarPercent.style.display = 'none'; avg1BarVariant.style.display = 'none'; avg1BarPercent.style.display = 'none'; strong4BarVariant.style.display = 'none'; strong4BarPercent.style.display = 'none'; // variables for the caption kits you are targeting const defCaption = document.getElementById("def_caption") const min5Caption = document.getElementById("min_5_caption") const min30Caption = document.getElementById("min_30_caption") const avg1Caption = document.getElementById("avg_1_caption") const strong4Caption = document.getElementById("strong_4_caption") // hide all the captions defCaption.style.display = 'none'; min5Caption.style.display = 'none'; min30Caption.style.display = 'none'; avg1Caption.style.display = 'none'; strong4Caption.style.display = 'none'; // funtion that determines strenght of user passowrd using zxcvbn const handleStrengthCalculation = (settings) => { // define the settings object with its defaults const { passphrase = "", common = false, isPwned = false, averageThreshold = 2, minLength = 12, strongThreshold = 3, } = settings // define the resultsByScore objects, these return an object with a variant and percentage, // depending on the score of the password const resultByScore = { 0: { variant: 'negative', label: '', percent: 0, }, 1: { variant: 'negative', label: 'This passphrase is too common', percent: 25, }, 2: { variant: 'negative', label: 'Too weak', percent: 25, }, 3: { variant: 'warning', label: 'Almost there, keep going!', percent: 50, }, 4: { variant: 'positive', label: 'Success! Strong passphrase', percent: 100, } } const { score } = zxcvbn(passphrase); const noPassphrase = passphrase.length <= 0 const commonPassphrase = common || isPwned const weakPassphrase = passphrase.length < minLength || score < averageThreshold const averagePassphrase = score < strongThreshold const strongPassphrase = score >= strongThreshold // conditional that returns the score of the password, along with the resultByScore object // so we can change the percantage and variant of the progress_simple kit if (noPassphrase) { return {...resultByScore[0], score} } else if (commonPassphrase) { return {...resultByScore[1], score} } else if (weakPassphrase) { return {...resultByScore[2], score} } else if (averagePassphrase){ return {...resultByScore[3], score} } else if (strongPassphrase) { return {...resultByScore[4], score} } } // event listeners attached to the input field min5.addEventListener('input', (e) => { const passphrase = e.target.value; // defining setting object to spread into handleStrengthCalculation setting = { minLength: 5, } // pass in passphrase and setting object to handleStrengthCalculation and set that equal to result variable const result = handleStrengthCalculation({passphrase, ...setting}) // set the value of the text_input to the score calcStrength.value = result.score // conditional statment to show or hide progress_simple bar and caption if user has entered a password if (passphrase) { min5BarVariant.style.display = 'block'; min5BarPercent.style.display = 'block'; min5Caption.style.display = 'block'; } else { min5BarVariant.style.display = 'none'; min5BarPercent.style.display = 'none'; min5Caption.style.display = 'none'; } // set the width of the progress_simple kit min5BarPercent.style.width = result.percent.toString()+ "%" // set the variant of the progress_simple kit min5BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); // set the text of the caption kit min5Caption.textContent = result.label }); defPassphrase.addEventListener('input', (e) => { const passphrase = e.target.value; const result = handleStrengthCalculation({passphrase}) calcStrength.value = result.score if (passphrase) { defBarVariant.style.display = 'block'; defBarPercent.style.display = 'block'; defCaption.style.display = 'block'; } else { defBarVariant.style.display = 'none'; defBarPercent.style.display = 'none'; defCaption.style.display = 'none'; } defBarPercent.style.width = result.percent.toString()+ "%" defBarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); defCaption.textContent = result.label }); min30.addEventListener('input', (e) => { const passphrase = e.target.value; setting = { minLength: 30, } const result = handleStrengthCalculation({passphrase, ...setting}) calcStrength.value = result.score if (passphrase) { min30BarVariant.style.display = 'block'; min30BarPercent.style.display = 'block'; min30Caption.style.display = 'block'; } else { min30BarVariant.style.display = 'none'; min30BarPercent.style.display = 'none'; min30Caption.style.display = 'none'; } min30BarPercent.style.width = result.percent.toString()+ "%" min30BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); min30Caption.textContent = result.label }); avg1.addEventListener('input', (e) => { const passphrase = e.target.value; setting = { averageThreshold: 1, } const result = handleStrengthCalculation({passphrase, ...setting}) calcStrength.value = result.score if (passphrase) { avg1BarVariant.style.display = 'block'; avg1BarPercent.style.display = 'block'; avg1Caption.style.display = 'block'; } else { avg1BarVariant.style.display = 'none'; avg1BarPercent.style.display = 'none'; avg1Caption.style.display = 'none'; } avg1BarPercent.style.width = result.percent.toString()+ "%" avg1BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); avg1Caption.textContent = result.label }); strong4.addEventListener('input', (e) => { const passphrase = e.target.value; setting = { strongThreshold: 4, } const result = handleStrengthCalculation({passphrase, ...setting}) calcStrength.value = result.score if (passphrase) { strong4BarVariant.style.display = 'block'; strong4BarPercent.style.display = 'block'; strong4Caption.style.display = 'block'; } else { strong4BarVariant.style.display = 'none'; strong4BarPercent.style.display = 'none'; strong4Caption.style.display = 'none'; } strong4BarPercent.style.width = result.percent.toString()+ "%" strong4BarVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); strong4Caption.textContent = result.label }); }) <% end %>
inputProps
is passed directly to an underlying Text Input kit. See the specific docs here for more details.
<%= pb_rails("passphrase", props: { input_props: { disabled: true, id: "my-disabled-passphrase", name: "my-disabled-field", }, label: "Pass props directly to input kit" }) %> <%= pb_rails("passphrase", props: { input_props: { id: "my-custome-id", name: "my-value-name", }, label: "Set name and ID for use in form libraries" }) %>
showTipsBelow
(react) / show_tips_below
(rails) takes 'xs', 'sm', 'md', 'lg', 'xl' and only show the tips below the given screen size. Similar to the responsive table breakpoints. Omit this prop to always show.
<%= pb_rails("passphrase", props: { label: "Pass an array of strings to the tips prop", tips: ['And the info icon will appear.', 'Each string will be displayed as its own tip'], }) %> <%= pb_rails("passphrase", props: { label: "Omit the prop to hide the icon" }) %> <%= pb_rails("passphrase", props: { label: "Only show tips at small screen size", show_tips_below: "sm", tips: ['Make the password longer', 'Type more things', 'Use something else'], }) %> <%= pb_rails("passphrase", props: { label: "Only show tips at medium screen size", show_tips_below: "md", tips: ['Make the password longer', 'Type more things', 'Use something else'], }) %> <%= pb_rails("passphrase", props: { label: "Only show tips at large screen size", show_tips_below: "lg", tips: ['Make the password longer', 'Type more things', 'Use something else'], }) %>
Strength is calculated on a 0-4 scale by the Zxcvbn package.
This example depends on the zxcvbn
library.
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.
<%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_change" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_change" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_change" }) %> <%= pb_rails("text_input", props: { label: "Passphrase Strength", value: "0", disabled: true, id: "calc_strength_change" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { // variables for the kits you are targeting const passphrase = document.querySelector(".passphrase_change").querySelector("input") const calcStrength = document.querySelector("#calc_strength_change") const barVariant = document.getElementById("bar_change") const barPercent = document.getElementById("bar_change").querySelector("div") const caption = document.getElementById("caption_change") // hide the bar and captions barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; const handleStrengthCalculation = (settings) => { const { passphrase = "", common = false, isPwned = false, averageThreshold = 2, minLength = 12, strongThreshold = 3, } = settings const resultByScore = { 0: { variant: 'negative', label: '', percent: 0, }, 1: { variant: 'negative', label: 'This passphrase is too common', percent: 25, }, 2: { variant: 'negative', label: 'Too weak', percent: 25, }, 3: { variant: 'warning', label: 'Almost there, keep going!', percent: 50, }, 4: { variant: 'positive', label: 'Success! Strong passphrase', percent: 100, } } const { score } = zxcvbn(passphrase); const noPassphrase = passphrase.length <= 0 const commonPassphrase = common || isPwned const weakPassphrase = passphrase.length < minLength || score < averageThreshold const averagePassphrase = score < strongThreshold const strongPassphrase = score >= strongThreshold if (noPassphrase) { return {...resultByScore[0], score} } else if (commonPassphrase) { return {...resultByScore[1], score} } else if (weakPassphrase) { return {...resultByScore[2], score} } else if (averagePassphrase){ return {...resultByScore[3], score} } else if (strongPassphrase) { return {...resultByScore[4], score} } } // event listeners attached to the input field passphrase.addEventListener('input', (e) => { const passphrase = e.target.value; // pass in passphrase to the handleStrengthCalculation and set that equal to result variable const result = handleStrengthCalculation({passphrase: passphrase}) // set the value of the text_input to the score calcStrength.value = result.score // conditional statment to show or hide progress_simple bar and caption if user has entered a password if (passphrase) { barVariant.style.display = 'block'; barPercent.style.display = 'block'; caption.style.display = 'block'; } else { barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; } // set the width of the progress_simple kit barPercent.style.width = result.percent.toString()+ "%" // set the variant of the progress_simple kit barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); // set the text of the caption kit caption.textContent = result.label }); }) <% end %>
This example depends on the zxcvbn
library.
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.
<%= pb_rails("body", props: { margin_bottom: "md", id: "body_common" }) %> <%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_common" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_common" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_common" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { const commonText = document.querySelector("#body_common") // variables for the kits you are targeting const passphrase = document.querySelector(".passphrase_common").querySelector("input") const barVariant = document.getElementById("bar_common") const barPercent = document.getElementById("bar_common").querySelector("div") const caption = document.getElementById("caption_common") // hide the bar and captions barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; const handleStrengthCalculation = (settings) => { const { passphrase = "", common = false, isPwned = false, averageThreshold = 2, minLength = 12, strongThreshold = 3, } = settings const resultByScore = { 0: { variant: 'negative', label: '', percent: 0, }, 1: { variant: 'negative', label: 'This passphrase is too common', percent: 25, }, 2: { variant: 'negative', label: 'Too weak', percent: 25, }, 3: { variant: 'warning', label: 'Almost there, keep going!', percent: 50, }, 4: { variant: 'positive', label: 'Success! Strong passphrase', percent: 100, } } const { score } = zxcvbn(passphrase); const noPassphrase = passphrase.length <= 0 const commonPassphrase = common || isPwned const weakPassphrase = passphrase.length < minLength || score < averageThreshold const averagePassphrase = score < strongThreshold const strongPassphrase = score >= strongThreshold if (noPassphrase) { return {...resultByScore[0], score} } else if (commonPassphrase) { return {...resultByScore[1], score} } else if (weakPassphrase) { return {...resultByScore[2], score} } else if (averagePassphrase){ return {...resultByScore[3], score} } else if (strongPassphrase) { return {...resultByScore[4], score} } } // array that holds the common passwords you wish to target const COMMON_PASSPHRASES = ['passphrase', 'apple', 'password', 'p@55w0rd'] commonText.textContent = `Try typing any of the following: ${COMMON_PASSPHRASES.join(', ')}` // function that checks if the user password is in the common password list const isCommon = (passphrase) => { if (COMMON_PASSPHRASES.includes(passphrase)) return true return false } // event listeners attached to the input field passphrase.addEventListener('input', (e) => { const passphrase = e.target.value; // pass in passphrase to the handleStrengthCalculation and set that equal to result variable const result = handleStrengthCalculation({ passphrase: passphrase, common: isCommon(passphrase) }) // conditional statment to show or hide progress_simple bar and caption if user has entered a password if (passphrase) { barVariant.style.display = 'block'; barPercent.style.display = 'block'; caption.style.display = 'block'; } else { barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; } // set the width of the progress_simple kit barPercent.style.width = result.percent.toString()+ "%" // set the variant of the progress_simple kit barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); // set the text of the caption kit caption.textContent = result.label }); }) <% end %>
Use HaveIBeenPwned's API to check for breached passwords.
As the passphrase is typed, it is checked against more than half a billion breached passwords, to help ensure its not compromised.
Should it fail, the feedback will express the passphrase is too common, prompting the user to change.
This uses their k-Anonymity model, so only the first 5 characters of a hashed copy of the passphrase are sent.
This example depends on the zxcvbn
library and haveibeenpwned
API.
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.
<%= pb_rails("passphrase", props: { label: "Passphrase", classname: "passphrase_breached" }) %> <%= pb_rails("progress_simple", props: { percent: 0, id: "bar_breached" }) %> <%= pb_rails("caption", props: { size: 'xs', text: "hello", id: "caption_breached" }) %> <%= javascript_tag do %> window.addEventListener("DOMContentLoaded", () => { // variables for the kits you are targeting const passphrase = document.querySelector(".passphrase_breached").querySelector("input") const barVariant = document.getElementById("bar_breached") const barPercent = document.getElementById("bar_breached").querySelector("div") const caption = document.getElementById("caption_breached") // hide the bar and captions barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; const handleStrengthCalculation = (settings) => { const { passphrase = "", common = false, isPwned = false, averageThreshold = 2, minLength = 12, strongThreshold = 3, } = settings const resultByScore = { 0: { variant: 'negative', label: '', percent: 0, }, 1: { variant: 'negative', label: 'This passphrase is too common', percent: 25, }, 2: { variant: 'negative', label: 'Too weak', percent: 25, }, 3: { variant: 'warning', label: 'Almost there, keep going!', percent: 50, }, 4: { variant: 'positive', label: 'Success! Strong passphrase', percent: 100, } } const { score } = zxcvbn(passphrase); const noPassphrase = passphrase.length <= 0 const commonPassphrase = common || isPwned const weakPassphrase = passphrase.length < minLength || score < averageThreshold const averagePassphrase = score < strongThreshold const strongPassphrase = score >= strongThreshold if (noPassphrase) { return {...resultByScore[0], score} } else if (commonPassphrase) { return {...resultByScore[1], score} } else if (weakPassphrase) { return {...resultByScore[2], score} } else if (averagePassphrase){ return {...resultByScore[3], score} } else if (strongPassphrase) { return {...resultByScore[4], score} } } // event listeners attached to the input field passphrase.addEventListener('input', (e) => { const passphrase = e.target.value; let pwndMatch = false const checkHaveIBeenPwned = async function (passphrase) { const buffer = new TextEncoder('utf-8').encode(passphrase) const digest = await crypto.subtle.digest('SHA-1', buffer) const hashArray = Array.from(new Uint8Array(digest)) const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('') const firstFive = hashHex.slice(0, 5) const endOfHash = hashHex.slice(5) const resp = await fetch(`https://api.pwnedpasswords.com/range/${firstFive}`) const text = await resp.text() if (passphrase.length < 5) { pwndMatch = false } else { pwndMatch = text.split('\n').some((line) => { return line.split(':')[0] === endOfHash.toUpperCase() }) } // pass in passphrase and isPwnd match to the handleStrengthCalculation and set that equal to result variable const result = handleStrengthCalculation({ passphrase: passphrase, isPwned: pwndMatch }); // conditional statment to show or hide progress_simple bar and caption if user has entered a password if (passphrase) { barVariant.style.display = 'block'; barPercent.style.display = 'block'; caption.style.display = 'block'; } else { barVariant.style.display = 'none'; barPercent.style.display = 'none'; caption.style.display = 'none'; } // set the width of the progress_simple kit barPercent.style.width = result.percent.toString()+ "%" // set the variant of the progress_simple kit barVariant.setAttribute("class", "pb_progress_simple_kit_"+ result.variant +"_left"); // set the text of the caption kit caption.textContent = result.label } checkHaveIBeenPwned(passphrase) }); }) <% end %>
Props | Type | Values |
---|---|---|
max_width |
array
|
0%
xs
sm
md
lg
xl
xxl
0
none
100%
|
min_width |
array
|
0%
xs
sm
md
lg
xl
xxl
0
none
100%
|
z_index |
array
|
1
2
3
4
5
6
7
8
9
10
|
number_spacing |
array
|
tabular
|
shadow |
array
|
none
deep
deeper
deepest
|
line_height |
array
|
tightest
tighter
tight
normal
loose
looser
loosest
|
display |
array
|
block
inline_block
inline
flex
inline_flex
none
|
cursor |
array
|
auto
default
none
contextMenu
help
pointer
progress
wait
cell
crosshair
text
verticalText
alias
copy
move
noDrop
notAllowed
grab
grabbing
eResize
nResize
neResize
nwResize
sResize
seResize
swResize
wResize
ewResize
nsResize
neswResize
nwseResize
colResize
rowResize
allScroll
zoomIn
zoomOut
|
flex_direction |
array
|
row
column
rowReverse
columnReverse
|
flex_wrap |
array
|
wrap
nowrap
wrapReverse
|
justify_content |
array
|
start
end
center
spaceBetween
spaceAround
spaceEvenly
|
justify_self |
array
|
auto
start
end
center
stretch
|
align_items |
array
|
flexStart
flexEnd
start
end
center
baseline
stretch
|
align_content |
array
|
start
end
center
spaceBetween
spaceAround
spaceEvenly
|
align_self |
array
|
auto
start
end
center
stretch
baseline
|
flex |
array
|
auto
initial
0
1
2
3
4
5
6
7
8
9
10
11
12
none
|
flex_grow |
array
|
1
0
|
flex_shrink |
array
|
1
0
|
order |
array
|
1
2
3
4
5
6
7
8
9
10
11
12
|
position |
array
|
relative
absolute
fixed
sticky
|
hover |
array
|
|
border_radius |
array
|
none
xs
sm
md
lg
xl
rounded
|
text_align |
array
|
start
end
left
right
center
justify
justify-all
match-parent
|
overflow |
array
|
visible
hidden
scroll
auto
|
truncate |
array
|
1
2
3
4
5
|
left |
array
|
0
xxs
xs
sm
md
lg
xl
auto
initial
inherit
|
top |
array
|
0
xxs
xs
sm
md
lg
xl
auto
initial
inherit
|
right |
array
|
0
xxs
xs
sm
md
lg
xl
auto
initial
inherit
|
bottom |
array
|
0
xxs
xs
sm
md
lg
xl
auto
initial
inherit
|
vertical_align |
array
|
baseline
super
top
middle
bottom
sub
text-top
text-bottom
|
overflow_x |
array
|
visible
hidden
scroll
auto
|
overflow_y |
array
|
visible
hidden
scroll
auto
|
margin |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_bottom |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_left |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_right |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_top |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_x |
array
|
none
xxs
xs
sm
md
lg
xl
|
margin_y |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_bottom |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_left |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_right |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_top |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_x |
array
|
none
xxs
xs
sm
md
lg
xl
|
padding_y |
array
|
none
xxs
xs
sm
md
lg
xl
|
classname |
string
|
|
dark |
boolean
|
|
group_hover |
boolean
|
|
id |
string
|
|
data |
hashprop
|
|
aria |
hashprop
|
|
html_options |
hashprop
|
|
children |
proc
|
|
style |
hashprop
|
|
height |
string
|
|
min_height |
string
|
|
max_height |
string
|
Props | Type | Values | Default |
---|---|---|---|
confirmation |
boolean
|
false
|
|
input_props |
hashprop
|
||
label |
string
|
||
show_tips_below |
enum
|
always
xs
sm
md
lg
xl
|
always
|
tips |
array
|
||
value |
string
|