Skip to content

Commit fa440d8

Browse files
docs(playground): DLT-3242 segmented control for compact enum props (#1165)
1 parent cb169df commit fa440d8

2 files changed

Lines changed: 95 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<template>
2+
<dt-text
3+
kind="label"
4+
:size="100"
5+
tone="secondary"
6+
class="d-input__label-text d-c-default"
7+
>
8+
<slot />
9+
</dt-text>
10+
<dt-segmented-control
11+
:model-value="String(value)"
12+
:size="100"
13+
:disabled="disabled"
14+
@change="onInput"
15+
>
16+
<dt-segmented-control-item
17+
v-for="option in options"
18+
:key="option.value"
19+
:value="String(option.value)"
20+
>
21+
{{ option.label }}
22+
</dt-segmented-control-item>
23+
</dt-segmented-control>
24+
</template>
25+
26+
<script setup>
27+
import { DtSegmentedControl, DtSegmentedControlItem, DtText } from '@dialpad/dialtone-vue';
28+
29+
import { VALUE_UPDATE_EVENT } from '@/src/lib/constants';
30+
import { computed } from 'vue';
31+
32+
const props = defineProps({
33+
value: {
34+
type: undefined,
35+
required: true,
36+
},
37+
validValues: {
38+
type: Array,
39+
default: undefined,
40+
},
41+
disabled: {
42+
type: Boolean,
43+
default: false,
44+
},
45+
generateLabel: {
46+
type: Function,
47+
default: (value) => value.toString(),
48+
},
49+
});
50+
51+
const emit = defineEmits([VALUE_UPDATE_EVENT]);
52+
53+
const options = computed(() => {
54+
return props.validValues?.map(v => ({
55+
value: v,
56+
label: props.generateLabel(v),
57+
})) ?? [];
58+
});
59+
60+
// DtSegmentedControl coerces values to strings — map back to original types on selection
61+
const valueMap = computed(() => {
62+
const map = {};
63+
props.validValues?.forEach(v => {
64+
map[String(v)] = v;
65+
});
66+
return map;
67+
});
68+
69+
function onInput (stringValue) {
70+
emit(VALUE_UPDATE_EVENT, valueMap.value[stringValue]);
71+
}
72+
</script>
73+
74+
<script>
75+
/**
76+
* Control that renders a segmented control for enum props with few, short options.
77+
*/
78+
export default {
79+
name: 'DtcControlSegmented',
80+
};
81+
</script>

packages/combinator/src/lib/control.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ import DtcControlString from '@/src/components/controls/control_string.vue';
1414
import DtcControlNullish from '@/src/components/controls/control_nullish.vue';
1515
import DtcControlBase from '@/src/components/controls/control_base.vue';
1616
import DtcControlIconSlot from '@/src/components/controls/control_icon_slot.vue';
17+
import DtcControlSegmented from '@/src/components/controls/control_segmented.vue';
1718

1819
import { typeOfMemberValue } from '@/src/lib/utils';
1920

21+
const MAX_SEGMENTED_COUNT = 6;
22+
const MAX_SEGMENTED_LABEL_LENGTH = 4;
23+
2024
/**
2125
* Symbol representing a value that is "not set".
2226
* The main usage is to indicate that a prop value should be 'undefined' instead of using its default value.
@@ -58,6 +62,10 @@ export const controlMap = Object.freeze({
5862
component: DtcControlSelection,
5963
default ({ values } = {}) { return values?.[0]; },
6064
},
65+
segmented: {
66+
component: DtcControlSegmented,
67+
default ({ values } = {}) { return values?.[0]; },
68+
},
6169
string: {
6270
component: DtcControlString,
6371
default () { return getControlDataDefault(this); },
@@ -102,6 +110,7 @@ export function getControlByValue (value) {
102110
export function getControlByMemberType (type, args) {
103111
if (type === 'boolean') return 'boolean';
104112
if (args?.values?.length > 0) {
113+
if (shouldUseSegmented(args.values)) return 'segmented';
105114
return 'selection';
106115
}
107116
switch (type) {
@@ -110,6 +119,11 @@ export function getControlByMemberType (type, args) {
110119
}
111120
}
112121

122+
function shouldUseSegmented (values) {
123+
return values.length <= MAX_SEGMENTED_COUNT &&
124+
values.every(v => String(v).length <= MAX_SEGMENTED_LABEL_LENGTH);
125+
}
126+
113127
/**
114128
* Serializes a value before giving it to a control that requires a serialized value.
115129
* Currently, this only converts between 'UNSET' and 'undefined'.

0 commit comments

Comments
 (0)