Skip to content

Commit 417ecfb

Browse files
committed
Added atoms select
1 parent c68fff2 commit 417ecfb

9 files changed

Lines changed: 253 additions & 0 deletions

File tree

src/assets/scss/6-components/atoms/__atoms.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@
33
\*------------------------------------*/
44
@import "buttons";
55
@import "checkbox-button";
6+
@import "labels";
7+
@import "radios";
8+
@import "selects";
9+
@import "text-input-icon";
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.c-label {
2+
@include font-style(
3+
$font-primary,
4+
"xsmall",
5+
get-color-neutral("70"),
6+
700,
7+
18px
8+
);
9+
letter-spacing: 0.15em;
10+
text-transform: uppercase;
11+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
.c-radio {
2+
@include padding(16px);
3+
4+
&:hover {
5+
cursor: pointer;
6+
}
7+
8+
input {
9+
&:checked,
10+
&:not(:checked) {
11+
position: absolute;
12+
left: -9999px;
13+
}
14+
&:checked + label,
15+
&:not(:checked) + label {
16+
@extend p;
17+
@include padding-right(40px);
18+
position: relative;
19+
display: inline-block;
20+
color: get-color-neutral("90");
21+
cursor: pointer;
22+
&:before {
23+
content: "";
24+
position: absolute;
25+
right: 0;
26+
top: 3px;
27+
width: 20px;
28+
height: 20px;
29+
background: #fff;
30+
border: 1px solid get-color-accents("blue-base");
31+
border-radius: 100%;
32+
}
33+
&:after {
34+
position: absolute;
35+
top: 8px;
36+
right: 5px;
37+
content: "";
38+
width: 10px;
39+
height: 10px;
40+
background: get-color-accents("blue-base");
41+
border-radius: 100%;
42+
-webkit-transition: all 0.2s ease;
43+
transition: all 0.2s ease;
44+
}
45+
}
46+
&:focus + label {
47+
&:before {
48+
border: 1px solid get-color-accents("blue-dark");
49+
}
50+
&::after {
51+
background: get-color-accents("blue-dark");
52+
}
53+
}
54+
&:not(:checked) + label:before {
55+
border-color: get-color-neutral("30");
56+
}
57+
&:not(:checked) + label:after {
58+
opacity: 0;
59+
-webkit-transform: scale(0);
60+
transform: scale(0);
61+
}
62+
&:checked + label:after {
63+
opacity: 1;
64+
-webkit-transform: scale(1);
65+
transform: scale(1);
66+
}
67+
}
68+
label {
69+
@extend p;
70+
@extend .-small;
71+
letter-spacing: 0.02em;
72+
word-break: break-word;
73+
74+
p {
75+
color: get-color-neutral("70");
76+
}
77+
}
78+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
.c-select {
2+
position: relative;
3+
display: inline-block;
4+
@include icon-fill(get-color-neutral("30"));
5+
6+
&:hover {
7+
select {
8+
border: 1px solid get-color-neutral("50");
9+
}
10+
11+
@include icon-fill(get-color-neutral("50"));
12+
}
13+
14+
select {
15+
@include padding(8px);
16+
@include padding-right(32px);
17+
@include font-style($color: get-color-neutral("90"));
18+
border: 1px solid get-color-neutral("30");
19+
border-radius: $border-radius-small;
20+
height: rem(40px);
21+
22+
// hides default arrow so we can place our chevron down icon instead
23+
-moz-appearance: none;
24+
-webkit-appearance: none;
25+
appearance: none;
26+
27+
&::-ms-expand {
28+
// hide default arrow in IE 11
29+
display: none;
30+
}
31+
32+
option {
33+
@include font-style($color: get-color-neutral("90"));
34+
}
35+
}
36+
37+
.c-icon {
38+
position: absolute;
39+
right: 8px;
40+
top: 12px;
41+
// forward pointer events to the <select> underneath the icon
42+
pointer-events: none;
43+
}
44+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.c-text-input-icon {
2+
position: relative;
3+
4+
.c-icon {
5+
position: absolute;
6+
left: 0;
7+
top: calc(50% - 14px);
8+
path {
9+
fill: get-color-neutral("50");
10+
}
11+
}
12+
input {
13+
border: none;
14+
padding-left: 30px;
15+
width: 100%;
16+
}
17+
}

src/atoms/forms/select.stories.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from "react";
2+
import { text } from "@storybook/addon-knobs";
3+
import { Select } from "./select";
4+
import Faker from "faker";
5+
6+
export default {
7+
component: Select,
8+
title: "Atoms | Forms / Select",
9+
};
10+
11+
export const selectKnobs = () => (
12+
<Select
13+
// disabled={boolean("Disabled", false)}
14+
id={Faker.random.uuid()}
15+
onChange={() => {}}
16+
options={[
17+
{ label: "Label 1", value: "Value1" },
18+
{ label: "Label 2", value: "Value2" },
19+
]}
20+
value={text("Value", "Input Value")}
21+
/>
22+
);

src/atoms/forms/select.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from "react";
2+
3+
describe("Select", () => {
4+
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/11", () => {});
5+
});

src/atoms/forms/select.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React, { ChangeEvent } from "react";
2+
import { StringUtils } from "andculturecode-javascript-core";
3+
import { Icons } from "../constants/icons";
4+
import { Icon } from "../icons/icon";
5+
6+
// -----------------------------------------------------------------------------------------
7+
// #region Interfaces
8+
// -----------------------------------------------------------------------------------------
9+
10+
export interface SelectProps<T = any> {
11+
cssClassName?: string;
12+
id: string;
13+
onChange: (selectedOption?: SelectOption<T>) => void;
14+
name?: string;
15+
options: SelectOption<T>[];
16+
value?: string;
17+
}
18+
19+
export interface SelectOption<T = any> {
20+
data?: T;
21+
label: string;
22+
value: string;
23+
}
24+
25+
// #endregion Interfaces
26+
27+
// -----------------------------------------------------------------------------------------
28+
// #region Component
29+
// -----------------------------------------------------------------------------------------
30+
31+
const Select: React.FC<SelectProps> = (props: SelectProps) => {
32+
const classNames = ["c-select"];
33+
if (StringUtils.hasValue(props.cssClassName)) {
34+
classNames.push(props.cssClassName!);
35+
}
36+
37+
const selectOptions = props.options.map((option) => (
38+
<option key={option.value} value={option.value}>
39+
{option.label}
40+
</option>
41+
));
42+
43+
const handleChange = (e: ChangeEvent<HTMLSelectElement>) => {
44+
const option = props.options.find(
45+
(o: SelectOption) => o.value === e.target.value
46+
);
47+
props.onChange(option);
48+
};
49+
50+
return (
51+
<div className={classNames.join(" ")}>
52+
<select
53+
onChange={handleChange}
54+
value={props.value}
55+
name={props.name}>
56+
{selectOptions}
57+
</select>
58+
<Icon type={Icons.ChevronDown} />
59+
</div>
60+
);
61+
};
62+
63+
// #endregion Component
64+
65+
// -----------------------------------------------------------------------------------------
66+
// #region Exports
67+
// -----------------------------------------------------------------------------------------
68+
69+
export { Select };
70+
71+
// #endregion Exports

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export { Button } from "./atoms/buttons/button";
1010
export { CheckboxButton } from "./atoms/forms/checkbox-button";
1111
export { CheckboxInput } from "./atoms/forms/checkbox-input";
1212
export { PasswordInput } from "./atoms/forms/password-input";
13+
export { Select } from "./atoms/forms/select";
1314
export { SubmitButton } from "./atoms/forms/submit-button";
1415
export { TextArea } from "./atoms/forms/text-area";
1516
export { TextInput } from "./atoms/forms/text-input";

0 commit comments

Comments
 (0)