Skip to content

Commit

Permalink
feat: FwbInput: Improved input layout to support proper positioning f…
Browse files Browse the repository at this point in the history
…or different lang directions
  • Loading branch information
andreyjamer committed Sep 6, 2024
1 parent c679aa9 commit 62fb704
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
13 changes: 8 additions & 5 deletions src/components/FwbInput/FwbInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
v-if="label"
:class="labelClasses"
>{{ label }}</label>
<div class="flex relative">
<div
class="flex relative items-center"
:class="[inputBlockClasses]"
>
<div
v-if="$slots.prefix"
class="w-10 flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none overflow-hidden"
class="flex items-center ms-3 pointer-events-none overflow-hidden flex-shrink-0"
>
<slot name="prefix" />
</div>
Expand All @@ -18,11 +21,11 @@
:type="type"
:required="required"
:autocomplete="autocomplete"
:class="[inputClasses, $slots.prefix ? 'pl-10' : '']"
:class="[inputClasses]"
>
<div
v-if="$slots.suffix"
class="absolute right-2.5 bottom-2.5"
class="flex items-center me-3 flex-shrink-0"
>
<slot name="suffix" />
</div>
Expand Down Expand Up @@ -79,7 +82,7 @@ const props = withDefaults(defineProps<InputProps>(), {
const model = useVModel(props, 'modelValue')
const { inputClasses, labelClasses } = useInputClasses(toRefs(props))
const { inputClasses, inputBlockClasses, labelClasses } = useInputClasses(toRefs(props))
const validationWrapperClasses = computed(() => twMerge(
'mt-2 text-sm',
Expand Down
23 changes: 16 additions & 7 deletions src/components/FwbInput/composables/useInputClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,21 @@ import {
const baseLabelClasses = 'block mb-2 text-sm font-medium'

// INPUT
const defaultInputClasses =
'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500'
const defaultInputClasses = 'block flex-grow w-full p-0 bg-transparent text-inherit ring-offset-0 ring-0 border-0 focus:ring-offset-0 focus:ring-0 focus:border-0'

// BLOCK
const defaultBlockClasses =
'focus-within:ring-offset-0 focus-within:ring-1 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus-within:ring-blue-500 focus-within:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus-within:ring-blue-500 dark:focus-within:border-blue-500'

const disabledInputClasses = 'cursor-not-allowed bg-gray-100'
const inputSizeClasses: Record<InputSize, string> = {
lg: 'p-4',
md: 'p-2.5 text-sm',
sm: 'p-2 text-sm',
}

const successInputClasses = 'bg-green-50 border-green-500 dark:border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 focus:ring-green-500 focus:border-green-500'
const errorInputClasses = 'bg-red-50 border-red-500 text-red-900 placeholder-red-700 focus:ring-red-500 focus:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500'
const successInputClasses = 'bg-green-50 border-green-500 dark:border-green-500 text-green-900 dark:text-green-400 placeholder-green-700 dark:placeholder-green-500 focus-within:ring-green-500 focus-within:border-green-500'
const errorInputClasses = 'bg-red-50 border-red-500 text-red-900 placeholder-red-700 focus-within:ring-red-500 focus-within:border-red-500 dark:text-red-500 dark:placeholder-red-500 dark:border-red-500'

export type UseInputClassesProps = {
size: Ref<InputSize>
Expand All @@ -29,10 +33,11 @@ export type UseInputClassesProps = {
}

export function useInputClasses (props: UseInputClassesProps): {
inputBlockClasses: Ref<string>
inputClasses: Ref<string>
labelClasses: Ref<string>
} {
const inputClasses = computed(() => {
const inputBlockClasses = computed(() => {
const vs = props.validationStatus.value

const classByStatus = vs === validationStatusMap.Success
Expand All @@ -42,13 +47,16 @@ export function useInputClasses (props: UseInputClassesProps): {
: ''

return twMerge(
defaultInputClasses,
defaultBlockClasses,
classByStatus,
inputSizeClasses[props.size.value],
props.disabled.value ? disabledInputClasses : '',
)
})

const inputClasses = computed(() => {
return twMerge(defaultInputClasses, inputSizeClasses[props.size.value])
})

const labelClasses = computed(() => {
const vs = props.validationStatus.value
const classByStatus = vs === validationStatusMap.Success
Expand All @@ -61,6 +69,7 @@ export function useInputClasses (props: UseInputClassesProps): {
})

return {
inputBlockClasses,
inputClasses,
labelClasses,
}
Expand Down

0 comments on commit 62fb704

Please sign in to comment.