Skip to content

Commit

Permalink
feat: rtl support #206
Browse files Browse the repository at this point in the history
  • Loading branch information
adamberecz committed May 26, 2022
1 parent 84539bd commit ac19de3
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 33 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ Join our [Discord channel](https://discord.gg/WhX2nG6GTQ) or [open an issue](htt
| **disabled** | `boolean` | `false` | Whether the input should be disabled for the user (API can still be used programmatically). |
| **inputType** | `string` | `text` | The `type` attribute of the search input. |
| **autocomplete** | `string` | `undefined` | The `autocomplete` attribute of the search input. |
| **rtl** | `boolean` | `false` | Whether the multiselect should be right-to-left. It also respects `dir="rtl"` on any parent element. |
| **max** | `number` | `-1` | The maximum number of options that **can be selected** when using `multiple` or `tags` mode. If `-1` the number of options won't be limited. |
| **limit** | `number` | `-1` | The maximum number of options that **should be displayed**. If `-1` the number of options won't be limited. |
| **loading** | `boolean` | `false` | Whether a loading spinner should be shown. |
Expand Down Expand Up @@ -555,24 +556,24 @@ Alternatively you can define class names directly by passing them to the `Multis
containerOpen: 'rounded-b-none',
containerOpenTop: 'rounded-t-none',
containerActive: 'ring ring-green-500 ring-opacity-30',
singleLabel: 'flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border',
singleLabel: 'flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
singleLabelText: 'overflow-ellipsis overflow-hidden block whitespace-nowrap max-w-full',
multipleLabel: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5',
search: 'w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5',
tags: 'flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2',
tag: 'bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap',
tagDisabled: 'pr-2 opacity-50',
multipleLabel: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
search: 'w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5 rtl:pl-0 rtl:pr-3.5',
tags: 'flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2 rtl:pl-0 rtl:pr-2',
tag: 'bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1',
tagDisabled: 'pr-2 opacity-50 rtl:pl-2',
tagRemove: 'flex items-center justify-center p-1 mx-0.5 rounded-sm hover:bg-black hover:bg-opacity-10 group',
tagRemoveIcon: 'bg-multiselect-remove bg-center bg-no-repeat opacity-30 inline-block w-3 h-3 group-hover:opacity-60',
tagsSearchWrapper: 'inline-block relative mx-1 mb-1 flex-grow flex-shrink h-full',
tagsSearch: 'absolute inset-0 border-0 outline-none focus:ring-0 appearance-none p-0 text-base font-sans box-border w-full',
tagsSearchCopy: 'invisible whitespace-pre-wrap inline-block h-px',
placeholder: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400',
caret: 'bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none',
placeholder: 'flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5',
caret: 'bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3.5',
caretOpen: 'rotate-180 pointer-events-auto',
clear: 'pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80',
clear: 'pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80 rtl:pr-0 rtl:pl-3.5',
clearIcon: 'bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block',
spinner: 'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0',
spinner: 'bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0 rtl:mr-0 rtl:ml-3.5',
dropdown: 'max-h-60 absolute -left-px -right-px bottom-0 transform translate-y-full border border-gray-300 -mt-px overflow-y-scroll z-50 bg-white flex flex-col rounded-b',
dropdownTop: '-translate-y-full top-px bottom-auto flex-col-reverse rounded-b-none rounded-t',
dropdownHidden: 'hidden',
Expand Down
19 changes: 10 additions & 9 deletions src/Multiselect.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@ declare class Multiselect extends Vue {
strict?: boolean;
closeOnSelect?: boolean;
autocomplete?: string;
groups: boolean;
groupLabel: string;
groupOptions: string;
groupHideEmpty: boolean;
groupSelect: boolean;
inputType: string;
groups?: boolean;
groupLabel?: string;
groupOptions?: string;
groupHideEmpty?: boolean;
groupSelect?: boolean;
inputType?: string;
attrs?: object;
onCreate?: Function;
searchStart: boolean;
reverse: boolean;
regex: string|object;
searchStart?: boolean;
reverse?: boolean;
regex?: string|object;
rtl?: boolean;

$emit(eventName: 'change', e: {originalEvent: Event, value: any}): this;
$emit(eventName: 'select', e: {originalEvent: Event, value: any, option: any}): this;
Expand Down
10 changes: 8 additions & 2 deletions src/Multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
:tabindex="tabindex"
:class="classList.container"
:id="id"
:dir="rtl ? 'rtl' : undefined"
@focusin="activate"
@focusout="deactivate"
@keydown="handleKeydown"
Expand Down Expand Up @@ -459,12 +460,12 @@
},
attrs: {
required: false,
type: [Object],
type: Object,
default: () => ({}),
},
onCreate: {
required: false,
type: [Function],
type: Function,
},
disabledProp: {
type: String,
Expand All @@ -486,6 +487,11 @@
required: false,
default: undefined,
},
rtl: {
type: Boolean,
required: false,
default: false,
},
},
setup(props, context)
{
Expand Down
40 changes: 40 additions & 0 deletions themes/default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,46 @@
display: none;
}

[dir="rtl"] {
.multiselect-multiple-label,
.multiselect-single-label,
.multiselect-placeholder {
padding-right: var(--ms-px, 0.875rem);
padding-left: calc(1.25rem + var(--ms-px, 0.875rem) * 3);
left: auto;
right: 0;
}

.multiselect-search {
padding-left: 0;
padding-right: var(--ms-px, 0.875rem);
}

.multiselect-tags {
padding-left: 0;
padding-right: var(--ms-py, 0.5rem);
}

.multiselect-tag {
padding: var(--ms-tag-py, 0.125rem) var(--ms-tag-px, 0.5rem) var(--ms-tag-py, 0.125rem) 0;
margin-right: 0;
margin-left: var(--ms-tag-mx, 0.25rem);

&.is-disabled {
padding-left: var(--ms-tag-px, 0.5rem);
}
}

.multiselect-spinner,
.multiselect-caret {
margin: 0 0 0 var(--ms-px, 0.875rem);
}

.multiselect-clear {
padding: 0 0 0 var(--ms-px, 0.875rem);
}
}

@keyframes multiselect-spin {
from {
transform: rotate(0);
Expand Down
24 changes: 12 additions & 12 deletions themes/tailwind.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,30 @@
}

.multiselect-single-label {
@apply flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border;
@apply flex items-center h-full max-w-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 pr-16 box-border rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
}

.multiselect-single-label-text {
@apply overflow-ellipsis overflow-hidden block whitespace-nowrap max-w-full;
}

.multiselect-multiple-label {
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5;
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
}

.multiselect-search {
@apply w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5;
@apply w-full absolute inset-0 outline-none focus:ring-0 appearance-none box-border border-0 text-base font-sans bg-white rounded pl-3.5 rtl:pl-0 rtl:pr-3.5;
}

.multiselect-tags {
@apply flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2;
@apply flex-grow flex-shrink flex flex-wrap items-center mt-1 pl-2 rtl:pl-0 rtl:pr-2;
}

.multiselect-tag {
@apply bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap;
@apply bg-green-500 text-white text-sm font-semibold py-0.5 pl-2 rounded mr-1 mb-1 flex items-center whitespace-nowrap rtl:pl-0 rtl:pr-2 rtl:mr-0 rtl:ml-1;

&.is-disabled {
@apply pr-2 opacity-50;
@apply pr-2 opacity-50 rtl:pl-2;
}
}

Expand Down Expand Up @@ -71,27 +71,27 @@
}

.multiselect-placeholder {
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400;
@apply flex items-center h-full absolute left-0 top-0 pointer-events-none bg-transparent leading-snug pl-3.5 text-gray-400 rtl:left-auto rtl:right-0 rtl:pl-0 rtl:pr-3.5;
}

.multiselect-caret {
@apply bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none;
@apply bg-multiselect-caret bg-center bg-no-repeat w-2.5 h-4 py-px box-content mr-3.5 relative z-10 opacity-40 flex-shrink-0 flex-grow-0 transition-transform transform pointer-events-none rtl:mr-0 rtl:ml-3.5;

&.is-open {
@apply rotate-180 pointer-events-auto;
}
}

.multiselect-clear {
@apply pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80;
@apply pr-3.5 relative z-10 opacity-40 transition duration-300 flex-shrink-0 flex-grow-0 flex hover:opacity-80 rtl:pr-0 rtl:pl-3.5;
}

.multiselect-clear-icon {
@apply bg-multiselect-remove bg-center bg-no-repeat w-2.5 h-4 py-px box-content inline-block;
}

.multiselect-spinner {
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0;
@apply bg-multiselect-spinner bg-center bg-no-repeat w-4 h-4 z-10 mr-3.5 animate-spin flex-shrink-0 flex-grow-0 rtl:mr-0 rtl:ml-3.5;
}

.multiselect-dropdown {
Expand Down Expand Up @@ -171,11 +171,11 @@
}

.multiselect-no-options {
@apply py-2 px-3 text-gray-600 bg-white text-left;
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
}

.multiselect-no-results {
@apply py-2 px-3 text-gray-600 bg-white text-left;
@apply py-2 px-3 text-gray-600 bg-white text-left rtl:text-right;
}

.multiselect-fake-input {
Expand Down

0 comments on commit ac19de3

Please sign in to comment.