-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
420 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
<template> | ||
<component :is="wrapper" class="lux-input"> | ||
<legend v-if="groupLabel">{{ groupLabel }}</legend> | ||
<div | ||
v-for="option in options" | ||
class="lux-radio" | ||
:class="{ 'lux-inline': !vertical }" | ||
:key="option.id" | ||
> | ||
<input | ||
type="radio" | ||
:id="option.id" | ||
:name="option.name" | ||
:value="option.value" | ||
:checked="option.checked" | ||
:disabled="option.disabled" | ||
:required="option.required" | ||
@change="change($event.target.value)" | ||
@blur="inputblur($event.target)" | ||
/> | ||
<label v-if="option.label" :for="option.id">{{ option.label }}</label> | ||
<label v-else :for="option.id">{{ option.value }}</label> | ||
</div> | ||
<div role="alert" class="lux-error" v-if="errormessage">{{ errormessage }}</div> | ||
</component> | ||
</template> | ||
|
||
<script> | ||
/** | ||
* Radio buttons should only be used when a user can select one option. | ||
* For multiple selections, use checkboxes. | ||
*/ | ||
export default { | ||
name: "LuxInputRadio", | ||
status: "ready", | ||
release: "1.0.0", | ||
type: "Element", | ||
data: function () { | ||
return { | ||
wrapper: this.groupLabel.length ? "fieldset" : "div", | ||
} | ||
}, | ||
props: { | ||
/** | ||
* If true, the radio buttons will be stacked vertically. Otherwise they will be horizontal (inline). | ||
*/ | ||
vertical: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
/** | ||
* The available options to check. Option properties are: id, value, disabled, required, checked | ||
*/ | ||
options: { | ||
required: true, | ||
type: Array, | ||
}, | ||
/** | ||
* The label of the form input field. | ||
*/ | ||
groupLabel: { | ||
type: String, | ||
default: "", | ||
}, | ||
/** | ||
* The validation message a user should get. | ||
*/ | ||
errormessage: { | ||
type: String, | ||
default: "", | ||
}, | ||
/** | ||
* Unique identifier of the form input field. | ||
*/ | ||
id: { | ||
type: String, | ||
default: "", | ||
required: true, | ||
}, | ||
/** | ||
* Whether the form input field is disabled or not. | ||
* `true, false` | ||
*/ | ||
disabled: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
/** | ||
* Whether the form input field is required or not. | ||
* `true, false` | ||
*/ | ||
required: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
/** | ||
* Manually trigger input field’s hover state. | ||
* `true, false` | ||
*/ | ||
hover: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
/** | ||
* Manually trigger input field’s focus state. | ||
* `true, false` | ||
*/ | ||
focus: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}, | ||
methods: { | ||
change(value) { | ||
this.$emit("change", value) | ||
}, | ||
inputblur(value) { | ||
this.$emit("inputblur", value) | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<style lang="scss" scoped> | ||
@import "../assets/styles/spacing.scss"; | ||
@import "../assets/styles/mixins.scss"; | ||
@import "../assets/styles/variables.css"; | ||
@import "../assets/styles/system.scss"; | ||
fieldset { | ||
border: 0; | ||
padding: 0; | ||
} | ||
.lux-input { | ||
@include stack-space(var(--space-small)); | ||
font-weight: var(--font-weight-regular); | ||
font-family: var(--font-family-text); | ||
font-size: var(--font-size-base); | ||
legend { | ||
margin-bottom: var(--space-x-small); | ||
} | ||
label { | ||
padding-right: var(--space-base); | ||
} | ||
} | ||
.lux-radio { | ||
@include reset; | ||
@include stack-space(var(--space-x-small)); | ||
font-family: var(--font-family-text); | ||
line-height: var(--line-height-base); | ||
} | ||
.lux-radio input[type="radio"] { | ||
@include visually-hidden; | ||
} | ||
.lux-radio label { | ||
position: relative; | ||
display: inline-block; | ||
margin-bottom: var(--space-xx-small); | ||
cursor: pointer; | ||
padding-left: var(--space-base); | ||
} | ||
.lux-radio label::before, | ||
.lux-radio label::after { | ||
position: absolute; | ||
content: ""; | ||
/*Needed for the line-height to take effect*/ | ||
display: inline-block; | ||
} | ||
/*Outer box of the fake radio*/ | ||
.lux-radio label::before { | ||
height: 16px; | ||
width: 16px; | ||
background-color: var(--color-white); | ||
border: 0; | ||
border-radius: var(--border-radius-circle); | ||
box-shadow: inset 0 1px 0 0 rgba($color-rich-black, 0.07), 0 0 0 1px tint($color-rich-black, 80%); | ||
left: 0; | ||
top: 4px; | ||
} | ||
/* On mouse-over, add a grey background color */ | ||
.lux-radio :not([disabled]) + label:hover::before { | ||
box-shadow: 0 1px 5px 0 rgba($color-rich-black, 0.07), 0 0 0 1px tint($color-rich-black, 60%); | ||
} | ||
.lux-radio input:checked + label::before { | ||
transition: box-shadow 0.2s ease; | ||
background-color: var(--color-bleu-de-france); | ||
box-shadow: inset 0 0 0 1px var(--color-bleu-de-france), 0 0 0 1px var(--color-bleu-de-france); | ||
outline: 0; | ||
} | ||
/*Checkmark of the fake radio*/ | ||
.lux-radio label::after { | ||
height: 6px; | ||
width: 6px; | ||
border-radius: var(--border-radius-circle); | ||
background-color: var(--color-white); | ||
left: 5px; | ||
top: 9px; | ||
} | ||
/*Hide the checkmark by default*/ | ||
.lux-radio input[type="radio"] + label::after { | ||
content: none; | ||
} | ||
/*Unhide on the checked state*/ | ||
.lux-radio input[type="radio"]:checked + label::after { | ||
content: ""; | ||
} | ||
/*Adding focus styles on the outer-box of the fake radio*/ | ||
.lux-radio input[type="radio"]:focus + label::before { | ||
transition: box-shadow 0.2s ease; | ||
box-shadow: inset 0 0 0 1px var(--color-bleu-de-france), 0 0 0 1px var(--color-bleu-de-france); | ||
outline: 0; | ||
} | ||
.lux-inline { | ||
display: inline-block; | ||
} | ||
[disabled] + label { | ||
cursor: not-allowed; | ||
color: var(--color-grayscale); | ||
} | ||
</style> | ||
|
||
<docs> | ||
```jsx | ||
<div> | ||
<lux-input-radio | ||
id="foo" | ||
vertical groupLabel="Where is my mind?" | ||
:options="[ | ||
{name: 'radio-group-name', value: 'In the clouds', id: 'radio-opt1', required: true}, | ||
{name: 'radio-group-name', value: 'I don\'t know', id: 'radio-opt2', disabled: true} | ||
]"> | ||
</lux-input-radio> | ||
</div> | ||
``` | ||
</docs> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
tests/unit/specs/components/__snapshots__/luxInputRadio.spec.js.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`LuxInputRadio.vue has the expected html structure 1`] = ` | ||
<div | ||
class="lux-input" | ||
> | ||
<!--v-if--> | ||
<div | ||
class="lux-radio lux-inline" | ||
> | ||
<input | ||
id="radio-opt1" | ||
name="opt 1" | ||
type="radio" | ||
value="one" | ||
/> | ||
<label | ||
for="radio-opt1" | ||
> | ||
one | ||
</label> | ||
</div> | ||
<div | ||
class="lux-radio lux-inline" | ||
> | ||
<input | ||
id="radio-opt2" | ||
name="opt 2" | ||
type="radio" | ||
value="two" | ||
/> | ||
<label | ||
for="radio-opt2" | ||
> | ||
two | ||
</label> | ||
</div> | ||
<!--v-if--> | ||
</div> | ||
`; |
Oops, something went wrong.