@dative-gpi/foundation-shared-components 1.1.19 → 1.1.20-progress-bar-2

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.
@@ -4,21 +4,53 @@
4
4
  :style="style"
5
5
  >
6
6
  <div
7
- class="fs-progress-bar-gradient"
7
+ class="fs-progress-bar-wrapper"
8
8
  >
9
- <div></div>
9
+ <div
10
+ class="fs-progress-bar-track"
11
+ >
12
+ <div
13
+ v-if="$props.cursor && isValueInRange"
14
+ class="fs-progress-bar-cursor"
15
+ ></div>
16
+ <div
17
+ v-if="!$props.cursor"
18
+ class="fs-progress-bar-fill"
19
+ ></div>
20
+ </div>
21
+ <div
22
+ v-if="positionedLabels.length"
23
+ class="fs-progress-bar-labels"
24
+ >
25
+ <div
26
+ v-for="label in positionedLabels"
27
+ :key="label.value"
28
+ class="fs-progress-bar-label"
29
+ :class="{
30
+ 'fs-progress-bar-label--start': label.percent === 0,
31
+ 'fs-progress-bar-label--end': label.percent === 100
32
+ }"
33
+ :style="{ left: `${label.percent}%` }"
34
+ >
35
+ <FSText
36
+ font="text-overline"
37
+ >
38
+ {{ label.display }}
39
+ </FSText>
40
+ </div>
41
+ </div>
10
42
  </div>
11
43
  <FSText
12
44
  v-if="$props.showValue"
13
45
  font="text-button"
14
46
  >
15
- {{ fixedRate }}%
47
+ {{ displayValue }}
16
48
  </FSText>
17
49
  </FSRow>
18
50
  </template>
19
51
 
20
52
  <script lang="ts">
21
- import { computed, defineComponent, type StyleValue } from "vue";
53
+ import { computed, defineComponent, type PropType, type StyleValue } from "vue";
22
54
 
23
55
  import { useColors } from '@dative-gpi/foundation-shared-components/composables';
24
56
 
@@ -50,6 +82,31 @@ export default defineComponent({
50
82
  type: Boolean,
51
83
  required: false,
52
84
  default: true
85
+ },
86
+ valueFormat: {
87
+ type: String as PropType<"percentage" | "raw">,
88
+ required: false,
89
+ default: "percentage"
90
+ },
91
+ min: {
92
+ type: Number,
93
+ required: false,
94
+ default: 0
95
+ },
96
+ max: {
97
+ type: Number,
98
+ required: false,
99
+ default: 1
100
+ },
101
+ labels: {
102
+ type: Array as PropType<Array<{ value: number; text?: string }>>,
103
+ required: false,
104
+ default: () => []
105
+ },
106
+ cursor: {
107
+ type: Boolean,
108
+ required: false,
109
+ default: false
53
110
  }
54
111
  },
