From 52ae7584c1ecdef480fb72ddaa65a51de884e2e8 Mon Sep 17 00:00:00 2001 From: OlkaB Date: Fri, 7 Jul 2023 08:04:04 +0100 Subject: [PATCH] feat: port CvNumberInput component to Vue3 --- .../CvNumberInput/CvNumberInput.stories.js | 169 +++++++++++++- .../CvNumberInput/CvNumberInput.vue | 219 +++++++++++++++++- src/use/cvInput.js | 40 ++++ 3 files changed, 423 insertions(+), 5 deletions(-) create mode 100644 src/use/cvInput.js diff --git a/src/components/CvNumberInput/CvNumberInput.stories.js b/src/components/CvNumberInput/CvNumberInput.stories.js index ccc6e1700..ade7dedc0 100644 --- a/src/components/CvNumberInput/CvNumberInput.stories.js +++ b/src/components/CvNumberInput/CvNumberInput.stories.js @@ -1,3 +1,4 @@ +import { action } from '@storybook/addon-actions'; import { sbCompPrefix, storyParametersObject, @@ -8,16 +9,178 @@ import CvNumberInput from './CvNumberInput.vue'; export default { title: `${sbCompPrefix}/${StorybookGroupConst}/CvNumberInput`, component: CvNumberInput, - argTypes: {}, + argTypes: { + // attrs + disabled: { + type: 'boolean', + table: { + type: { summary: 'boolean' }, + category: 'attributes', + }, + description: 'Specify whether the `` should be disabled', + }, + placeholder: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'attributes', + }, + description: 'Specify the placeholder attribute for the ``', + }, + // props + helperText: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: + 'Provide text that is used alongside the control label for additional help', + }, + hideLabel: { + type: 'boolean', + table: { + type: { summary: 'boolean' }, + category: 'props', + defaultValue: false, + }, + description: + 'Specify whether you want the underlying label to be visually hidden', + }, + invalidMessage: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: + 'Provide the text that is displayed when the control is in an invalid state', + }, + label: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: "Input's label", + }, + light: { + type: 'boolean', + table: { + type: { summary: 'boolean' }, + category: 'props', + defaultValue: false, + }, + 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.", + }, + modelValue: { + 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", + }, + passwordHideLabel: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: '"Hide password" tooltip text on password visibility toggle', + }, + passwordShowLabel: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: '"Show password" tooltip text on password visibility toggle', + }, + passwordVisible: { + type: 'boolean', + table: { + type: { summary: 'boolean' }, + category: 'props', + }, + description: 'Toggle password visibility.', + }, + type: { + 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', + }, + warnText: { + type: 'string', + table: { + type: { summary: 'string' }, + category: 'props', + }, + description: + 'Provide the text that is displayed when the control is in warning state', + }, + // slots + 'helper-text': { + type: 'string', + table: { + type: { summary: 'string | html | Component' }, + category: 'slots', + }, + description: + "Helper text slot. It isn't shown if invalid message or warn text, either props or slots, are available", + }, + 'invalid-message': { + type: 'string', + table: { + type: { summary: 'string | html | Component' }, + category: 'slots', + }, + description: 'Invalid message slot.', + }, + 'warn-text': { + type: 'string', + table: { + type: { summary: 'string | html | Component' }, + category: 'slots', + }, + description: + "Warn text slot. It isn't shown if invalid message, either prop or slot, is available", + }, + // events + 'update:modelValue': { + type: 'event', + table: { + type: { summary: 'event' }, + category: 'events', + }, + control: { type: null }, + description: + "Triggered on textarea update. `update:modelValue` is the vue3 default 'event' for two-way data binding with v-model", + }, + }, }; -const template = ``; +const template = ``; const Template = (args, { argTypes }) => { return { props: Object.keys(argTypes), components: { CvNumberInput }, template, - setup: () => ({ args }), + setup: () => ({ + args, + onInput: action('input'), + onChange: action('change'), + }), }; }; diff --git a/src/components/CvNumberInput/CvNumberInput.vue b/src/components/CvNumberInput/CvNumberInput.vue index 80117fec9..36429b67a 100644 --- a/src/components/CvNumberInput/CvNumberInput.vue +++ b/src/components/CvNumberInput/CvNumberInput.vue @@ -1,5 +1,220 @@ - + + + diff --git a/src/use/cvInput.js b/src/use/cvInput.js new file mode 100644 index 000000000..3894399b2 --- /dev/null +++ b/src/use/cvInput.js @@ -0,0 +1,40 @@ +import { onBeforeMount, onBeforeUpdate, ref, useSlots } from 'vue'; +import { useIsLight } from './cvTheme'; + +export const useCvInputHelpers = props => { + const slots = useSlots(); + const isInvalid = ref(false); + const isWarn = ref(false); + const isHelper = ref(false); + const isLight = useIsLight(props); + + function checkSlots() { + // NOTE: slots is not reactive so needs to be managed on updated + isInvalid.value = !!( + props.invalidMessage?.length || slots['invalid-message'] + ); + isWarn.value = + !isInvalid.value && !!(props.warnText?.length || slots['warn-text']); + isHelper.value = + !isInvalid.value && + !isWarn.value && + !!(props.helperText?.length || slots['helper-text']); + } + console.log('useCvInputHelpers: ', { + slots, + isInvalid: isInvalid.value, + isWarn: isWarn.value, + isHelper: isHelper.value, + isLight: isLight.value, + }); + onBeforeMount(checkSlots); + onBeforeUpdate(checkSlots); + + return { + slots, + isInvalid, + isWarn, + isHelper, + isLight, + }; +};