@kvass/widgets 1.0.17 → 1.1.0

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.
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div class="project-selector-card" :class="'project-selector-card--' + theme">
3
+ <component
4
+ :is="item.url && !['development'].includes(status) ? 'a' : 'div'"
5
+ class="project-selector-card__header"
6
+ :href="item.url"
7
+ >
8
+ <div v-if="!disableLabel" class="project-selector-card__header-category">
9
+ <Category :value="status" component="div" active />
10
+ </div>
11
+ <div
12
+ class="project-selector-card__header-cover"
13
+ :style="{ backgroundImage: `url(${cover})` }"
14
+ ></div>
15
+ </component>
16
+ <div class="project-selector-card__content">
17
+ <h2 class="project-selector-card__content-name">
18
+ {{ item.name }}
19
+ </h2>
20
+
21
+ <span
22
+ v-if="item.address && item.address.city"
23
+ class="project-selector-card__content-location"
24
+ >
25
+ <svg
26
+ aria-hidden="true"
27
+ focusable="false"
28
+ data-prefix="fas"
29
+ data-icon="map-pin"
30
+ role="img"
31
+ xmlns="http://www.w3.org/2000/svg"
32
+ viewBox="0 0 288 512"
33
+ >
34
+ <path
35
+ fill="currentColor"
36
+ d="M112 316.94v156.69l22.02 33.02c4.75 7.12 15.22 7.12 19.97 0L176 473.63V316.94c-10.39 1.92-21.06 3.06-32 3.06s-21.61-1.14-32-3.06zM144 0C64.47 0 0 64.47 0 144s64.47 144 144 144 144-64.47 144-144S223.53 0 144 0zm0 76c-37.5 0-68 30.5-68 68 0 6.62-5.38 12-12 12s-12-5.38-12-12c0-50.73 41.28-92 92-92 6.62 0 12 5.38 12 12s-5.38 12-12 12z"
37
+ ></path>
38
+ </svg>
39
+
40
+ <span class="project-selector-card__content-city">
41
+ {{ item.address ? item.address.city : '' }}
42
+ </span>
43
+ </span>
44
+ <div
45
+ class="project-selector-card__content-intro"
46
+ v-html="item.intro"
47
+ ></div>
48
+ <a
49
+ v-if="item.url && !['development'].includes(status)"
50
+ class="project-selector-card__content-url"
51
+ :href="item.url"
52
+ >
53
+ Se prosjektet</a
54
+ >
55
+ </div>
56
+ </div>
57
+ </template>
58
+
59
+ <script setup>
60
+ import Category from './Category.ce.vue'
61
+ import { ref } from 'vue'
62
+ import { computed } from '@vue/reactivity'
63
+
64
+ const props = defineProps({
65
+ item: {
66
+ type: Object,
67
+ default: () => ({}),
68
+ },
69
+ theme: {
70
+ type: String,
71
+ default: 'default',
72
+ enums: ['default', 'primary', 'flat'],
73
+ },
74
+ disableLabel: {
75
+ type: Boolean,
76
+ default: false,
77
+ },
78
+ })
79
+
80
+ const cover = computed(() => {
81
+ return (
82
+ getImage(
83
+ props.item.media && props.item.media.cover
84
+ ? props.item.media.cover
85
+ : null,
86
+ ) ||
87
+ getImage(
88
+ props.item.media && props.item.media.gallery
89
+ ? props.item.media.gallery
90
+ : null,
91
+ )
92
+ )
93
+ })
94
+
95
+ const status = computed(() => props.item.status)
96
+
97
+ function getImage(value) {
98
+ if (!value || !value.length) return
99
+ let result = value.find((i) => {
100
+ if (i.type) return i.type.startsWith('image')
101
+ return i
102
+ })
103
+ if (!result) return
104
+ return result.url
105
+ }
106
+ </script>
107
+
108
+ <style lang="scss">
109
+ @import '../styles/components/card';
110
+ </style>
@@ -0,0 +1,87 @@
1
+ <template>
2
+ <component
3
+ class="category"
4
+ :class="[`category--${status}`, { 'category--active': active }]"
5
+ :is="component"
6
+ >
7
+ <span>{{ label }}</span>
8
+ </component>
9
+ </template>
10
+
11
+ <script setup>
12
+ import { computed } from '@vue/reactivity'
13
+ const themeMap = {
14
+ sale: 'sale',
15
+ upcoming: 'upcoming',
16
+ development: 'development',
17
+ sold: 'sold',
18
+ }
19
+
20
+ const categoryMap = {
21
+ sale: 'Til salgs',
22
+ upcoming: 'Kommer for salg',
23
+ development: 'Under utvikling',
24
+ all: 'Alle',
25
+ sold: 'Utsolgt',
26
+ }
27
+
28
+ const props = defineProps({
29
+ value: {
30
+ type: String,
31
+ default: 'development',
32
+ },
33
+ component: {
34
+ type: String,
35
+ default: 'div',
36
+ },
37
+ active: {
38
+ type: Boolean,
39
+ },
40
+ })
41
+
42
+ const status = computed(() => {
43
+ if (themeMap[props.value]) return themeMap[props.value]
44
+ return 'default'
45
+ })
46
+
47
+ const label = computed(() => categoryMap[props.value])
48
+ </script>
49
+
50
+ <style lang="scss">
51
+ .category {
52
+ @import '../styles/_variables';
53
+ padding: 1rem 1.5rem;
54
+ border: none;
55
+ border-radius: GetVariable('border-radius');
56
+ font-size: 0.9em;
57
+ background-color: GetVariable('light-grey');
58
+
59
+ &:focus-visible {
60
+ outline: 2px solid GetVariable('primary');
61
+ outline-offset: 2px;
62
+ }
63
+
64
+ &--primary.category--active {
65
+ background-color: GetVariable('primary');
66
+ }
67
+ &--sale.category--active {
68
+ background-color: GetVariable('sale');
69
+ }
70
+ &--sold.category--active {
71
+ background-color: GetVariable('sold');
72
+ }
73
+ &--development.category--active {
74
+ background-color: GetVariable('development');
75
+ }
76
+ &--upcoming.category--active {
77
+ background-color: GetVariable('upcoming');
78
+ }
79
+ &--default.category--active {
80
+ background-color: GetVariable('default');
81
+ }
82
+
83
+ &--active {
84
+ color: white;
85
+ }
86
+ }
87
+ </style>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <div class="project-selector-category">
3
+ <CategoryTrigger
4
+ v-for="(item, index) in items"
5
+ :key="index"
6
+ class="project-selector-category__selector"
7
+ :value="item"
8
+ :active="value == item"
9
+ component="button"
10
+ @click.native="$emit('input', item)"
11
+ />
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import CategoryTrigger from './Category.ce.vue'
17
+
18
+ const props = defineProps({
19
+ items: {
20
+ type: Array,
21
+ default: () => [],
22
+ },
23
+ value: {
24
+ type: String,
25
+ },
26
+ })
27
+ </script>
28
+
29
+ <style lang="scss">
30
+ .project-selector-category {
31
+ @import '../styles/_variables';
32
+
33
+ &__selector {
34
+ @media (max-width: $kvass-project-selector-resposive) {
35
+ width: 100%;
36
+ }
37
+ &:hover {
38
+ box-shadow: inset 0 0 0 2em rgba(74, 74, 74, 0.2);
39
+ }
40
+ cursor: pointer;
41
+ }
42
+ }
43
+ </style>
@@ -0,0 +1,70 @@
1
+ <template>
2
+ <select class="project-type-selector__trigger">
3
+ <option
4
+ v-for="(item, index) in items"
5
+ :key="index"
6
+ :value="item"
7
+ @change="$emit('input', item)"
8
+ class="project-type-selector__dropdown-item"
9
+ >
10
+ {{ Capitalize(item === 'none' ? 'Velg type' : item) }}
11
+ </option>
12
+ </select>
13
+ </template>
14
+
15
+ <script setup>
16
+ function Capitalize(value) {
17
+ return value.charAt(0).toUpperCase() + value.substring(1)
18
+ }
19
+
20
+ const props = defineProps({
21
+ items: {
22
+ type: Array,
23
+ default: () => [],
24
+ },
25
+ value: {
26
+ type: String,
27
+ },
28
+ })
29
+ </script>
30
+
31
+ <style lang="scss">
32
+ @import '../styles/_variables';
33
+ .project-type-selector {
34
+ .elder-dropdown__content {
35
+ z-index: 11;
36
+ }
37
+ &__trigger {
38
+ // remove select arrow
39
+ appearance: none;
40
+
41
+ /* for IE 10 */
42
+ &:-ms-expand {
43
+ display: none;
44
+ }
45
+
46
+ padding: 1rem 2rem;
47
+ border: none;
48
+ border-radius: GetVariable('border-radius');
49
+ font-size: 0.9em;
50
+ background-color: GetVariable('primary');
51
+ color: white;
52
+
53
+ @media (max-width: $kvass-project-selector-resposive) {
54
+ width: 100%;
55
+ }
56
+ }
57
+ &__dropdown-item {
58
+ &--selected {
59
+ background-color: rgba(143, 143, 143, 0.4);
60
+ }
61
+ text-align: center !important;
62
+ padding: 0.5rem 1.5rem;
63
+ font-size: 0.9em;
64
+
65
+ &:hover {
66
+ background-color: rgba(36, 36, 36, 0.4);
67
+ }
68
+ }
69
+ }
70
+ </style>
@@ -0,0 +1,16 @@
1
+ import { defineCustomElement } from 'vue'
2
+ import App from './App.ce.vue'
3
+ import Card from './components/Card.ce.vue'
4
+ import Category from './components/Category.ce.vue'
5
+ import CategorySelector from './components/CategorySelector.ce.vue'
6
+ import ProjectTypeSelector from './components/ProjectTypeSelector.ce.vue'
7
+
8
+ App.styles = [
9
+ ...App.styles,
10
+ ...Card.styles,
11
+ ...Category.styles,
12
+ ...CategorySelector.styles,
13
+ ...ProjectTypeSelector.styles,
14
+ ]
15
+
16
+ customElements.define('kvass-project-portal', defineCustomElement(App))
@@ -0,0 +1,19 @@
1
+ $kvass-project-selector-resposive: 767px;
2
+
3
+ $variables: (
4
+ 'primary': #0523a8,
5
+ 'secondary': #3d495b,
6
+ 'background-color': #efeded,
7
+ 'dark': #272727,
8
+ 'sale': #2da71d,
9
+ 'sold': #cc3434,
10
+ 'upcoming': #e9b03d,
11
+ 'development': #3d495b,
12
+ 'border-radius': 3px,
13
+ 'card-spacing': 2.5rem,
14
+ 'light-grey': #efefef,
15
+ );
16
+
17
+ @function GetVariable($key) {
18
+ @return var(--kvass-project-selector-#{$key}, map-get($variables, $key));
19
+ }
@@ -0,0 +1,178 @@
1
+ @import '../_variables';
2
+
3
+ .project-selector-card {
4
+ position: relative;
5
+ font-family: var(--kvass-project-selector-secondary-font, inherit);
6
+ display: flex;
7
+ flex-direction: column;
8
+ border-radius: GetVariable('border-radius');
9
+ background-color: white;
10
+ text-decoration: none;
11
+ color: inherit;
12
+ overflow: hidden;
13
+
14
+ $space: GetVariable('card-spacing');
15
+
16
+ &__header {
17
+ min-height: var(--kvass-project-selector-header-min-height, 250px);
18
+ background-color: GetVariable('dark');
19
+
20
+ @media (max-width: $kvass-project-selector-resposive) {
21
+ min-height: var(
22
+ --kvass-project-selector-header-min-height-resposive,
23
+ 150px
24
+ );
25
+ }
26
+
27
+ &-category {
28
+ position: absolute;
29
+ background-color: GetVariable('secondary');
30
+ z-index: 11;
31
+ color: white;
32
+ left: var(--kvass-project-selector-card-status-gap, 0.5rem);
33
+ top: var(--kvass-project-selector-card-status-gap, 0.5rem);
34
+ border-radius: GetVariable('border-radius');
35
+ .category {
36
+ font-size: var(--kvass-project-selector-card-status-font-size, 0.8em);
37
+ padding: var(--kvass-project-selector-card-status-padding-x, 0.5rem)
38
+ var(--kvass-project-selector-card-status-padding-x, 1rem);
39
+ }
40
+ }
41
+
42
+ &-cover {
43
+ width: 100%;
44
+ background-repeat: no-repeat;
45
+ height: 100%;
46
+ background-size: cover;
47
+ background-position: center;
48
+ transition: transform 0.62s cubic-bezier(0.05, 0.2, 0.1, 1);
49
+
50
+ &:hover {
51
+ transform: scale(1.11);
52
+ -webkit-transform: scale(1.11);
53
+ }
54
+ }
55
+ }
56
+
57
+ &__title {
58
+ font-weight: bold;
59
+ line-height: 1;
60
+ margin: 0;
61
+ }
62
+
63
+ &__content {
64
+ background-color: GetVariable('background-color');
65
+ border-top: none;
66
+ text-align: left;
67
+ display: flex;
68
+ flex-direction: column;
69
+ gap: 0.5rem;
70
+ padding: calc(#{$space} - 0.5rem);
71
+
72
+ height: 100%;
73
+
74
+ &-name {
75
+ color: GetVariable('dark');
76
+ margin: 0 !important;
77
+ }
78
+
79
+ &-url {
80
+ color: GetVariable('primary');
81
+ font-size: 1.1em;
82
+ margin-top: auto;
83
+ text-decoration: underline;
84
+ text-decoration-color: GetVariable('primary');
85
+ text-underline-offset: 0.3em;
86
+ text-decoration-thickness: 1px;
87
+
88
+ &:hover {
89
+ color: GetVariable('secondary');
90
+ }
91
+ }
92
+
93
+ &-city {
94
+ font-size: 1.2rem;
95
+ }
96
+
97
+ &-location {
98
+ display: flex;
99
+ align-items: center;
100
+ align-content: center;
101
+ gap: 1rem;
102
+ color: GetVariable('secondary');
103
+
104
+ svg {
105
+ opacity: 0.5;
106
+ height: 0.9rem;
107
+ path {
108
+ color: currentColor;
109
+ }
110
+ }
111
+ }
112
+
113
+ @media (max-width: $kvass-project-selector-resposive) {
114
+ gap: 0.5rem;
115
+ padding: calc(#{$space} - 0.5rem) calc(#{$space} - 1rem);
116
+ }
117
+ }
118
+ }
119
+
120
+ // tiles theme
121
+ .project-selector--theme-tiles {
122
+ .project-selector-card {
123
+ border-radius: var(--kvass-project-selector-border-radius, 0px);
124
+
125
+ &:hover {
126
+ .project-selector-card__content {
127
+ background: rgba(0, 0, 0, 0.2) !important;
128
+ }
129
+ }
130
+
131
+ &__header {
132
+ min-height: var(--kvass-project-selector-header-min-height, 400px);
133
+
134
+ @media (max-width: $kvass-project-selector-resposive) {
135
+ min-height: var(
136
+ --kvass-project-selector-header-min-height-resposive,
137
+ 250px
138
+ );
139
+ }
140
+ }
141
+
142
+ &__content {
143
+ font-size: 1.5rem;
144
+ height: unset !important;
145
+ position: absolute;
146
+ inset: 0;
147
+ z-index: 10;
148
+ pointer-events: none;
149
+ background: rgba(0, 0, 0, 0.4) !important;
150
+ transition: background 200ms ease;
151
+
152
+ display: grid !important;
153
+ place-content: center;
154
+
155
+ & > * {
156
+ color: white !important;
157
+ text-align: center;
158
+ }
159
+
160
+ &-url {
161
+ text-decoration-color: currentColor;
162
+ font-size: 0.8em;
163
+ }
164
+
165
+ &-location {
166
+ justify-content: center;
167
+ margin-bottom: 1rem;
168
+
169
+ svg {
170
+ display: none;
171
+ }
172
+ }
173
+ &-intro {
174
+ font-size: 0.8em;
175
+ }
176
+ }
177
+ }
178
+ }
package/vite.config.js CHANGED
@@ -1,6 +1,6 @@
1
+ import vue from '@vitejs/plugin-vue'
1
2
  import { fileURLToPath } from 'url'
2
3
  import { defineConfig } from 'vite'
3
- import vue from '@vitejs/plugin-vue'
4
4
 
5
5
  // https://vitejs.dev/config/
6
6
  export default defineConfig({
@@ -11,14 +11,16 @@ export default defineConfig({
11
11
  manualChunks: false,
12
12
  entryFileNames: `[name].js`,
13
13
  chunkFileNames: `[name].js`,
14
- assetFileNames: `[name].[ext]`
14
+ assetFileNames: `[name].[ext]`,
15
15
  },
16
16
  input: {
17
- contact: fileURLToPath(new URL('./src/contact/main.js', import.meta.url))
18
- }
19
- }
17
+ contact: fileURLToPath(new URL('./src/contact/main.js', import.meta.url)),
18
+ 'img-comparison-slider': fileURLToPath(new URL('./src/img-comparison-slider/main.js', import.meta.url)),
19
+ 'project-portal': fileURLToPath(new URL('./src/project-portal/main.js', import.meta.url)),
20
+ },
21
+ },
20
22
  },
21
23
  server: {
22
- port: 3001
23
- }
24
+ port: 3001,
25
+ },
24
26
  })