55
112
  setup(props) {
@@ -58,37 +115,92 @@ export default defineComponent({
58
115
  const lightColors = getColors(ColorEnum.Light);
59
116
  const successColors = getColors(ColorEnum.Success);
60
117
  const errorColors = getColors(ColorEnum.Error);
61
-
62
- const fixedRate = computed(() => {
63
- return (props.modelValue * 100).toFixed(0);
118
+
119
+ const isValid = computed(() => props.max > props.min);
120
+
121
+ const range = computed(() => props.max - props.min);
122
+
123
+ const clampedValue = computed(() => {
124
+ if (!isValid.value) {
125
+ return props.min;
126
+ }
127
+ return Math.min(Math.max(props.modelValue, props.min), props.max);
64
128
  });
65
129
 
66
- const relativeWidth = computed(() => {
67
- return props.modelValue ? 100 / props.modelValue : 0;
130
+ const valuePercent = computed(() => {
131
+ if (!isValid.value) {
132
+ return 0;
133
+ }
134
+ return ((clampedValue.value - props.min) / range.value) * 100;
68
135
  });
69
-
70
- const startColor = computed(() => {
71
- return props.startColor ?? errorColors.base;
136
+
137
+ const isValueInRange = computed(() => {
138
+ return props.modelValue >= props.min && props.modelValue <= props.max;
139
+ });
140
+
141
+ const zeroPercent = computed(() => {
142
+ if (!isValid.value) { return 0; }
143
+ const zero = Math.min(Math.max(0, props.min), props.max);
144
+ return ((zero - props.min) / range.value) * 100;
145
+ });
146
+
147
+ const fillLeft = computed(() => Math.min(zeroPercent.value, valuePercent.value));
148
+
149
+ const fillWidth = computed(() => Math.abs(valuePercent.value - zeroPercent.value));
150
+
151
+ const gradientStartStop = computed(() => {
152
+ if (fillWidth.value === 0) { return "0%"; }
153
+ return `${-(fillLeft.value / fillWidth.value) * 100}%`;
72
154
  });
73
155
 
74
- const endColor = computed(() => {
75
- return props.endColor ?? successColors.base;
156
+ const gradientEndStop = computed(() => {
157
+ if (fillWidth.value === 0) { return "100%"; }
158
+ return `${((100 - fillLeft.value) / fillWidth.value) * 100}%`;
76
159
  });
77
160
 
78
- const style = computed((): StyleValue => {
79
- return {
80
- '--progress-bar-background-color': lightColors.dark,
81
- '--progress-bar-gradient-start-color': startColor.value,
82
- '--progress-bar-gradient-end-color': endColor.value,
83
- '--progress-bar-gradient-width': `min(100%, ${fixedRate.value}%)`,
84
- '--progress-bar-total-relative-width': `${relativeWidth.value}%`
85
- };
161
+ const fillColor = computed(() => {
162
+ return clampedValue.value >= 0
163
+ ? (props.endColor ?? successColors.base)
164
+ : (props.startColor ?? errorColors.base);
86
165
  });
87
166
 
167
+ const positionedLabels = computed(() => {
168
+ return props.labels.map(label => {
169
+ const percent = isValid.value
170
+ ? ((label.value - props.min) / range.value) * 100
171
+ : 0;
172
+
173
+ return {
174
+ value: label.value,
175
+ display: label.text ?? label.value,
176
+ percent: Math.min(Math.max(percent, 0), 100)
177
+ };
178
+ });
179
+ });
180
+
181
+ const displayValue = computed(() => {
182
+ if (props.valueFormat === "raw") { return props.modelValue.toFixed(2); }
183
+ return `${Math.round(valuePercent.value)}%`;
184
+ });
185
+
186
+ const style = computed((): StyleValue => ({
187
+ "--progress-bar-background": lightColors.dark,
188
+ "--progress-bar-gradient-start": props.startColor ?? errorColors.base,
189
+ "--progress-bar-gradient-start-stop": gradientStartStop.value,
190
+ "--progress-bar-gradient-end": props.endColor ?? successColors.base,
191
+ "--progress-bar-gradient-end-stop": gradientEndStop.value,
192
+ "--progress-bar-fill-color": fillColor.value,
193
+ "--progress-bar-fill-left": `${fillLeft.value}%`,
194
+ "--progress-bar-fill-width": `${fillWidth.value}%`,
195
+ "--progress-bar-cursor-position": `${valuePercent.value}%`
196
+ }));
197
+
88
198
  return {
89
- style,
90
- fixedRate
91
- }
92
- },
199
+ positionedLabels,
200
+ isValueInRange,
201
+ displayValue,
202
+ style
203
+ };
204
+ }
93
205
  });
94
- </script>
206
+ </script>
@@ -389,7 +389,7 @@ export default defineComponent({
389
389
  if(!map.value || !props.bounds) {
390
390
  return;
391
391
  }
392
- fitBounds(props.bounds, { maxZoom: 14 });
392
+ fitBounds(props.bounds, { maxZoom: props.zoom });
393
393
  });
394
394
 
395
395
  watch(() => props.enableScrollWheelZoom, (newValue) => {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://github.com/Dative-GPI/foundation-shared-ui.git"
5
5
  },
6
6
  "sideEffects": false,
7
- "version": "1.1.19",
7
+ "version": "1.1.20-progress-bar-2",
8
8
  "description": "",
9
9
  "publishConfig": {
10
10
  "access": "public"
@@ -13,8 +13,8 @@
13
13
  "author": "",
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
- "@dative-gpi/foundation-shared-domain": "1.1.19",
17
- "@dative-gpi/foundation-shared-services": "1.1.19"
16
+ "@dative-gpi/foundation-shared-domain": "1.1.20-progress-bar-2",
17
+ "@dative-gpi/foundation-shared-services": "1.1.20-progress-bar-2"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@dative-gpi/bones-ui": "^1.0.0",
@@ -38,5 +38,5 @@
38
38
  "sass": "1.71.1",
39
39
  "sass-loader": "13.3.2"
40
40
  },
41
- "gitHead": "ac4763dd165ca723d5518dd2965e4fbc8ba092e4"
41
+ "gitHead": "1bf7de326389a2bb6cee7baa796033b0fd2c22f9"
42
42
  }
@@ -1,14 +1,53 @@
1
- .fs-progress-bar-gradient {
1
+ .fs-progress-bar-wrapper {
2
2
  flex: 1;
3
- background-color: var(--progress-bar-background-color);
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 2px;
6
+ }
7
+
8
+ .fs-progress-bar-track {
9
+ position: relative;
10
+ background-color: var(--progress-bar-background);
4
11
  height: 8px;
5
12
  border-radius: 4px;
6
13
 
7
- div {
14
+ .fs-progress-bar-fill {
15
+ position: absolute;
16
+ height: 100%;
17
+ left: var(--progress-bar-fill-left);
18
+ width: var(--progress-bar-fill-width);
19
+ background-color: var(--progress-bar-fill-color);
20
+ border-radius: 4px;
8
21
  transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
22
+ }
23
+
24
+ .fs-progress-bar-cursor {
25
+ position: absolute;
26
+ top: 0;
9
27
  height: 100%;
10
- background: linear-gradient(to right, var(--progress-bar-gradient-start-color) 0%, var(--progress-bar-gradient-end-color) var(--progress-bar-total-relative-width));
11
- width: var(--progress-bar-gradient-width);
28
+ width: 12px;
12
29
  border-radius: 4px;
30
+ background-color: var(--progress-bar-fill-color);
31
+ left: var(--progress-bar-cursor-position);
32
+ transform: translateX(-50%);
33
+ transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1);
34
+ }
35
+ }
36
+
37
+ .fs-progress-bar-labels {
38
+ position: relative;
39
+ height: 16px;
40
+
41
+ .fs-progress-bar-label {
42
+ position: absolute;
43
+ transform: translateX(-50%);
44
+
45
+ &.fs-progress-bar-label--start {
46
+ transform: translateX(0);
47
+ }
48
+
49
+ &.fs-progress-bar-label--end {
50
+ transform: translateX(-100%);
51
+ }
13
52
  }
14
53
  }