@dative-gpi/foundation-shared-components 1.1.20-progress-bar → 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.
@@ -3,65 +3,43 @@
3
3
  align="center-center"
4
4
  :style="style"
5
5
  >
6
- <template
7
- v-if="isCentered"
6
+ <div
7
+ class="fs-progress-bar-wrapper"
8
8
  >
9
9
  <div
10
- class="fs-progress-bar-centered-wrapper"
10
+ class="fs-progress-bar-track"
11
11
  >
12
12
  <div
13
- class="fs-progress-bar-centered"
14
- >
15
- <template
16
- v-if="$props.cursor"
17
- >
18
- <div
19
- class="fs-progress-bar-centered-cursor"
20
- ></div>
21
- </template>
22
- <template
23
- v-else
24
- >
25
- <div
26
- class="fs-progress-bar-centered-fill"
27
- ></div>
28
- <div
29
- class="fs-progress-bar-centered-marker"
30
- ></div>
31
- </template>
32
- </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
+ >
33
25
  <div
34
- v-if="$props.showLabels"
35
- class="fs-progress-bar-centered-labels"
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}%` }"
36
34
  >
37
35
  <FSText
38
36
  font="text-overline"
39
37
  >
40
- {{ $props.min }}
41
- </FSText>
42
- <FSText
43
- font="text-overline"
44
- class="fs-progress-bar-centered-label-middle"
45
- >
46
- 0
47
- </FSText>
48
- <FSText
49
- font="text-overline"
50
- >
51
- {{ $props.max }}
38
+ {{ label.display }}
52
39
  </FSText>
53
40
  </div>
54
41
  </div>
55
- </template>
56
- <template
57
- v-else
58
- >
59
- <div
60
- class="fs-progress-bar-gradient"
61
- >
62
- <div></div>
63
- </div>
64
- </template>
42
+ </div>
65
43
  <FSText
66
44
  v-if="$props.showValue"
67
45
  font="text-button"
@@ -72,7 +50,7 @@
72
50
  </template>
73
51
 
74
52
  <script lang="ts">
75
- import { computed, defineComponent, type StyleValue } from "vue";
53
+ import { computed, defineComponent, type PropType, type StyleValue } from "vue";
76
54
 
77
55
  import { useColors } from '@dative-gpi/foundation-shared-components/composables';
78
56
 
@@ -105,20 +83,25 @@ export default defineComponent({
105
83
  required: false,
106
84
  default: true
107
85
  },
86
+ valueFormat: {
87
+ type: String as PropType<"percentage" | "raw">,
88
+ required: false,
89
+ default: "percentage"
90
+ },
108
91
  min: {
109
92
  type: Number,
110
93
  required: false,
111
- default: undefined
94
+ default: 0
112
95
  },
113
96
  max: {
114
97
  type: Number,
115
98
  required: false,
116
- default: undefined
99
+ default: 1
117
100
  },
118
- showLabels: {
119
- type: Boolean,
101
+ labels: {
102
+ type: Array as PropType<Array<{ value: number; text?: string }>>,
120
103
  required: false,
121
- default: true
104
+ default: () => []
122
105
  },
123
106
  cursor: {
124
107
  type: Boolean,
@@ -133,80 +116,91 @@ export default defineComponent({
133
116
  const successColors = getColors(ColorEnum.Success);
134
117
  const errorColors = getColors(ColorEnum.Error);
135
118
 
136
- const fixedRate = computed(() => {
137
- return (props.modelValue * 100).toFixed(0);
138
- });
119
+ const isValid = computed(() => props.max > props.min);
139
120
 
140
- const relativeWidth = computed(() => {
141
- return props.modelValue ? 100 / props.modelValue : 0;
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);
142
128
  });
143
129
 
144
- const startColor = computed(() => {
145
- return props.startColor ?? errorColors.base;
130
+ const valuePercent = computed(() => {
131
+ if (!isValid.value) {
132
+ return 0;
133
+ }
134
+ return ((clampedValue.value - props.min) / range.value) * 100;
146
135
  });
147
136
 
148
- const endColor = computed(() => {
149
- return props.endColor ?? successColors.base;
137
+ const isValueInRange = computed(() => {
138
+ return props.modelValue >= props.min && props.modelValue <= props.max;
150
139
  });
151
140
 
152
- const isCentered = computed(() => {
153
- return props.min !== undefined && props.max !== undefined;
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;
154
145
  });
155
146
 
156
- const effectiveMin = computed(() => props.min ?? -1);
157
- const effectiveMax = computed(() => props.max ?? 1);
147
+ const fillLeft = computed(() => Math.min(zeroPercent.value, valuePercent.value));
158
148
 
159
- const centerPercent = computed(() => {
160
- return ((0 - effectiveMin.value) / (effectiveMax.value - effectiveMin.value)) * 100;
161
- });
149
+ const fillWidth = computed(() => Math.abs(valuePercent.value - zeroPercent.value));
162
150
 
163
- const valuePercent = computed(() => {
164
- const clamped = Math.min(Math.max(props.modelValue, effectiveMin.value), effectiveMax.value);
165
- return ((clamped - effectiveMin.value) / (effectiveMax.value - effectiveMin.value)) * 100;
151
+ const gradientStartStop = computed(() => {
152
+ if (fillWidth.value === 0) { return "0%"; }
153
+ return `${-(fillLeft.value / fillWidth.value) * 100}%`;
166
154
  });
167
155
 
168
- const fillLeft = computed(() => {
169
- return Math.min(centerPercent.value, valuePercent.value);
156
+ const gradientEndStop = computed(() => {
157
+ if (fillWidth.value === 0) { return "100%"; }
158
+ return `${((100 - fillLeft.value) / fillWidth.value) * 100}%`;
170
159
  });
171
160
 
172
- const fillWidth = computed(() => {
173
- return Math.abs(valuePercent.value - centerPercent.value);
161
+ const fillColor = computed(() => {
162
+ return clampedValue.value >= 0
163
+ ? (props.endColor ?? successColors.base)
164
+ : (props.startColor ?? errorColors.base);
174
165
  });
175
166
 
176
- const displayValue = computed(() => {
177
- return isCentered.value
178
- ? props.modelValue.toFixed(2)
179
- : `${fixedRate.value}%`;
180
- });
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;
181
172
 
182
- const style = computed((): StyleValue => {
183
- if (isCentered.value) {
184
- const fillColor = props.modelValue >= 0
185
- ? (props.endColor ?? successColors.dark)
186
- : (props.startColor ?? errorColors.dark);
187
173
  return {
188
- '--progress-bar-background-color': lightColors.dark,
189
- '--progress-bar-fill-color': fillColor,
190
- '--progress-bar-fill-left': `${fillLeft.value}%`,
191
- '--progress-bar-fill-width': `${fillWidth.value}%`,
192
- '--progress-bar-center-position': `${centerPercent.value}%`,
193
- '--progress-bar-value-position': `${valuePercent.value}%`
174
+ value: label.value,
175
+ display: label.text ?? label.value,
176
+ percent: Math.min(Math.max(percent, 0), 100)
194
177
  };
195
- }
196
- return {
197
- '--progress-bar-background-color': lightColors.dark,
198
- '--progress-bar-gradient-start-color': startColor.value,
199
- '--progress-bar-gradient-end-color': endColor.value,
200
- '--progress-bar-gradient-width': `min(100%, ${fixedRate.value}%)`,
201
- '--progress-bar-total-relative-width': `${relativeWidth.value}%`
202
- };
178
+ });
179
+ });
180
+
181
+ const displayValue = computed(() => {
182
+ if (props.valueFormat === "raw") { return props.modelValue.toFixed(2); }
183
+ return `${Math.round(valuePercent.value)}%`;
203
184
  });
204
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
+
205
198
  return {
206
- isCentered,
207
- style,
208
- displayValue
209
- }
210
- },
199
+ positionedLabels,
200
+ isValueInRange,
201
+ displayValue,
202
+ style
203
+ };
204
+ }
211
205
  });
212
- </script>
206
+ </script>
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.20-progress-bar",
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.20-progress-bar",
17
- "@dative-gpi/foundation-shared-services": "1.1.20-progress-bar"
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": "0b4a2295745dff49b26c5c3934a04af92560c8b1"
41
+ "gitHead": "1bf7de326389a2bb6cee7baa796033b0fd2c22f9"
42
42
  }
@@ -1,72 +1,53 @@
1
- .fs-progress-bar-gradient {
2
- flex: 1;
3
- background-color: var(--progress-bar-background-color);
4
- height: 8px;
5
- border-radius: 4px;
6
-
7
- div {
8
- transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
9
- 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);
12
- border-radius: 4px;
13
- }
14
- }
15
-
16
- .fs-progress-bar-centered-wrapper {
1
+ .fs-progress-bar-wrapper {
17
2
  flex: 1;
18
3
  display: flex;
19
4
  flex-direction: column;
20
5
  gap: 2px;
21
6
  }
22
7
 
23
- .fs-progress-bar-centered {
8
+ .fs-progress-bar-track {
24
9
  position: relative;
25
- background-color: var(--progress-bar-background-color);
10
+ background-color: var(--progress-bar-background);
26
11
  height: 8px;
27
12
  border-radius: 4px;
28
13
 
29
- .fs-progress-bar-centered-fill {
14
+ .fs-progress-bar-fill {
30
15
  position: absolute;
31
16
  height: 100%;
32
- background-color: var(--progress-bar-fill-color);
33
17
  left: var(--progress-bar-fill-left);
34
18
  width: var(--progress-bar-fill-width);
19
+ background-color: var(--progress-bar-fill-color);
35
20
  border-radius: 4px;
36
21
  transition: all 0.28s cubic-bezier(0.4, 0, 0.2, 1);
37
22
  }
38
23
 
39
- .fs-progress-bar-centered-marker {
40
- position: absolute;
41
- top: 0;
42
- height: 100%;
43
- width: 2px;
44
- background-color: var(--progress-bar-background-color);
45
- left: var(--progress-bar-center-position);
46
- transform: translateX(-50%);
47
- }
48
-
49
- .fs-progress-bar-centered-cursor {
24
+ .fs-progress-bar-cursor {
50
25
  position: absolute;
51
26
  top: 0;
52
27
  height: 100%;
53
28
  width: 12px;
54
29
  border-radius: 4px;
55
30
  background-color: var(--progress-bar-fill-color);
56
- left: var(--progress-bar-value-position);
31
+ left: var(--progress-bar-cursor-position);
57
32
  transform: translateX(-50%);
58
33
  transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1);
59
34
  }
60
35
  }
61
36
 
62
- .fs-progress-bar-centered-labels {
37
+ .fs-progress-bar-labels {
63
38
  position: relative;
64
- display: flex;
65
- justify-content: space-between;
39
+ height: 16px;
66
40
 
67
- .fs-progress-bar-centered-label-middle {
41
+ .fs-progress-bar-label {
68
42
  position: absolute;
69
- left: var(--progress-bar-center-position);
70
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
+ }
71
52
  }
72
53
  }