Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved input layout to support proper positioning for right-to-left languages #322

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading