From 96966d612fb93b884df866907729e1643599157c Mon Sep 17 00:00:00 2001 From: Bence Markus Date: Sun, 26 Nov 2023 22:18:55 +0100 Subject: [PATCH] new cmponents | new css | refactor --- scripts/postbuild.cjs | 8 +++- src/components/Input/BoInput.vue | 46 +++++++++---------- .../Input/__stories__/BoInput.stories.ts | 29 ++++-------- src/components/Input/constants.ts | 20 ++++++-- src/components/Input/index.ts | 1 + src/components/Input/input.scss | 33 +++++++------ src/styles/layout.ts | 1 + src/styles/themes.scss | 12 ++++- src/styles/typography.ts | 1 + utils/storybook.ts | 6 +++ vite.config.ts | 7 ++- 11 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 src/styles/layout.ts create mode 100644 src/styles/typography.ts diff --git a/scripts/postbuild.cjs b/scripts/postbuild.cjs index 8f0117af..902f8d3f 100644 --- a/scripts/postbuild.cjs +++ b/scripts/postbuild.cjs @@ -18,10 +18,14 @@ const files_to_remove_on_root = [ 'inter.cjs.js', 'colors.es.js', 'colors.cjs.js', - 'animation.es.js', - 'animation.cjs.js', + 'layout.es.js', + 'layout.cjs.js', 'assistant.es.js', 'assistant.cjs.js', + 'animation.es.js', + 'animation.cjs.js', + 'typography.es.js', + 'typography.cjs.js', 'vite.config.d.ts', 'vitest.config.d.ts', ]; diff --git a/src/components/Input/BoInput.vue b/src/components/Input/BoInput.vue index df522fbb..d83e1c73 100644 --- a/src/components/Input/BoInput.vue +++ b/src/components/Input/BoInput.vue @@ -10,7 +10,6 @@
-
-
+
+
-
-
- +
@@ -72,7 +69,8 @@ import { HTMLInputType, InputFieldEvent, InputSize, -} from './constants'; + validTextInputFieldTypes, +} from '@/components/Input'; import { Icon, BoIcon, IconSize } from '@/components/Icon'; import type { OptionalCss } from '@/types'; import { BoSpinner, SpinnerSize, SpinnerVariant } from '@/components/Loader'; @@ -80,8 +78,8 @@ import { BambooColor } from '@/constants'; const emits = defineEmits<{ (event: InputFieldEvent.Focus): void; - (event: InputFieldEvent.Clear): void; (event: InputFieldEvent.Blur, value: Event): void; + (event: InputFieldEvent.Input, value: string | null): void; (event: InputFieldEvent.Change, value: string | null): void; }>(); @@ -101,6 +99,9 @@ const props = defineProps({ type: { type: String as PropType, default: () => HTMLInputType.Text, + validator: (value: HTMLInputType): boolean => { + return validTextInputFieldTypes.includes(value); + }, }, disabled: { type: Boolean, @@ -138,10 +139,6 @@ const props = defineProps({ type: Boolean, default: false, }, - clearable: { - type: Boolean, - default: true, - }, }); const { @@ -161,7 +158,6 @@ const { } = toRefs(props); const showPassword = ref(false); -const inputVal = ref(modelValue.value); const boInputRef = ref(null); const showErrorMsg = computed(() => { @@ -173,7 +169,9 @@ const isReadonly = computed(() => { }); const inputType = computed(() => { - return showPassword.value ? HTMLInputType.Text : type?.value; + return showPassword.value && type.value === HTMLInputType.Password + ? HTMLInputType.Text + : type.value; }); const eyeIcon = computed(() => { @@ -209,8 +207,8 @@ const hasShowPasswordIcon = computed(() => { type.value === HTMLInputType.Password && !disabled.value && !isLoading.value && - inputVal.value != null && - inputVal.value !== '' + modelValue.value != null && + modelValue.value !== '' ); }); @@ -223,11 +221,11 @@ const onFocus = (): void => { }; const onInput = (): void => { - emits(InputFieldEvent.Change, inputVal.value); + emits(InputFieldEvent.Input, modelValue.value); }; const onChange = (): void => { - emits(InputFieldEvent.Change, inputVal.value); + emits(InputFieldEvent.Change, modelValue.value); }; const onBlur = (event: Event): void => { diff --git a/src/components/Input/__stories__/BoInput.stories.ts b/src/components/Input/__stories__/BoInput.stories.ts index 69978214..62022d85 100644 --- a/src/components/Input/__stories__/BoInput.stories.ts +++ b/src/components/Input/__stories__/BoInput.stories.ts @@ -3,6 +3,7 @@ import { HTMLAutocompleteAttribute, HTMLInputType, InputSize, + validTextInputFieldTypes, } from '@/components/Input'; import type { Meta, StoryObj } from '@storybook/vue3'; import { stringEnumFormatter } from '@utils/index'; @@ -77,7 +78,7 @@ const meta = { control: { type: 'select', }, - options: Object.values(HTMLInputType), + options: validTextInputFieldTypes, }, disabled: { description: 'Whether the field is disabled or not', @@ -208,17 +209,20 @@ const meta = { category: 'props', subcategory: 'optional', type: { - summary: 'HTMLInputType', - detail: stringEnumFormatter(HTMLInputType, 'HTMLInputType'), + summary: 'HTMLAutocompleteAttribute', + detail: stringEnumFormatter( + HTMLAutocompleteAttribute, + 'HTMLAutocompleteAttribute', + ), }, }, defaultValue: { - summary: undefined, + summary: HTMLAutocompleteAttribute.Off, }, control: { type: 'select', }, - options: Object.values(HTMLInputType), + options: Object.values(HTMLAutocompleteAttribute), }, readonly: { description: 'Whether the field is readonly', @@ -237,20 +241,6 @@ const meta = { type: 'boolean', }, }, - clearable: { - description: 'Whether the clear icon is shown', - table: { - category: 'props', - subcategory: 'optional', - type: { - summary: 'boolean', - }, - }, - defaultValue: { - summary: false, - }, - type: 'boolean', - }, }, } satisfies Meta; @@ -266,7 +256,6 @@ export const Example: Story = { label: 'Label', disabled: false, readonly: false, - clearable: false, isLoading: false, size: InputSize.MD, type: HTMLInputType.Text, diff --git a/src/components/Input/constants.ts b/src/components/Input/constants.ts index ff426a6b..bf632878 100644 --- a/src/components/Input/constants.ts +++ b/src/components/Input/constants.ts @@ -90,9 +90,23 @@ export enum InputSize { } export enum InputFieldEvent { - Focus = 'focus', Blur = 'blur', - Input = 'input', + Focus = 'focus', Change = 'change', - Clear = 'clear', + Input = 'update:modelValue', } + +export const validTextInputFieldTypes: HTMLInputType[] = [ + HTMLInputType.Text, + HTMLInputType.Email, + HTMLInputType.Password, + HTMLInputType.Tel, + HTMLInputType.Url, + HTMLInputType.Search, + HTMLInputType.Number, + HTMLInputType.Date, + HTMLInputType.DatetimeLocal, + HTMLInputType.Month, + HTMLInputType.Time, + HTMLInputType.Week, +]; diff --git a/src/components/Input/index.ts b/src/components/Input/index.ts index b986d39b..3702397a 100644 --- a/src/components/Input/index.ts +++ b/src/components/Input/index.ts @@ -4,4 +4,5 @@ export { HTMLInputType, InputFieldEvent, InputSize, + validTextInputFieldTypes, } from './constants'; diff --git a/src/components/Input/input.scss b/src/components/Input/input.scss index ccac9104..71eb3804 100644 --- a/src/components/Input/input.scss +++ b/src/components/Input/input.scss @@ -1,5 +1,7 @@ @import '@/styles/layout.scss'; +@import '@/styles/themes.scss'; @import '@/styles/typography.scss'; + *, *:before, *:after { @@ -19,39 +21,44 @@ @extend .font-regular; display: block; - color: var(--input-label-color); + color: var(--input-text-color); } &__field-container { - margin: 6px 0; + padding: 6px 0; position: relative; &__input { width: 100%; outline: none; display: block; - padding: 12px 8px; border-radius: 6px; - color: var(--gray-600); + color: var(--input-text-color); border: 1px solid var(--input-border-color); background-color: var(--input-background-color); - box-shadow: 0 0 15px 4px rgba(0, 0, 0, 0.06); &.sm { - @extend .height-sm; + padding: 8px; } &.md { - @extend .height-md; + padding: 10px; + } + + &.lg { + padding: 16px; } - .lg { - @extend .height-lg; + &:disabled { + color: var(--input-disabled-text-color); + background-color: var(--input-disabled-background-color); + border: 1px solid var(--input-disabled-border-color); } &.default { - :focus { - border: 1px solid var(--black); + &:focus { + border: 1px solid var(--blue-600); + transition: all 0.2s ease-in-out; } } @@ -69,7 +76,7 @@ position: absolute; top: 0; bottom: 0; - right: 10px; + right: 15px; display: flex; align-items: center; justify-content: center; @@ -98,6 +105,6 @@ @extend .font-inter; @extend .font-regular; - color: var(--input-label-color); + color: var(--input-text-color); } } diff --git a/src/styles/layout.ts b/src/styles/layout.ts new file mode 100644 index 00000000..76e273a8 --- /dev/null +++ b/src/styles/layout.ts @@ -0,0 +1 @@ +import './layout.scss'; diff --git a/src/styles/themes.scss b/src/styles/themes.scss index 254fccf4..87f3d485 100644 --- a/src/styles/themes.scss +++ b/src/styles/themes.scss @@ -7,15 +7,23 @@ .__light { --icon-color: var(--black); - --input-label-color: var(--gray-800); + --input-text-color: var(--gray-800); --input-border-color: var(--gray-100); --input-background-color: var(--gray-50); + --input-focus-border-color: var(--blue-600); + --input-disabled-text-color: var(--gray-500); + --input-disabled-border-color: var(--gray-100); + --input-disabled-background-color: var(--gray-100); } .__dark { --icon-color: var(--white); - --input-label-color: var(--gray-300); + --input-text-color: var(--gray-300); --input-border-color: var(--gray-800); --input-background-color: var(--gray-800); + --input-focus-border-color: var(--blue-600); + --input-disabled-text-color: var(--gray-500); + --input-disabled-border-color: var(--gray-700); + --input-disabled-background-color: var(--gray-700); } diff --git a/src/styles/typography.ts b/src/styles/typography.ts new file mode 100644 index 00000000..e241cd79 --- /dev/null +++ b/src/styles/typography.ts @@ -0,0 +1 @@ +import './typography.scss'; diff --git a/utils/storybook.ts b/utils/storybook.ts index f0fd46c1..22bd7b6a 100644 --- a/utils/storybook.ts +++ b/utils/storybook.ts @@ -11,3 +11,9 @@ export const stringEnumFormatter = ( .join('\r\n') + '\r\n}' }`; }; + +export const arrayFormatter = (array: string[], name: string): string => { + return `array ${name} {\n${array + .map((m: string) => ` ${m},`) + .join('\r\n')}\r\n}`; +}; diff --git a/vite.config.ts b/vite.config.ts index 82537e3b..dda45de7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -15,9 +15,10 @@ const bambooLibConfig: UserConfig = defineConfig({ entry: [ 'src/index.ts', 'src/styles/colors.ts', + 'src/styles/layout.ts', 'src/styles/animation.ts', + 'src/styles/typography.ts', 'src/styles/fonts/inter.ts', - 'src/styles/fonts/assistant.ts', ], fileName: (format, entry) => { if (entry === 'main') return `index.${format}.js`; @@ -43,6 +44,10 @@ const bambooLibConfig: UserConfig = defineConfig({ assistant: fileURLToPath( new URL('src/styles/fonts/assistant.ts', import.meta.url), ), + typography: fileURLToPath( + new URL('src/styles/typography.ts', import.meta.url), + ), + layout: fileURLToPath(new URL('src/styles/layout.ts', import.meta.url)), }, }, },