@eturnity/eturnity_reusable_components 1.0.9 → 1.0.13

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eturnity/eturnity_reusable_components",
3
- "version": "1.0.9",
3
+ "version": "1.0.13",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vue-cli-service serve",
@@ -10,6 +10,7 @@
10
10
  "build-storybook": "build-storybook"
11
11
  },
12
12
  "dependencies": {
13
+ "@vueform/slider": "1.0.5",
13
14
  "core-js": "^3.6.5",
14
15
  "vue": "^2.6.11",
15
16
  "vue-styled-components": "^1.6.0"
@@ -22,6 +23,7 @@
22
23
  "@vue/cli-plugin-babel": "~4.5.0",
23
24
  "@vue/cli-plugin-eslint": "~4.5.0",
24
25
  "@vue/cli-service": "~4.5.0",
26
+ "@vue/composition-api": "^1.0.0-rc.10",
25
27
  "babel-eslint": "^10.1.0",
26
28
  "eslint": "^6.7.2",
27
29
  "eslint-plugin-vue": "^6.2.2",
package/src/App.vue CHANGED
@@ -1,9 +1,13 @@
1
1
  <template>
2
2
  <ThemeProvider :theme="getTheme()" :style="{ height: '100%' }">
3
3
  <page-container>
4
- <div>Hello World</div>
5
- <close-button />
6
- <modal :isOpen="true" />
4
+ <slider
5
+ :value="inputValue"
6
+ unit="m"
7
+ @change="onChangeSlider($event)"
8
+ :minValue="10"
9
+ :maxValue="500"
10
+ />
7
11
  </page-container>
8
12
  </ThemeProvider>
9
13
  </template>
@@ -12,8 +16,7 @@
12
16
  import { ThemeProvider } from "vue-styled-components"
13
17
  import theme from "./assets/theme"
14
18
  import styled from "vue-styled-components"
15
- import CloseButton from "@/components/buttons/closeButton"
16
- import Modal from "@/components/modals/modal"
19
+ import slider from "@/components/inputs/slider"
17
20
 
18
21
  const PageContainer = styled.div`
19
22
  padding: 40px;
@@ -24,13 +27,27 @@ export default {
24
27
  components: {
25
28
  ThemeProvider,
26
29
  PageContainer,
27
- CloseButton,
28
- Modal,
30
+ slider,
31
+ },
32
+ data() {
33
+ return {
34
+ inputValue: 50,
35
+ checkedOption: "button_1",
36
+ question: {
37
+ number_format_precision: 4,
38
+ number_min_allowed: 0,
39
+ number_max_allowed: 10,
40
+ unit_short_name: "cm",
41
+ },
42
+ }
29
43
  },
30
44
  methods: {
31
45
  getTheme() {
32
46
  return theme
33
47
  },
48
+ onChangeSlider(event) {
49
+ this.inputValue = event
50
+ },
34
51
  },
35
52
  }
36
53
  </script>
Binary file
@@ -0,0 +1,36 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: none; display: block; shape-rendering: auto;" width="207px" height="207px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
3
+ <g transform="rotate(0 50 50)">
4
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
5
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.875s" repeatCount="indefinite"></animate>
6
+ </rect>
7
+ </g><g transform="rotate(45 50 50)">
8
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
9
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
10
+ </rect>
11
+ </g><g transform="rotate(90 50 50)">
12
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
13
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.625s" repeatCount="indefinite"></animate>
14
+ </rect>
15
+ </g><g transform="rotate(135 50 50)">
16
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
17
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
18
+ </rect>
19
+ </g><g transform="rotate(180 50 50)">
20
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
21
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.375s" repeatCount="indefinite"></animate>
22
+ </rect>
23
+ </g><g transform="rotate(225 50 50)">
24
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
25
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
26
+ </rect>
27
+ </g><g transform="rotate(270 50 50)">
28
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
29
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="-0.125s" repeatCount="indefinite"></animate>
30
+ </rect>
31
+ </g><g transform="rotate(315 50 50)">
32
+ <rect x="48" y="20" rx="0" ry="0" width="4" height="14" fill="#000000">
33
+ <animate attributeName="opacity" values="1;0" keyTimes="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
34
+ </rect>
35
+ </g>
36
+ <!-- [ldio] generated by https://loading.io/ --></svg>
Binary file
@@ -0,0 +1,6 @@
1
+ <svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M26.7677 12.2383H15.4708C13.6885 12.2383 12.2385 13.6883 12.2385 15.4706V21.6083C10.9445 22.5326 9.63063 23.4325 8.37891 24.4139C9.64181 25.4045 10.968 26.3123 12.2738 27.2449C12.5052 28.8018 13.8508 30 15.4708 30H26.7677C28.55 30 30 28.55 30 26.7675V15.4706C30 13.6883 28.55 12.2383 26.7677 12.2383ZM22.9692 24.5883C22.7621 24.5883 22.6021 24.5226 22.5552 24.3436L22.1972 23.0914H20.0411L19.6836 24.3436C19.6365 24.5226 19.4765 24.5883 19.2693 24.5883C18.9397 24.5883 18.4973 24.3814 18.4973 24.0802C18.4973 24.0612 18.5067 24.0237 18.5161 23.9859L20.3332 18.0643C20.4179 17.7818 20.7662 17.6498 21.1146 17.6498C21.4723 17.6498 21.8207 17.7818 21.9054 18.0643L23.7225 23.9859C23.7318 24.0237 23.7412 24.0518 23.7412 24.0802C23.7412 24.3718 23.2988 24.5883 22.9692 24.5883Z" fill="white"/>
3
+ <path d="M20.2954 22.131H21.9337L21.1143 19.241L20.2954 22.131Z" fill="white"/>
4
+ <path d="M10.4807 15.4706C10.4807 14.2905 10.8934 13.2056 11.5807 12.3502C10.578 12.3502 9.6476 12.0364 8.88062 11.5034C8.11363 12.0367 7.18323 12.3502 6.18027 12.3502C5.90675 12.3502 5.68474 12.1282 5.68474 11.8545C5.68474 11.5807 5.90675 11.3589 6.18027 11.3589C6.88271 11.3589 7.54005 11.1644 8.10287 10.8275C7.42401 10.0948 6.97266 9.14886 6.86348 8.10196H6.1805C5.90675 8.10196 5.68474 7.88017 5.68474 7.60643C5.68474 7.33269 5.90675 7.11067 6.1805 7.11067H8.38531V5.90721C8.38531 5.63324 8.6071 5.41145 8.88084 5.41145C9.15459 5.41145 9.37637 5.63324 9.37637 5.90721V7.11067H11.5812C11.8549 7.11067 12.077 7.33269 12.077 7.60643C12.077 7.88017 11.8549 8.10196 11.5812 8.10196H10.8982C10.789 9.14886 10.3377 10.0948 9.65881 10.8275C10.2214 11.1649 10.879 11.3589 11.5812 11.3589C11.8428 11.3589 12.0566 11.5617 12.0751 11.8188C12.9666 10.9893 14.1602 10.4805 15.471 10.4805H17.7617V8.39172C19.0587 7.46534 20.3833 6.57167 21.6211 5.56641C20.3441 4.60054 19.0292 3.68558 17.7264 2.75505C17.4948 1.1982 16.1492 0 14.5292 0H3.2325C1.44997 0 0 1.44997 0 3.23227V14.5294C0 16.3117 1.44997 17.7617 3.2325 17.7617H10.4807V15.4706Z" fill="white"/>
5
+ <path d="M8.88072 10.2081C9.42317 9.64531 9.79144 8.91449 9.89925 8.10219H7.86243C7.97023 8.91449 8.33873 9.64531 8.88072 10.2081Z" fill="white"/>
6
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg width="27" height="26" viewBox="0 0 27 26" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M16.5999 25.8002H2.8999C1.4999 25.8002 0.399902 24.7002 0.399902 23.3002V2.7002C0.399902 1.3002 1.4999 0.200195 2.8999 0.200195H13.7999L19.0999 5.5002V9.0002H17.2999V6.2002L13.0999 2.0002H2.8999C2.4999 2.0002 2.1999 2.3002 2.1999 2.7002V23.4002C2.1999 23.8002 2.4999 24.1002 2.8999 24.1002H16.6999C17.0999 24.1002 17.3999 23.8002 17.3999 23.4002H19.1999C19.0999 24.7002 17.9999 25.8002 16.5999 25.8002Z" fill="white"/>
3
+ <path d="M23 12.6V15H26.4V16.5H23V20.6H21.2V11.3V11H21.5H26.6V12.6H23Z" fill="white"/>
4
+ <path d="M18.9999 12.2C18.0999 11.4 16.8999 11 15.1999 11C14.2999 11 13.3999 11.1 12.6999 11.2H12.3999V11.5V20.5H12.6999C13.2999 20.6 13.9999 20.6 14.7999 20.6C16.5999 20.6 17.9999 20.1 18.8999 19.2C19.7999 18.3 20.2999 17 20.2999 15.5C20.2999 14.1 19.7999 13 18.9999 12.2ZM15.0999 19.1C14.7999 19.1 14.4999 19.1 14.1999 19.1V12.6C14.4999 12.6 14.7999 12.5 15.1999 12.5C16.3999 12.5 17.1999 12.8 17.6999 13.4C18.1999 13.9 18.4999 14.7 18.4999 15.7C18.4999 16.8 18.1999 17.7 17.5999 18.3C16.9999 18.9 16.1999 19.1 15.0999 19.1Z" fill="white"/>
5
+ <path d="M10.5999 11.8C9.9999 11.3 9.0999 11 7.8999 11C6.9999 11 6.1999 11.1 5.5999 11.2H5.3999V20.5H7.0999V17C7.2999 17 7.4999 17 7.6999 17C8.8999 17 9.8999 16.7 10.5999 15.9C11.0999 15.4 11.3999 14.6 11.3999 13.8C11.4999 13 11.0999 12.2 10.5999 11.8ZM7.7999 15.5C7.4999 15.5 7.2999 15.5 7.1999 15.5V12.5H7.2999C7.4999 12.5 7.6999 12.5 7.8999 12.5C8.4999 12.5 8.8999 12.6 9.1999 12.9C9.4999 13.1 9.6999 13.5 9.6999 14C9.6999 14.5 9.4999 14.9 9.1999 15.2C8.8999 15.4 8.4999 15.5 7.7999 15.5Z" fill="white"/>
6
+ </svg>
Binary file
@@ -1,26 +1,26 @@
1
1
  const theme = {
2
2
  colors: {
3
- primary: '#48a2d0',
4
- secondary: '#fdb813',
5
- tertiary: '#d5d5d5',
6
- black: '#353535',
7
- yellow: '#fdb813',
8
- darkGray: '#818181',
9
- mediumGray: '#d5d5d5',
10
- lightGray: '#f2f2f2',
11
- white: '#fff',
12
- blue: '#48a2d0',
13
- red: '#ff7e7e'
3
+ primary: "#48a2d0",
4
+ secondary: "#fdb813",
5
+ tertiary: "#d5d5d5",
6
+ black: "#353535",
7
+ yellow: "#fdb813",
8
+ darkGray: "#818181",
9
+ mediumGray: "#d5d5d5",
10
+ lightGray: "#f2f2f2",
11
+ white: "#fff",
12
+ blue: "#48a2d0",
13
+ red: "#ff7e7e",
14
+ disabled: "#c4c4c4",
14
15
  },
15
- hasCustomPrimary: false, // need this to know for the button hovers
16
16
  screen: {
17
- mobileSmall: '345px',
18
- mobile: '425px',
19
- mobileLarge: '530px',
20
- tablet: '768px',
21
- tabletLarge: '950px'
17
+ mobileSmall: "345px",
18
+ mobile: "425px",
19
+ mobileLarge: "530px",
20
+ tablet: "768px",
21
+ tabletLarge: "950px",
22
22
  },
23
- borderRadius: '4px'
23
+ borderRadius: "4px",
24
24
  }
25
25
 
26
26
  export default theme
@@ -0,0 +1,156 @@
1
+ <template>
2
+ <component-wrapper>
3
+ <icon-wrapper>
4
+ <icon-img
5
+ :isActive="showInfo"
6
+ :size="size"
7
+ :borderColor="borderColor"
8
+ @click.prevent="toggleShowInfo()"
9
+ >
10
+ <svg
11
+ class="img-icon"
12
+ :width="size"
13
+ :height="size"
14
+ viewBox="0 0 24 24"
15
+ fill="none"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ >
18
+ <path
19
+ class="img-icon"
20
+ d="M20.4853 3.51469C18.2188 1.24823 15.2053 0 12 0C8.79469 0 5.78123 1.24823 3.51469 3.51469C1.24823 5.78123 0 8.79469 0 12C0 15.2053 1.24823 18.2188 3.51469 20.4853C5.78123 22.7518 8.79469 24 12 24C15.2053 24 18.2188 22.7518 20.4853 20.4853C22.7518 18.2188 24 15.2053 24 12C24 8.79469 22.7518 5.78123 20.4853 3.51469ZM12 3.28125C13.4216 3.28125 14.5781 4.4378 14.5781 5.85938C14.5781 7.28095 13.4216 8.4375 12 8.4375C10.5784 8.4375 9.42188 7.28095 9.42188 5.85938C9.42188 4.4378 10.5784 3.28125 12 3.28125ZM15.2812 19.6875H8.71875V18.2812H10.125V11.9167H8.71875V10.5104H13.875V18.2812H15.2812V19.6875Z"
21
+ fill="#D5D5D5"
22
+ />
23
+ </svg>
24
+ </icon-img>
25
+ <text-overlay
26
+ v-if="showInfo"
27
+ :borderColor="borderColor"
28
+ :alignText="alignText"
29
+ >
30
+ {{ text }}
31
+ </text-overlay>
32
+ </icon-wrapper>
33
+ </component-wrapper>
34
+ </template>
35
+
36
+ <script>
37
+ // import InfoText from "@eturnity/eturnity_reusable_components/src/components/infoText"
38
+ //To use:
39
+ // <info-component
40
+ // text="Veritatis et quasi architecto beatae vitae"
41
+ // borderColor="#ccc"
42
+ // size="20"
43
+ // alignText="right" // default is left
44
+ // />
45
+
46
+ import styled from "vue-styled-components"
47
+
48
+ const IconWrapper = styled.div`
49
+ position: relative;
50
+ `
51
+
52
+ const textAttrs = { borderColor: String, alignText: String }
53
+ const TextOverlay = styled("div", textAttrs)`
54
+ position: absolute;
55
+ top: 34px;
56
+ right: ${(props) => (props.alignText === "left" ? "-10px" : "inherit")};
57
+ left: ${(props) => (props.alignText === "left" ? "inherit" : "-10px")};
58
+ background: #fff;
59
+ border: 1px solid
60
+ ${(props) =>
61
+ props.borderColor ? props.borderColor : props.theme.colors.secondary};
62
+ padding: 16px;
63
+ width: max-content;
64
+ max-width: 400px;
65
+ font-size: 14px;
66
+ font-weight: 400;
67
+ border-radius: 4px;
68
+ z-index: 99;
69
+ color: ${(props) => props.theme.colors.black};
70
+
71
+ :before {
72
+ content: "";
73
+ background-color: #fff;
74
+ position: absolute;
75
+ top: 2px;
76
+ right: ${(props) => (props.alignText === "left" ? "-12px" : "inherit")};
77
+ left: ${(props) => (props.alignText === "left" ? "inherit" : "40px")};
78
+ height: 8px;
79
+ width: 8px;
80
+ border: 1px solid
81
+ ${(props) =>
82
+ props.borderColor ? props.borderColor : props.theme.colors.secondary};
83
+ border-width: 1px 0 0 1px;
84
+ transform-origin: center center;
85
+ transform: translate(-2em, -0.5em) rotate(45deg);
86
+ }
87
+ `
88
+
89
+ const iconAttrs = { isActive: Boolean, size: String, borderColor: String }
90
+ const IconImg = styled("div", iconAttrs)`
91
+ cursor: pointer;
92
+ height: ${(props) => props.size + "px"};
93
+
94
+ .img-icon {
95
+ fill: ${(props) =>
96
+ props.isActive
97
+ ? props.borderColor
98
+ ? props.borderColor
99
+ : props.theme.colors.secondary
100
+ : props.theme.colors.mediumGray};
101
+ }
102
+ `
103
+
104
+ const ComponentWrapper = styled.div`
105
+ display: inline-block;
106
+ `
107
+
108
+ export default {
109
+ name: "info-text",
110
+ components: {
111
+ IconWrapper,
112
+ TextOverlay,
113
+ ComponentWrapper,
114
+ IconImg,
115
+ },
116
+ props: {
117
+ text: {
118
+ required: true,
119
+ },
120
+ borderColor: {
121
+ required: false,
122
+ default: null,
123
+ },
124
+ size: {
125
+ required: false,
126
+ default: "20",
127
+ },
128
+ alignText: {
129
+ required: false,
130
+ default: "left", // "left" or "right"
131
+ },
132
+ },
133
+ methods: {
134
+ toggleShowInfo() {
135
+ this.showInfo = !this.showInfo
136
+
137
+ if (this.showInfo) {
138
+ document.addEventListener("click", this.clickOutside)
139
+ } else {
140
+ document.removeEventListener("click", this.clickOutside)
141
+ }
142
+ },
143
+ clickOutside(event) {
144
+ if (this.$el.contains(event.target)) {
145
+ return
146
+ }
147
+ this.toggleShowInfo()
148
+ },
149
+ },
150
+ data() {
151
+ return {
152
+ showInfo: false,
153
+ }
154
+ },
155
+ }
156
+ </script>
@@ -0,0 +1,112 @@
1
+ <template>
2
+ <component-wrapper>
3
+ <container :checkColor="checkColor"
4
+ >{{ label }}
5
+ <input-checkbox
6
+ type="checkbox"
7
+ :checked="isChecked"
8
+ @change="onChangeHandler($event.target.checked)"
9
+ />
10
+ <span class="checkmark"></span>
11
+ </container>
12
+ </component-wrapper>
13
+ </template>
14
+
15
+ <script>
16
+ // import Checkbox from "@eturnity/eturnity_reusable_components/src/components/inputs/checkbox"
17
+ //To use:
18
+ // <checkbox
19
+ // label="Do you accept the Terms?"
20
+ // :isChecked="isChecked" //required
21
+ // @on-event-handler="onInputChange($event)" //required
22
+ // checkColor="blue"
23
+ // />
24
+ import styled from "vue-styled-components"
25
+
26
+ const ComponentWrapper = styled.div`
27
+ display: inline-block;
28
+ `
29
+
30
+ const containerAttrs = { checkColor: String }
31
+ const Container = styled("label", containerAttrs)`
32
+ display: grid;
33
+ height: 28px;
34
+ align-content: center;
35
+ color: ${(props) => props.theme.colors.black};
36
+ position: relative;
37
+ padding-left: 42px;
38
+ margin-bottom: 12px;
39
+ cursor: pointer;
40
+ font-size: 16px;
41
+ user-select: none;
42
+
43
+ .checkmark {
44
+ position: absolute;
45
+ top: 0;
46
+ left: 0;
47
+ height: 25px;
48
+ width: 25px;
49
+ background-color: #fff;
50
+ border-radius: 4px;
51
+ border: 1px solid ${(props) => props.theme.colors.mediumGray};
52
+
53
+ &:after {
54
+ content: "";
55
+ position: absolute;
56
+ display: none;
57
+ }
58
+ }
59
+
60
+ .checkmark:after {
61
+ left: 9px;
62
+ top: 5px;
63
+ width: 5px;
64
+ height: 10px;
65
+ border: solid
66
+ ${(props) =>
67
+ props.checkColor ? props.checkColor : props.theme.colors.black};
68
+ border-width: 0 3px 3px 0;
69
+ transform: rotate(45deg);
70
+ }
71
+ `
72
+
73
+ const InputCheckbox = styled.input`
74
+ cursor: pointer;
75
+ position: absolute;
76
+ opacity: 0;
77
+ cursor: pointer;
78
+ height: 0;
79
+ width: 0;
80
+
81
+ &:checked ~ .checkmark:after {
82
+ display: block;
83
+ }
84
+ `
85
+
86
+ export default {
87
+ name: "checkbox",
88
+ components: {
89
+ ComponentWrapper,
90
+ Container,
91
+ InputCheckbox,
92
+ },
93
+ props: {
94
+ label: {
95
+ required: false,
96
+ default: "",
97
+ },
98
+ isChecked: {
99
+ required: true,
100
+ default: false,
101
+ },
102
+ checkColor: {
103
+ required: false,
104
+ },
105
+ },
106
+ methods: {
107
+ onChangeHandler(value) {
108
+ this.$emit("on-event-handler", value)
109
+ },
110
+ },
111
+ }
112
+ </script>
@@ -0,0 +1,215 @@
1
+ <template>
2
+ <container>
3
+ <input-wrapper>
4
+ <input-container
5
+ :hasUnit="!!question.unit_short_name"
6
+ :placeholder="placeholder"
7
+ :isError="isError"
8
+ :inputWidth="inputWidth"
9
+ :value="textInput"
10
+ :hasLength="!!textInput.length"
11
+ @input="onChangeHandler"
12
+ @blur="onInputBlur()"
13
+ @keyup.enter="$emit('on-enter-click')"
14
+ />
15
+ <unit-container
16
+ v-if="question.unit_short_name"
17
+ :hasLength="!!textInput.length"
18
+ :isError="isError"
19
+ >{{ question.unit_short_name }}</unit-container
20
+ >
21
+ </input-wrapper>
22
+ <error-message v-if="isError">{{ errorMessage }}</error-message>
23
+ </container>
24
+ </template>
25
+
26
+ <script>
27
+ // import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
28
+ //This component should be used for questions with input fields only
29
+ //How to use:
30
+ // <input-number
31
+ // placeholder="Enter distance"
32
+ // :isError="false" //default is false
33
+ // inputWidth="150px" //by default, this is 100%
34
+ // :question="question"
35
+ // :value="inputValue" //required -- String
36
+ // @input-change="onInputChange($event)" //required
37
+ // @on-enter-click="onInputSubmit()"
38
+ // :errorMessage="Enter a number between 1 and 10"
39
+ // />
40
+ // question data example:
41
+ // question: {
42
+ // number_format_precision: 4,
43
+ // number_min_allowed: 0,
44
+ // number_max_allowed: 10,
45
+ // unit_short_name: "cm",
46
+ // },
47
+ import styled from "vue-styled-components"
48
+ import {
49
+ stringToNumber,
50
+ numberToString,
51
+ } from "../../../helpers/numberConverter"
52
+
53
+ const Container = styled.div`
54
+ width: 100%;
55
+ position: relative;
56
+ `
57
+
58
+ const inputProps = {
59
+ isError: Boolean,
60
+ hasUnit: Boolean,
61
+ inputWidth: String,
62
+ hasLength: Boolean,
63
+ }
64
+ const InputContainer = styled("input", inputProps)`
65
+ border: 1px solid
66
+ ${(props) =>
67
+ props.isError
68
+ ? props.theme.colors.red
69
+ : props.hasLength
70
+ ? props.theme.colors.primary
71
+ : props.theme.colors.mediumGray};
72
+ padding: ${(props) =>
73
+ props.hasUnit ? "11px 40px 11px 10px" : "11px 5px 11px 10px"};
74
+ border-radius: 4px;
75
+ font-size: 16px;
76
+ color: ${(props) =>
77
+ props.isError ? props.theme.colors.red : props.theme.colors.primary};
78
+ width: ${(props) => (props.inputWidth ? props.inputWidth : "auto")};
79
+
80
+ &::placeholder {
81
+ color: ${(props) =>
82
+ props.isError ? props.theme.colors.red : props.theme.colors.darkGray};
83
+ }
84
+
85
+ &:focus {
86
+ outline: none;
87
+ }
88
+ `
89
+
90
+ const InputWrapper = styled.span`
91
+ position: relative;
92
+ `
93
+
94
+ const UnitContainer = styled("span", inputProps)`
95
+ border-left: 1px solid
96
+ ${(props) =>
97
+ props.isError
98
+ ? props.theme.colors.red
99
+ : props.hasLength
100
+ ? props.theme.colors.primary
101
+ : props.theme.colors.mediumGray};
102
+ position: absolute;
103
+ right: 10px;
104
+ top: 0;
105
+ padding-left: 10px;
106
+ color: ${(props) =>
107
+ props.isError
108
+ ? props.theme.colors.red
109
+ : props.hasLength
110
+ ? props.theme.colors.primary
111
+ : props.theme.colors.mediumGray};
112
+ `
113
+
114
+ const ErrorMessage = styled.div`
115
+ font-size: 14px;
116
+ color: ${(props) => props.theme.colors.red};
117
+ padding-top: 16px;
118
+ `
119
+
120
+ export default {
121
+ name: "input-number",
122
+ components: {
123
+ Container,
124
+ InputContainer,
125
+ InputWrapper,
126
+ UnitContainer,
127
+ ErrorMessage,
128
+ },
129
+ data() {
130
+ return {
131
+ textInput: "",
132
+ numberPrecision: 0, // we set this on created. By default is 0
133
+ minValue: 0,
134
+ maxValue: 100,
135
+ }
136
+ },
137
+ props: {
138
+ placeholder: {
139
+ required: false,
140
+ default: "",
141
+ },
142
+ isError: {
143
+ required: false,
144
+ default: false,
145
+ },
146
+ question: {
147
+ required: true,
148
+ },
149
+ inputWidth: {
150
+ required: false,
151
+ default: null,
152
+ },
153
+ value: {
154
+ required: true,
155
+ default: null,
156
+ },
157
+ clearInput: {
158
+ required: false,
159
+ default: false,
160
+ },
161
+ errorMessage: {
162
+ required: false,
163
+ default: "Please insert a correct number",
164
+ },
165
+ },
166
+ methods: {
167
+ onChangeHandler($event) {
168
+ this.textInput = $event
169
+ let formattedValue = stringToNumber({
170
+ value: $event,
171
+ numberPrecision: this.numberPrecision,
172
+ })
173
+ if (isNaN(formattedValue)) {
174
+ this.textInput = ""
175
+ formattedValue = ""
176
+ }
177
+ this.$emit("input-change", formattedValue)
178
+ },
179
+ onInputBlur() {
180
+ let num = stringToNumber({
181
+ value: this.textInput,
182
+ numberPrecision: this.numberPrecision,
183
+ })
184
+ this.textInput = numberToString({
185
+ value: num,
186
+ numberPrecision: this.numberPrecision,
187
+ })
188
+ },
189
+ },
190
+ created() {
191
+ this.numberPrecision = this.question.number_format_precision
192
+ this.minValue = this.question.number_min_allowed
193
+ this.maxValue = this.question.number_max_allowed
194
+ if (this.value) {
195
+ this.textInput = numberToString({
196
+ value: this.value,
197
+ numberPrecision: this.numberPrecision,
198
+ })
199
+ }
200
+ },
201
+ watch: {
202
+ clearInput: function (value) {
203
+ if (value) {
204
+ // If the value is typed, then we should clear the textInput on Continue
205
+ this.textInput = ""
206
+ }
207
+ },
208
+ question: function (value) {
209
+ this.numberPrecision = value.number_format_precision
210
+ this.minValue = value.number_min_allowed
211
+ this.maxValue = value.number_max_allowed
212
+ },
213
+ },
214
+ }
215
+ </script>
@@ -0,0 +1,144 @@
1
+ <template>
2
+ <container>
3
+ <input-wrapper>
4
+ <label-wrapper v-if="label">
5
+ <input-label>{{ label }}</input-label>
6
+ <info-text
7
+ v-if="infoTextMessage"
8
+ :text="infoTextMessage"
9
+ borderColor="#ccc"
10
+ size="16"
11
+ :alignText="infoTextAlign"
12
+ />
13
+ </label-wrapper>
14
+ <input-container
15
+ :placeholder="placeholder"
16
+ :isError="isError"
17
+ :inputWidth="inputWidth"
18
+ :value="value"
19
+ @input="onChangeHandler"
20
+ />
21
+ </input-wrapper>
22
+ <error-message v-if="isError">{{ errorMessage }}</error-message>
23
+ </container>
24
+ </template>
25
+
26
+ <script>
27
+ import styled from "vue-styled-components"
28
+ import InfoText from "../../infoText"
29
+
30
+ const Container = styled.div`
31
+ width: 100%;
32
+ position: relative;
33
+ `
34
+
35
+ const InputLabel = styled.div`
36
+ font-weight: bold;
37
+ `
38
+
39
+ const LabelWrapper = styled.div`
40
+ display: inline-grid;
41
+ grid-template-columns: auto 1fr;
42
+ grid-gap: 12px;
43
+ align-items: center;
44
+ margin-bottom: 12px;
45
+ `
46
+
47
+ const inputProps = { isError: Boolean, inputWidth: String }
48
+ const InputContainer = styled("input", inputProps)`
49
+ border: ${(props) =>
50
+ props.isError
51
+ ? "1px solid " + props.theme.colors.red
52
+ : "1px solid " + props.theme.colors.mediumGray};
53
+ padding: ${(props) =>
54
+ props.hasUnit ? "11px 40px 11px 10px" : "11px 5px 11px 10px"};
55
+ border-radius: 4px;
56
+ font-size: 16px;
57
+ color: ${(props) =>
58
+ props.isError ? props.theme.colors.red : props.theme.colors.black};
59
+ width: 100%;
60
+ box-sizing: border-box; // to allow width of 100% with padding
61
+ font-weight: 500;
62
+
63
+ &::placeholder {
64
+ color: ${(props) =>
65
+ props.isError ? props.theme.colors.red : props.theme.colors.darkGray};
66
+ }
67
+
68
+ &:focus {
69
+ outline: none;
70
+ }
71
+ `
72
+
73
+ const InputWrapper = styled.span`
74
+ position: relative;,
75
+ `
76
+
77
+ const ErrorMessage = styled.div`
78
+ font-size: 14px;
79
+ color: ${(props) => props.theme.colors.red};
80
+ position: absolute;
81
+ bottom: -18px;
82
+ `
83
+
84
+ export default {
85
+ // import InputText from "@eturnity/eturnity_reusable_components/src/components/inputs/inputText"
86
+ // To use:
87
+ // <input-text
88
+ // placeholder="Company name"
89
+ // :value="companyName"
90
+ // @input-change="onInputChange({ value: $event, type: 'companyName' })"
91
+ // :isError="checkErrors()"
92
+ // :errorMessage="This is my error message"
93
+ // infoTextAlign="right" // left by default
94
+ // infoTextMessage="My info message"
95
+ // label="Question 5"
96
+ // />
97
+ name: "input-text",
98
+ components: {
99
+ Container,
100
+ InputContainer,
101
+ InputWrapper,
102
+ ErrorMessage,
103
+ InfoText,
104
+ InputLabel,
105
+ LabelWrapper,
106
+ },
107
+ props: {
108
+ placeholder: {
109
+ required: false,
110
+ default: "",
111
+ },
112
+ isError: {
113
+ required: false,
114
+ default: false,
115
+ },
116
+ inputWidth: {
117
+ required: false,
118
+ default: null,
119
+ },
120
+ value: {
121
+ required: true,
122
+ default: null,
123
+ },
124
+ errorMessage: {
125
+ required: false,
126
+ default: "",
127
+ },
128
+ infoTextMessage: {
129
+ required: false,
130
+ },
131
+ infoTextAlign: {
132
+ required: false,
133
+ },
134
+ label: {
135
+ required: false,
136
+ },
137
+ },
138
+ methods: {
139
+ onChangeHandler($event) {
140
+ this.$emit("input-change", $event)
141
+ },
142
+ },
143
+ }
144
+ </script>
@@ -0,0 +1,251 @@
1
+ <template>
2
+ <component-wrapper :layout="layout">
3
+ <radio-wrapper v-for="(item, index) in options" :key="item.value">
4
+ <label-container :size="size" :isDisabled="item.disabled">
5
+ <radio
6
+ type="radio"
7
+ :value="selectedOption"
8
+ @click="onInputHandler(item.value)"
9
+ :name="'radioButtons_' + radioName"
10
+ :checked="selectedOption === item.value"
11
+ :disabled="item.disabled"
12
+ />
13
+ <span class="checkmark"></span>
14
+ <label-text :isDisabled="item.disabled">{{ item.label }}</label-text>
15
+ <info-text v-if="item.infoText" :text="item.infoText" size="16" />
16
+ </label-container>
17
+ <image-container v-if="item.img">
18
+ <radio-image :src="item.img" />
19
+ <div class="search-icn-container" @click="toggleImageModal(index)">
20
+ <img
21
+ class="search-icn"
22
+ :src="require('../../../assets/icons/search_icon.png')"
23
+ />
24
+ </div>
25
+ </image-container>
26
+ <modal
27
+ v-if="item.img"
28
+ :isOpen="isImageOpen(index)"
29
+ @on-close="toggleImageModal(null)"
30
+ >
31
+ <modal-image-container>
32
+ <modal-image :src="item.img" />
33
+ </modal-image-container>
34
+ </modal>
35
+ </radio-wrapper>
36
+ </component-wrapper>
37
+ </template>
38
+
39
+ <script>
40
+ // import RadioButton from "@eturnity/eturnity_reusable_components/src/components/inputs/radioButton"
41
+ // To use:
42
+ // <radio-button
43
+ // :options="radioOptions"
44
+ // :selectedOption="checkedOption"
45
+ // @on-radio-change="onInputChange($event)"
46
+ // layout="vertical"
47
+ // size="large"
48
+ // />
49
+ // Data being passed should look like:
50
+ // radioOptions: [
51
+ // { label: 'Button 1', value: 'button_1', img: 'www.imagesrc.com', infoText: 'my info text' },
52
+ // { label: 'Button 2', value: 'button_2', img: 'www.imagesrc.com', infoText: 'my info text 2' },
53
+ // { label: 'Button 3', value: 'button_3', img: 'www.imagesrc.com', disabled: true },
54
+ // { label: 'Button 4', value: 'button_4', disabled: true }
55
+ // ]
56
+
57
+ import styled from "vue-styled-components"
58
+ import Modal from "../../modals/modal"
59
+ import InfoText from "../../infoText"
60
+
61
+ const wrapperProps = {
62
+ layout: String,
63
+ }
64
+ const ComponentWrapper = styled("div", wrapperProps)`
65
+ display: flex;
66
+ flex-direction: ${(props) =>
67
+ props.layout === "vertical" ? "column" : "row"};
68
+ grid-gap: 32px;
69
+ flex-wrap: wrap;
70
+ `
71
+
72
+ const Radio = styled.input`
73
+ cursor: pointer;
74
+ position: absolute;
75
+ opacity: 0;
76
+ cursor: pointer;
77
+ height: 0;
78
+ width: 0;
79
+
80
+ &:checked ~ .checkmark {
81
+ background-color: white;
82
+
83
+ &:after {
84
+ display: block;
85
+ }
86
+ }
87
+ `
88
+
89
+ const RadioWrapper = styled.div`
90
+ display: grid;
91
+ grid-gap: 10px;
92
+ `
93
+
94
+ const containerProps = { size: String, isDisabled: Boolean }
95
+ const LabelContainer = styled("label", containerProps)`
96
+ display: grid;
97
+ grid-template-columns: auto 1fr auto;
98
+ grid-gap: 16px;
99
+ align-items: center;
100
+ color: ${(props) =>
101
+ props.isDisabled ? props.theme.colors.disabled : props.theme.colors.black};
102
+ position: relative;
103
+ cursor: ${(props) => (props.isDisabled ? "not-allowed" : "pointer")};
104
+ font-size: 16px;
105
+ user-select: none;
106
+ flex: auto;
107
+ align-self: baseline;
108
+
109
+ .checkmark {
110
+ position: relative;
111
+ height: ${(props) =>
112
+ props.size === "large"
113
+ ? "23px"
114
+ : props.size === "medium"
115
+ ? "17px"
116
+ : "12px"};
117
+ width: ${(props) =>
118
+ props.size === "large"
119
+ ? "23px"
120
+ : props.size === "medium"
121
+ ? "17px"
122
+ : "12px"};
123
+ background-color: #fff;
124
+ border-radius: 100%;
125
+ border: 1px solid ${(props) => props.theme.colors.mediumGray};
126
+
127
+ &:after {
128
+ content: "";
129
+ position: absolute;
130
+ display: none;
131
+ }
132
+ }
133
+
134
+ .checkmark:after {
135
+ top: ${(props) =>
136
+ props.size === "large" ? "6px" : props.size === "medium" ? "5px" : "3px"};
137
+ left: ${(props) =>
138
+ props.size === "large" ? "7px" : props.size === "medium" ? "5px" : "3px"};
139
+ width: ${(props) =>
140
+ props.size === "large"
141
+ ? "10px"
142
+ : props.size === "medium"
143
+ ? "7px"
144
+ : "6px"};
145
+ height: ${(props) =>
146
+ props.size === "large"
147
+ ? "10px"
148
+ : props.size === "medium"
149
+ ? "7px"
150
+ : "6px"};
151
+ border-radius: 100%;
152
+ background: ${(props) => props.theme.colors.primary};
153
+ }
154
+ `
155
+
156
+ const textAttrs = { isDisabled: Boolean }
157
+ const LabelText = styled("div", textAttrs)`
158
+ color: ${(props) =>
159
+ props.isDisabled ? props.theme.colors.disabled : props.theme.colors.black};
160
+ `
161
+
162
+ const RadioImage = styled.img`
163
+ max-width: 100px;
164
+ `
165
+
166
+ const ImageContainer = styled.div`
167
+ border-radius: 4px;
168
+ cursor: pointer;
169
+ display: grid;
170
+ align-items: center;
171
+ justify-items: center;
172
+ position: relative;
173
+
174
+ .search-icn-container {
175
+ display: none;
176
+ }
177
+
178
+ &:hover {
179
+ .search-icn-container {
180
+ display: grid;
181
+ position: absolute;
182
+ background: rgba(0, 0, 0, 0.4);
183
+ width: 100%;
184
+ height: 100%;
185
+ align-items: center;
186
+ justify-items: center;
187
+ }
188
+ }
189
+ `
190
+
191
+ const ModalImage = styled.img``
192
+
193
+ const ModalImageContainer = styled.div`
194
+ padding: 40px;
195
+ `
196
+
197
+ export default {
198
+ name: "radio-button",
199
+ components: {
200
+ Radio,
201
+ ComponentWrapper,
202
+ LabelContainer,
203
+ RadioWrapper,
204
+ RadioImage,
205
+ ImageContainer,
206
+ Modal,
207
+ ModalImage,
208
+ ModalImageContainer,
209
+ InfoText,
210
+ LabelText,
211
+ },
212
+ props: {
213
+ selectedOption: {
214
+ required: true,
215
+ default: false,
216
+ },
217
+ options: {
218
+ required: true,
219
+ default: [],
220
+ },
221
+ layout: {
222
+ required: false,
223
+ default: "horizontal", //2 options: 'vertical' (only 1 per row) & 'horizontal' (many per row)
224
+ },
225
+ size: {
226
+ required: false,
227
+ default: "medium", // small, medium, large
228
+ },
229
+ },
230
+ data() {
231
+ return {
232
+ radioName: "",
233
+ selectedImage: null,
234
+ }
235
+ },
236
+ methods: {
237
+ onInputHandler(value) {
238
+ this.$emit("on-radio-change", value)
239
+ },
240
+ isImageOpen(index) {
241
+ return this.selectedImage === index
242
+ },
243
+ toggleImageModal(value) {
244
+ this.selectedImage = value
245
+ },
246
+ },
247
+ created() {
248
+ this.radioName = Math.round(Math.random() * 10000)
249
+ },
250
+ }
251
+ </script>
@@ -0,0 +1,126 @@
1
+ <template>
2
+ <container>
3
+ <Slider
4
+ :value="value"
5
+ @update="onChange($event)"
6
+ :tooltips="false"
7
+ :min="minValue"
8
+ :max="maxValue"
9
+ />
10
+ <number-text> {{ value }} {{ unit }} </number-text>
11
+ </container>
12
+ </template>
13
+
14
+ <script>
15
+ // import Slider from "@eturnity/eturnity_reusable_components/src/components/inputs/slider"
16
+ //To use:
17
+ // <slider
18
+ // :value="sliderValue" //required from parent
19
+ // unit="m" //optional
20
+ // @change="onChangeSlider($event)" //required to have @change in parent
21
+ // :minValue="10" //default is 0 if not specified
22
+ // :maxValue="500" //default is 100 if not specified
23
+ // />
24
+ import Slider from "@vueform/slider/dist/slider.vue2.js"
25
+ import styled from "vue-styled-components"
26
+
27
+ const Container = styled.div`
28
+ margin: 16px 0 16px 21px;
29
+ display: grid;
30
+ grid-template-columns: 1fr auto;
31
+ grid-gap: 40px;
32
+ align-items: center;
33
+
34
+ .slider-touch-area {
35
+ background-color: ${(props) => props.theme.colors.mediumGray};
36
+ border-radius: 100%;
37
+ display: flex;
38
+ grid-gap: 3px;
39
+ align-items: center;
40
+ justify-items: center;
41
+ box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
42
+
43
+ span {
44
+ // This is for the white lines on the button
45
+ width: 2px;
46
+ height: 10px;
47
+ background: white;
48
+ display: inline-block;
49
+
50
+ &:nth-of-type(1) {
51
+ margin-left: 7px;
52
+ }
53
+ }
54
+ }
55
+
56
+ .slider-connect {
57
+ background: ${(props) => props.theme.colors.blue};
58
+ }
59
+
60
+ .slider-base {
61
+ background-color: ${(props) => props.theme.colors.lightGray};
62
+ border-radius: 0;
63
+ }
64
+
65
+ .slider-connects {
66
+ border-radius: 0;
67
+ }
68
+
69
+ .slider-handle {
70
+ //we need to override the default values coming from the package
71
+ height: 26px !important;
72
+ width: 26px !important;
73
+ top: -11px !important;
74
+ }
75
+ `
76
+
77
+ const NumberText = styled.div`
78
+ font-weight: 500;
79
+ font-size: 24px;
80
+ color: ${(props) => props.theme.colors.black};
81
+ `
82
+
83
+ export default {
84
+ name: "slider",
85
+ components: {
86
+ Slider,
87
+ Container,
88
+ NumberText,
89
+ },
90
+ props: {
91
+ value: {
92
+ required: false,
93
+ default: 0,
94
+ },
95
+ unit: {
96
+ required: false,
97
+ default: "",
98
+ },
99
+ minValue: {
100
+ required: false,
101
+ default: 0,
102
+ },
103
+ maxValue: {
104
+ required: false,
105
+ default: 100,
106
+ },
107
+ },
108
+ methods: {
109
+ onChange(value) {
110
+ this.$emit("change", value)
111
+ },
112
+ },
113
+ mounted() {
114
+ // This is to add the 3 white lines to the slider button
115
+ let slider = document.querySelector(".slider-touch-area")
116
+ let span1 = document.createElement("span")
117
+ let span2 = document.createElement("span")
118
+ let span3 = document.createElement("span")
119
+ slider.appendChild(span1)
120
+ slider.appendChild(span2)
121
+ slider.appendChild(span3)
122
+ },
123
+ }
124
+ </script>
125
+
126
+ <style src="@vueform/slider/themes/default.css"></style>
@@ -12,6 +12,7 @@
12
12
  </template>
13
13
 
14
14
  <script>
15
+ // import Modal from "@eturnity/eturnity_reusable_components/src/components/modals/modal"
15
16
  // This is a more flexible modal box, where the parent can decide how the body of the modal looks
16
17
  // To use:
17
18
  // <modal :isOpen="isOpen" @on-close="$emit('on-close-summary')">
@@ -59,7 +60,7 @@ const ModalContainer = styled.div`
59
60
  background: white;
60
61
  margin: 0 auto;
61
62
  overflow: auto;
62
- max-width: 600px;
63
+ max-width: 95%;
63
64
  max-height: 95%;
64
65
  min-width: 100px;
65
66
  min-height: 100px;
@@ -0,0 +1,41 @@
1
+ export const stringToNumber = ({ value, numberPrecision }) => {
2
+ // This is for saving. It converts our input string to a readable number
3
+ let newVal = value.toString()
4
+ const selectedLang = localStorage.getItem("lang")
5
+ // The first replace will replace not allowed characters with a blank
6
+ if (selectedLang === "de-DE" || selectedLang === "it-CH") {
7
+ // replace commas with a dot, and dots with blank
8
+ newVal = newVal
9
+ .replace(/[^\d.,']/g, "")
10
+ .replace(/[.\s]/, "")
11
+ .replace(/[,\s]/, ".")
12
+ } else if (selectedLang === "en-us") {
13
+ // replace commas with blank
14
+ newVal = newVal.replace(/[^\d.,']/g, "").replace(/[,\s]/, "")
15
+ } else if (
16
+ selectedLang === "de-ch" ||
17
+ selectedLang === "fr-ch" ||
18
+ selectedLang === "it-ch"
19
+ ) {
20
+ // replace ' with blank
21
+ newVal = newVal.replace(/[^\d.,']/g, "").replace(/['\s]/, "")
22
+ } else if (selectedLang === "fr-fr") {
23
+ // replace space with blank, and commas with dot
24
+ newVal = newVal.replace(/[^\d.,']/g, "").replace(/[,\s]/, ".")
25
+ } else {
26
+ // en-US as default
27
+ newVal = newVal.replace(/[^\d.,']/g, "").replace(/[,\s]/, "")
28
+ }
29
+ newVal = parseFloat(newVal).toFixed(numberPrecision)
30
+ return parseFloat(newVal)
31
+ }
32
+
33
+ export const numberToString = ({ value, numberPrecision }) => {
34
+ let selectedLang = localStorage.getItem("lang")
35
+ ? localStorage.getItem("lang")
36
+ : "en-US"
37
+ return value.toLocaleString(selectedLang, {
38
+ minimumFractionDigits: numberPrecision,
39
+ maximumFractionDigits: numberPrecision,
40
+ })
41
+ }
package/src/main.js CHANGED
@@ -1,8 +1,11 @@
1
- import Vue from 'vue'
2
- import App from './App.vue'
1
+ import Vue from "vue"
2
+ import App from "./App.vue"
3
+ import VueCompositionAPI from "@vue/composition-api"
3
4
 
4
5
  Vue.config.productionTip = false
5
6
 
7
+ Vue.use(VueCompositionAPI)
8
+
6
9
  new Vue({
7
- render: h => h(App),
8
- }).$mount('#app')
10
+ render: (h) => h(App),
11
+ }).$mount("#app")