Skip to content

Commit

Permalink
feat: number input fix emitted value type, add label slot, progress o…
Browse files Browse the repository at this point in the history
…n stories
  • Loading branch information
OlkaB committed Jul 12, 2023
1 parent 52ae758 commit 304a4b1
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 56 deletions.
97 changes: 50 additions & 47 deletions src/components/CvNumberInput/CvNumberInput.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,114 +11,109 @@ export default {
component: CvNumberInput,
argTypes: {
// attrs
disabled: {
type: 'boolean',
table: {
type: { summary: 'boolean' },
category: 'attributes',
},
description: 'Specify whether the `<input>` should be disabled',
},
placeholder: {
ariaLabelForDownButton: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'attributes',
},
description: 'Specify the placeholder attribute for the `<input>`',
description: 'Aria label for down (decrease) button',
},
// props
helperText: {
ariaLabelForUpButton: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
category: 'attributes',
},
description:
'Provide text that is used alongside the control label for additional help',
description: 'Aria label for up (increase) button',
},
hideLabel: {
disabled: {
type: 'boolean',
table: {
type: { summary: 'boolean' },
category: 'props',
defaultValue: false,
category: 'attributes',
},
description:
'Specify whether you want the underlying label to be visually hidden',
description: 'Specify whether the `<input>` should be disabled',
},
invalidMessage: {
max: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
type: { summary: 'string | number' },
category: 'attributes',
},
description:
'Provide the text that is displayed when the control is in an invalid state',
description: '`max` attribute for input HTML element',
},
label: {
min: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
type: { summary: 'string | number' },
category: 'attributes',
},
description: "Input's label",
description: '`min` attribute for input HTML element',
},
light: {
step: {
type: 'string',
table: {
type: { summary: 'string | number' },
category: 'attributes',
},
description: '`step` attribute for input HTML element',
},
// props
formItem: {
type: 'boolean',
table: {
type: { summary: 'boolean' },
category: 'props',
defaultValue: false,
defaultValue: true,
},
description:
"Toggles light version. For use on `$ui-01` backgrounds only. Don't use this to make tile background color same as container background color.",
"Adds .bx--form-item class to component's wrapping HTML element",
},
modelValue: {
helperText: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
},
description:
"Input's value, modelValue is the vue3 default 'prop' for two-way data binding with v-model",
'Provide text that is used alongside the control label for additional help',
},
passwordHideLabel: {
invalidMessage: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
},
description: '"Hide password" tooltip text on password visibility toggle',
description:
'Provide the text that is displayed when the control is in an invalid state',
},
passwordShowLabel: {
label: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
},
description: '"Show password" tooltip text on password visibility toggle',
description: "Input's label",
},
passwordVisible: {
light: {
type: 'boolean',
table: {
type: { summary: 'boolean' },
category: 'props',
defaultValue: false,
},
description: 'Toggle password visibility.',
description:
"Toggles light version. For use on `$ui-01` backgrounds only. Don't use this to make tile background color same as container background color.",
},
type: {
modelValue: {
type: 'string',
table: {
type: { summary: 'string' },
category: 'props',
defaultValue: { summary: 'text' },
},
options: ['text', 'password'],
control: {
type: 'select',
},
description: 'Input type, only `text` and `password` are available',
description:
"Input's value, modelValue is the vue3 default 'prop' for two-way data binding with v-model",
},
warnText: {
type: 'string',
Expand All @@ -130,6 +125,14 @@ export default {
'Provide the text that is displayed when the control is in warning state',
},
// slots
'label ': {
type: 'string',
table: {
type: { summary: 'string | html | Component' },
category: 'slots',
},
description: 'Input label slot',
},
'helper-text': {
type: 'string',
table: {
Expand Down
30 changes: 21 additions & 9 deletions src/components/CvNumberInput/CvNumberInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@
]"
:data-invalid="dataInvalidAttributeValue"
>
<label v-show="label" :for="cvId" :class="`${carbonPrefix}--label`">
{{ label }}
<label
v-show="label || slots['label']"
:for="cvId"
:class="`${carbonPrefix}--label`"
>
<slot name="label">
{{ label }}
</slot>
</label>

<div
Expand All @@ -27,7 +33,7 @@
>
<input
ref="input"
v-model.number="internalValue"
v-model="internalValue"
:id="cvId"
:data-invalid="dataInvalidAttributeValue"
type="number"
Expand Down Expand Up @@ -95,7 +101,7 @@
</template>

<script setup>
import { computed, ref } from 'vue';
import { computed, ref, useSlots } from 'vue';
import Add16 from '@carbon/icons-vue/es/add/16';
import Subtract16 from '@carbon/icons-vue/es/subtract/16';
import WarningFilled16 from '@carbon/icons-vue/es/warning--filled/16';
Expand Down Expand Up @@ -156,6 +162,7 @@ const props = defineProps({
...propsTheme,
});
const modelValueType = typeof props.modelValue;
const cvId = useCvId(props);
const { isInvalid, isWarn, isHelper, isLight } = useCvInputHelpers(props);
const dataInvalidAttributeValue = computed(() =>
Expand All @@ -177,16 +184,19 @@ const iconClasses = computed(() => {
});
const emit = defineEmits(['update:modelValue']);
const input = ref(null);
const formatInputValueType = value => {
return modelValueType === 'string' ? value : Number(value);
};
const internalValue = computed({
get() {
const { modelValue } = props;
if (typeof modelValue === 'number') return modelValue;
const valueAsNumber = Number(modelValue);
return Number.isNaN(valueAsNumber) ? '' : valueAsNumber;
return props.modelValue;
},
set(value) {
onInput(value);
const valueFormatted = formatInputValueType(value);
onInput(valueFormatted);
},
});
Expand All @@ -211,6 +221,8 @@ const doDown = () => {
input.value.stepDown();
onProgrammaticValueChanged(input);
};
const slots = useSlots();
</script>

<script>
Expand Down

0 comments on commit 304a4b1

Please sign in to comment.