@policystudio/policy-studio-ui-vue 1.1.14 → 1.1.18

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.
@@ -1250,6 +1250,7 @@ video {
1250
1250
  color: #798490;
1251
1251
  color: rgba(121, 132, 144, var(--text-opacity));
1252
1252
  margin-top: 0.25rem;
1253
+ font-style: italic;
1253
1254
  font-size: 12px;
1254
1255
  line-height: 15.6px;
1255
1256
  }
@@ -2916,38 +2917,104 @@ video {
2916
2917
 
2917
2918
  .psui-el-dropdown-menu-list {
2918
2919
  width: 100%;
2919
- font-weight: 700;
2920
- margin-top: 0.75rem;
2921
- margin-bottom: 0.75rem;
2920
+ display: flex;
2921
+ flex-direction: column;
2922
+ font-weight: 500;
2923
+ margin-top: 1rem;
2924
+ margin-bottom: 1rem;
2922
2925
  }
2923
2926
 
2924
- .psui-el-dropdown-menu-list li {
2925
- width: 100%;
2927
+ .psui-el-dropdown-menu-list-item {
2928
+ display: flex;
2929
+ align-items: flex-end;
2930
+ justify-content: space-between;
2931
+ font-size: 16px;
2932
+ line-height: 130%;
2933
+ border-radius: 0.375rem;
2926
2934
  --text-opacity: 1;
2927
2935
  color: #515E6A;
2928
2936
  color: rgba(81, 94, 106, var(--text-opacity));
2929
- font-size: 14px;
2930
- line-height: 130%;
2931
- list-style-type: none;
2932
- display: flex;
2933
- flex-direction: column;
2937
+ margin-left: 1rem;
2938
+ margin-right: 1rem;
2934
2939
  cursor: pointer;
2935
- padding: 7px 20px;
2936
- font-weight: 700;
2940
+ transition-property: all;
2937
2941
  }
2938
2942
 
2939
- .psui-el-dropdown-menu-list li:hover {
2940
- --text-opacity: 1;
2941
- color: #318FAC;
2942
- color: rgba(49, 143, 172, var(--text-opacity));
2943
+ .psui-el-dropdown-menu-list-item:hover * {
2944
+ opacity: 1 !important;
2945
+ }
2946
+
2947
+ .psui-el-dropdown-menu-list-item.absolute-childrens {
2948
+ position: relative;
2949
+ }
2950
+
2951
+ .psui-el-dropdown-menu-list-item.absolute-childrens .helper {
2952
+ position: absolute;
2953
+ top: 0;
2954
+ right: -18px;
2955
+ }
2956
+
2957
+ .psui-el-dropdown-menu-list-item{
2958
+ padding: 11.5px 16px 11.5px 8px;
2959
+ }
2960
+
2961
+ .psui-el-dropdown-menu-list-item:hover {
2962
+ --bg-opacity: 1;
2963
+ background-color: #F3F6F9;
2964
+ background-color: rgba(243, 246, 249, var(--bg-opacity));
2965
+ }
2966
+
2967
+ .psui-el-dropdown-menu-list-item-left-label {
2968
+ font-weight: 700;
2969
+ display: flex;
2970
+ align-items: center;
2971
+ flex: 0 1 auto;
2972
+ width: auto;
2973
+ }
2974
+
2975
+ .psui-el-dropdown-menu-list-item-line {
2976
+ display: flex;
2977
+ flex: 1 1 0%;
2978
+ border-bottom-width: 1px;
2979
+ --border-opacity: 1;
2980
+ border-color: #A2ACB7;
2981
+ border-color: rgba(162, 172, 183, var(--border-opacity));
2982
+ border-style: dashed;
2983
+ margin-left: 0.5rem;
2984
+ margin-right: 0.5rem;
2985
+ margin-bottom: 0.25rem;
2986
+ }
2987
+
2988
+ .psui-el-dropdown-menu-list-item-right-label {
2989
+ display: flex;
2990
+ flex: 0 1 auto;
2991
+ width: auto;
2992
+ font-weight: 400;
2993
+ }
2994
+
2995
+ .psui-el-dropdown-menu-list-item.is-selected {
2943
2996
  --bg-opacity: 1;
2944
2997
  background-color: #ECF7FB;
2945
2998
  background-color: rgba(236, 247, 251, var(--bg-opacity));
2999
+ --text-opacity: 1;
3000
+ color: #318FAC;
3001
+ color: rgba(49, 143, 172, var(--text-opacity));
2946
3002
  }
2947
3003
 
2948
- .psui-el-dropdown-menu-list li span {
2949
- width: 100%;
2950
- }
3004
+ .psui-el-dropdown-menu-list-item.is-selected .psui-el-dropdown-menu-list-item-line {
3005
+ --border-opacity: 1;
3006
+ border-color: #318FAC;
3007
+ border-color: rgba(49, 143, 172, var(--border-opacity));
3008
+ }
3009
+
3010
+ .psui-el-dropdown-menu-list-item.is-selected:hover {
3011
+ --bg-opacity: 1;
3012
+ background-color: #ECF7FB;
3013
+ background-color: rgba(236, 247, 251, var(--bg-opacity));
3014
+ --text-opacity: 1;
3015
+ color: #318FAC;
3016
+ color: rgba(49, 143, 172, var(--text-opacity));
3017
+ }
2951
3018
 
2952
3019
  .psui-el-slider .psui-el-slider-label {
2953
3020
  margin-bottom: 0.5rem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@policystudio/policy-studio-ui-vue",
3
- "version": "1.1.14",
3
+ "version": "1.1.18",
4
4
  "description": "Policy Studio UI",
5
5
  "main": "src/index.js",
6
6
  "author": "Policy Studio Team",
@@ -1,19 +1,38 @@
1
1
  @layer components {
2
- .psui-el-dropdown-menu-list {
3
- @apply psui-w-full psui-font-bold psui-my-3;
2
+ .psui-el-dropdown-menu-list {
3
+ @apply psui-w-full psui-flex psui-flex-col psui-font-medium psui-my-4;
4
4
 
5
- li {
6
- @apply psui-w-full psui-text-gray-60 psui-text-small psui-list-none psui-flex psui-flex-col psui-cursor-pointer;
7
- padding: 7px 20px;
8
- font-weight: 700;
5
+ &-item {
6
+ @apply psui-flex psui-items-end psui-justify-between psui-text-p psui-rounded-md psui-text-gray-60 psui-mx-4 psui-cursor-pointer psui-transition-all psui-show-childrens-on-hover;
7
+ padding: 11.5px 16px 11.5px 8px;
9
8
 
10
- &:hover {
11
- @apply psui-text-blue-60 psui-bg-blue-10;
12
- }
9
+ &:hover {
10
+ @apply psui-bg-gray-10;
11
+ }
13
12
 
14
- span {
15
- @apply psui-w-full;
16
- }
13
+ &-left-label {
14
+ @apply psui-font-bold psui-flex psui-items-center psui-flex-initial psui-w-auto;
15
+ }
16
+
17
+ &-line {
18
+ @apply psui-flex psui-flex-1 psui-border-b psui-border-gray-40 psui-border-dashed psui-mx-2 psui-mb-1;
19
+ }
20
+
21
+ &-right-label {
22
+ @apply psui-flex psui-flex-initial psui-w-auto psui-font-normal;
23
+ }
24
+
25
+ &.is-selected {
26
+ @apply psui-bg-blue-10 psui-text-blue-60;
27
+
28
+ .psui-el-dropdown-menu-list-item-line {
29
+ @apply psui-border-blue-60;
30
+ }
31
+
32
+ &:hover {
33
+ @apply psui-bg-blue-10 psui-text-blue-60;
17
34
  }
35
+ }
18
36
  }
37
+ }
19
38
  }
@@ -11,7 +11,7 @@
11
11
  }
12
12
 
13
13
  &-hint {
14
- @apply psui-text-gray-50 psui-mt-1;
14
+ @apply psui-text-gray-50 psui-mt-1 psui-italic;
15
15
  font-size: 12px;
16
16
  line-height: 15.6px;
17
17
  }
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <div class="psui-el-dropdown-menu" ref="PSDropdown" v-click-outside="close">
2
+ <div
3
+ ref="PSDropdown"
4
+ class="psui-el-dropdown-menu"
5
+ :class="{ 'is-open' : show }"
6
+ v-click-outside="close"
7
+ >
3
8
  <div
4
9
  ref="PSDropdownTrigger"
5
10
  v-if="$slots.dropdownTrigger"
@@ -1,23 +1,75 @@
1
1
  <template>
2
- <ul class="psui-el-dropdown-menu-list">
2
+ <ul
3
+ class="psui-el-dropdown-menu-list"
4
+ :class="`layout-${layout}`"
5
+ >
3
6
  <li
4
- v-for="item in getItems"
5
- :key="getKeyValue(item)"
7
+ v-for="(item, index) in getItems"
8
+ :key="`${index}-${getKeyValue(item)}`"
9
+ :id="`${index}-${getKeyValue(item)}`"
10
+ :class="{ 'is-selected psui-bg-blue-10 psui-text-blue-60 hover:psui-bg-blue-10 hover:psui-text-blue-60' : getSelected === getKeyValue(item) }"
11
+ class="psui-el-dropdown-menu-list-item"
12
+ @mouseover="isHovering = index"
13
+ @mouseout="isHovering = false"
6
14
  @click="selectItem(item)"
7
15
  >
8
- <span>{{ getKeyLabel(item) }}</span>
16
+ <div class="psui-el-dropdown-menu-list-item-left-label">
17
+ {{ getLeftLabel(item) }}
18
+ <div
19
+ v-if="item.description"
20
+ class="psui-font-normal psui-text-gray-50 psui-ml-1"
21
+ :class="{ 'psui-text-blue-60' : item.key == getItems.key }"
22
+ >
23
+ {{ item.description }}
24
+ </div>
25
+ <PsIcon
26
+ v-if="item.hasHelper"
27
+ icon="help_outline"
28
+ size="20"
29
+ class="psui-text-blue-60 psui-opacity-0 psui-transition psui-leading-none psui-cursor-pointer psui-ml-1"
30
+ :display="item.key == getItems.key || isHovering == index ? 'flex' : 'none'"
31
+ @click.native.stop="$eventBus.$emit('openDescriptionModal', { type: item.hasHelper.type, id: item.hasHelper.id, slug: item.hasHelper.slug })"
32
+ />
33
+ </div>
34
+ <div class="psui-el-dropdown-menu-list-item-line" />
35
+ <div
36
+ v-if="rightLabelFormatter"
37
+ class="psui-el-dropdown-menu-list-item-rigth-label"
38
+ >
39
+ {{ rightLabelFormatter(item.key, studyData[item.key], studyData) }}
40
+ </div>
41
+ <div
42
+ v-else
43
+ class="psui-el-dropdown-menu-list-item-rigth-label"
44
+ >
45
+ {{ getRightLabel(item) }}
46
+ </div>
9
47
  </li>
10
48
  </ul>
11
49
  </template>
12
50
 
13
51
  <script>
52
+ import PsIcon from '../ui/PsIcon.vue'
53
+ export const itemStyle = ['default', 'radio', 'icon', 'checkbox', 'switch', 'rich']
54
+
14
55
  export default {
15
- name: 'PsDropdownSimple',
56
+ name: 'PsDropdownList',
57
+ components: { PsIcon },
16
58
  props: {
59
+ /**
60
+ * It sets the style of items
61
+ */
62
+ layout: {
63
+ type: String,
64
+ default: 'default',
65
+ validator: (value) => {
66
+ return itemStyle.indexOf(value) !== -1
67
+ }
68
+ },
17
69
  /**
18
70
  * It sets the text key which will retrieve a icon from Google Fonts. Make sure to get the correct description of your icon on https://fonts.google.com/.
19
71
  */
20
- icon:{
72
+ icon: {
21
73
  type: String,
22
74
  },
23
75
  /**
@@ -28,13 +80,23 @@ export default {
28
80
  required: true
29
81
  },
30
82
  /**
31
- * It sets the item selected on the dropdown menu.
83
+ * It sets the left key label of your items if needed.
32
84
  */
33
- selected: {},
85
+ leftLabel: {
86
+ type: [String, Function],
87
+ default: 'left_label'
88
+ },
89
+ /**
90
+ * It sets the right key label of your items if needed.
91
+ */
92
+ rightLabel: {
93
+ type: [String, Function],
94
+ default: 'right_label'
95
+ },
34
96
  /**
35
97
  * It sets the key label of your items if needed.
36
98
  */
37
- keyLabel: {
99
+ label: {
38
100
  type: [String, Function],
39
101
  default: 'label'
40
102
  },
@@ -44,11 +106,30 @@ export default {
44
106
  keyValue: {
45
107
  type: [String, Function],
46
108
  default: 'value'
47
- }
109
+ },
110
+ /**
111
+ * It sets the format function to display values.
112
+ */
113
+ rightLabelFormatter: {
114
+ type: Function
115
+ },
116
+ /**
117
+ * It sets the format function to display values.
118
+ */
119
+ studyData: {
120
+ type: [String, Object]
121
+ },
122
+ /**
123
+ * It sets the item selected on the dropdown menu.
124
+ */
125
+ selected: {},
48
126
  },
127
+ data: () => ({
128
+ isHovering: false
129
+ }),
49
130
  computed: {
50
131
  getSelected() {
51
- if (this.selected) {
132
+ if (this.selected !== undefined) {
52
133
  if (typeof this.selected === 'object' && this.selected[this.keyValue] ) {
53
134
  return this.selected[this.keyValue]
54
135
  } else {
@@ -67,10 +148,20 @@ export default {
67
148
  this.$emit('update:selected', this.getKeyValue(item) )
68
149
  this.$emit('change', item )
69
150
  },
70
- getKeyLabel(item) {
71
- if(typeof this.keyLabel == 'function') return this.keyLabel(item)
151
+ getLeftLabel(item) {
152
+ if(typeof this.leftLabel == 'function') return this.leftLabel(item)
153
+ if(typeof item === 'string') return item
154
+ return item[this.leftLabel]
155
+ },
156
+ getRightLabel(item) {
157
+ if(typeof this.rightLabel == 'function') return this.rightLabel(item)
158
+ if(typeof item === 'string') return item
159
+ return item[this.rightLabel]
160
+ },
161
+ getLabel(item) {
162
+ if(typeof this.label == 'function') return this.label(item)
72
163
  if(typeof item === 'string') return item
73
- return item[this.keyLabel]
164
+ return item[this.label]
74
165
  },
75
166
  getKeyValue(item) {
76
167
  if(typeof this.keyValue == 'function') return this.keyValue(item)
@@ -171,38 +171,40 @@
171
171
  v-if="layout != 'comparison'"
172
172
  class="psui-space-x-2 psui-show-childrens-on-hover"
173
173
  >
174
- <PsTooltip v-if="column.hasProjections && !item.is_disabled && selectedRow != item.id">
174
+ <PsTooltip v-if="column.hasProjections && !item.is_disabled && selectedRow == item.id && columnSelectedKey == column.key">
175
175
  <template v-slot:trigger>
176
176
  <PsIcon
177
- icon="bar_chart"
177
+ icon="close"
178
178
  size="16"
179
179
  class="psui-cursor-pointer"
180
- icon-classes="psui-text-blue-60 psui-opacity-0 psui-leading-none psui-transition"
180
+ icon-classes="psui-text-blue-60 psui-leading-none psui-transition"
181
181
  :style="{ display: 'flex' }"
182
- @click.native="onSelectRow(item, column)"
182
+ @click.native="onCloseSelectRow(item)"
183
183
  />
184
184
  </template>
185
185
  <template v-slot:content>
186
- Show projections in the chart
186
+ Close projections
187
187
  </template>
188
188
  </PsTooltip>
189
189
 
190
- <PsTooltip v-if="column.hasProjections && !item.is_disabled && selectedRow == item.id && columnSelectedKey == column.key">
190
+ <PsTooltip v-else>
191
191
  <template v-slot:trigger>
192
192
  <PsIcon
193
- icon="close"
193
+ icon="bar_chart"
194
194
  size="16"
195
195
  class="psui-cursor-pointer"
196
- icon-classes="psui-text-blue-60 psui-leading-none psui-transition"
196
+ icon-classes="psui-text-blue-60 psui-opacity-0 psui-leading-none psui-transition"
197
197
  :style="{ display: 'flex' }"
198
- @click.native="onCloseSelectRow(item)"
198
+ @click.native="onSelectRow(item, column)"
199
199
  />
200
200
  </template>
201
201
  <template v-slot:content>
202
- Close projections
202
+ Show projections in the chart
203
203
  </template>
204
204
  </PsTooltip>
205
205
 
206
+
207
+
206
208
  <p v-if="formatFunction && !item.is_disabled">
207
209
  {{ formatFunction(column.key, item.data[column.key], item.data) }}
208
210
  </p>
@@ -425,6 +427,13 @@ export default {
425
427
  },
426
428
  mounted () {
427
429
  this.setCollapsedRows()
430
+ this.$eventBus.$on('resetPolicyImpactItemSelected', (item) => {
431
+ this.$eventBus.$emit('setPolicyItemSelected', { item, columnSelectedKey: 'forecast_emissions_savings' })
432
+ this.selectedRow = null
433
+ })
434
+ },
435
+ beforeDestroy() {
436
+ this.$eventBus.$off('resetPolicyImpactItemSelected')
428
437
  },
429
438
  methods: {
430
439
  setCollapsedRows() {
@@ -516,8 +525,7 @@ export default {
516
525
  this.$emit('policy-selected', { item: item, column: column })
517
526
  },
518
527
  onCloseSelectRow(item) {
519
- this.$eventBus.$emit('setPolicyItemSelected', { item, columnSelectedKey: 'forecast_emissions_savings' })
520
- this.selectedRow = null
528
+ this.$eventBus.$emit('resetPolicyImpactItemSelected', item)
521
529
  }
522
530
  },
523
531
  }
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div style="display: contents">
2
+ <div :style="{display: display}">
3
3
  <span
4
4
  v-if="getIconType === 'material-icons'"
5
5
  class="material-icons-round"
@@ -65,6 +65,14 @@ export default {
65
65
  default: null
66
66
  },
67
67
 
68
+ /**
69
+ * It sets fill property display of the icon.
70
+ */
71
+ display: {
72
+ type: String,
73
+ default: 'contents'
74
+ },
75
+
68
76
  /**
69
77
  * It sets the color of the icon.
70
78
  */
@@ -0,0 +1,158 @@
1
+ import PsDropdownList, { itemStyle } from '../components/forms/PsDropdownList.vue'
2
+ export default {
3
+ title: 'Components/Dropdown/Dropdown List',
4
+ component: { PsDropdownList },
5
+ argTypes: {
6
+ layout: {
7
+ control: {
8
+ type: 'inline-radio',
9
+ options: itemStyle
10
+ }
11
+ },
12
+ rigthLabelFormatter: {
13
+ control: {
14
+ type: 'select',
15
+ options: [null, 'label', 'function']
16
+ }
17
+ }
18
+ }
19
+ }
20
+
21
+ const Template = (args, { argTypes }) => ({
22
+ props: Object.keys(argTypes),
23
+ components: { PsDropdownList },
24
+ data: () => ({
25
+ selected: item
26
+ }),
27
+ template: `
28
+ <div style="width:100%;" class="psui-flex psui-space-x-10">
29
+ <PsDropdownList
30
+ v-bind="$props"
31
+ :selected.sync="selected"
32
+ left-label="title"
33
+ key-value="key"
34
+ :study-data="study_data"
35
+ />
36
+ </div>
37
+ `,
38
+ })
39
+
40
+ const items = [
41
+ {
42
+ 'isActive': true,
43
+ 'key': 'forecast_units_affected',
44
+ 'title': 'Affected Units',
45
+ 'description': '(lifecycle)',
46
+ 'right_label': '00',
47
+ 'hasProjections': true,
48
+ 'hasHelper': {
49
+ 'type': 'helpers',
50
+ 'id': 17,
51
+ 'slug': 'forecast_units_affected'
52
+ },
53
+ 'chartProjection': {
54
+ 'title': 'Number of Affected Units',
55
+ 'subtitle': ''
56
+ }
57
+ },
58
+ {
59
+ 'isActive': false,
60
+ 'key': 'forecast_initial_cost',
61
+ 'title': 'Compliance Cost',
62
+ 'description': '(lifecycle)',
63
+ 'right_label': '00',
64
+ 'hasProjections': true,
65
+ 'hasHelper': {
66
+ 'type': 'helpers',
67
+ 'id': 20,
68
+ 'slug': 'forecast_initial_cost'
69
+ },
70
+ 'chartProjection': {
71
+ 'title': 'Compliance Cost',
72
+ 'subtitle': ''
73
+ }
74
+ },
75
+ {
76
+ 'isActive': true,
77
+ 'key': 'forecast_emissions_savings',
78
+ 'title': 'Emissions Reductions',
79
+ 'description': '(lifecycle MTCO²e)',
80
+ 'right_label': '00',
81
+ 'hasProjections': true,
82
+ 'hasHelper': {
83
+ 'type': 'helpers',
84
+ 'id': 18,
85
+ 'slug': 'forecast_emissions_savings'
86
+ },
87
+ 'chartProjection': {
88
+ 'title': 'Emissions Reductions',
89
+ 'subtitle': 'MTCO²e'
90
+ }
91
+ },
92
+ {
93
+ 'isActive': true,
94
+ 'key': 'forecast_lifecycle_savings',
95
+ 'title': 'Lifecycle Savings',
96
+ 'description': '(on-bill)',
97
+ 'right_label': '00',
98
+ 'hasProjections': true,
99
+ 'hasHelper': {
100
+ 'type': 'helpers',
101
+ 'id': 19,
102
+ 'slug': 'forecast_lifecycle_savings'
103
+ },
104
+ 'chartProjection': {
105
+ 'title': 'Bill Savings',
106
+ 'subtitle': ''
107
+ }
108
+ },
109
+ {
110
+ 'isActive': false,
111
+ 'key': 'forecast_kwh_savings',
112
+ 'title': 'Electricity Savings',
113
+ 'description': '(lifecycle kWh)',
114
+ 'right_label': '00',
115
+ 'hasProjections': true,
116
+ 'hasHelper': {
117
+ 'type': 'helpers',
118
+ 'id': 21,
119
+ 'slug': 'forecast_kwh_savings'
120
+ },
121
+ 'chartProjection': {
122
+ 'title': 'Electricity Savings',
123
+ 'subtitle': 'kWh'
124
+ }
125
+ },
126
+ {
127
+ 'isActive': false,
128
+ 'key': 'forecast_therms_savings',
129
+ 'title': 'Gas Savings',
130
+ 'description': '(lifecycle therms)',
131
+ 'right_label': '00',
132
+ 'hasProjections': true,
133
+ 'hasHelper': {
134
+ 'type': 'helpers',
135
+ 'id': 22,
136
+ 'slug': 'forecast_therms_savings'
137
+ },
138
+ 'chartProjection': {
139
+ 'title': 'Gas Savings',
140
+ 'subtitle': 'therms'
141
+ }
142
+ }
143
+ ]
144
+ const item = items[0]
145
+ const studyData = {
146
+ 'forecast_units_affected': 7001.75,
147
+ 'forecast_emissions_savings': 17575.66588897,
148
+ 'forecast_therms_savings': 5060589.279978376,
149
+ 'forecast_kwh_savings': -104561078.77158748,
150
+ 'forecast_lifecycle_savings': -40645997.14350001,
151
+ 'forecast_initial_cost': -21144739.311334003
152
+ }
153
+
154
+ export const DropdownList = Template.bind({})
155
+ DropdownList.args = {
156
+ items: items,
157
+ study_data: studyData,
158
+ }