diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-24 18:10:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-24 18:10:11 +0300 |
commit | 7308ec9d13fb69018200a40f287e76ef499ed47c (patch) | |
tree | 06c75f7ddceebd61d09f925a48fef2789338f3cd /app/assets/javascripts/vue_shared/components | |
parent | f296f23500b4b3758670ae0c5ce2e1779f533e8b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components')
-rw-r--r-- | app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js | 7 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue | 64 |
2 files changed, 58 insertions, 13 deletions
diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js index 377f1e7c136..531ed5fe0ea 100644 --- a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js +++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.stories.js @@ -8,16 +8,21 @@ export default { const defaultProps = { value: 'hR8x1fuJbzwu5uFKLf9e', formInputGroupProps: { class: 'gl-form-input-xl' }, + readonly: false, }; const Template = (args, { argTypes }) => ({ components: { InputCopyToggleVisibility }, + data() { + return { value: args.value }; + }, props: Object.keys(argTypes), template: `<input-copy-toggle-visibility - :value="value" + v-model="value" :initial-visibility="initialVisibility" :show-toggle-visibility-button="showToggleVisibilityButton" :show-copy-button="showCopyButton" + :readonly="readonly" :form-input-group-props="formInputGroupProps" :copy-button-title="copyButtonTitle" />`, diff --git a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue index dea279890b1..c371c1aeff9 100644 --- a/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue +++ b/app/assets/javascripts/vue_shared/components/form/input_copy_toggle_visibility.vue @@ -8,6 +8,7 @@ import { } from '@gitlab/ui'; import { __ } from '~/locale'; +import { Mousetrap, MOUSETRAP_COPY_KEYBOARD_SHORTCUT } from '~/lib/mousetrap'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { @@ -52,6 +53,11 @@ export default { required: false, default: __('Copy'), }, + readonly: { + type: Boolean, + required: false, + default: false, + }, formInputGroupProps: { type: Object, required: false, @@ -61,6 +67,12 @@ export default { }, }, data() { + if (!this.readonly && !this.value) { + return { + valueIsVisible: true, + }; + } + return { valueIsVisible: this.initialVisibility, }; @@ -77,33 +89,60 @@ export default { computedValueIsVisible() { return !this.showToggleVisibilityButton || this.valueIsVisible; }, - displayedValue() { - return this.computedValueIsVisible ? this.value : '*'.repeat(this.value.length || 20); + inputType() { + return this.computedValueIsVisible ? 'text' : 'password'; }, }, + mounted() { + this.$options.mousetrap = new Mousetrap(this.$refs.input.$el); + this.$options.mousetrap.bind(MOUSETRAP_COPY_KEYBOARD_SHORTCUT, this.handleFormInputCopy); + }, + beforeDestroy() { + this.$options.mousetrap?.unbind(MOUSETRAP_COPY_KEYBOARD_SHORTCUT); + }, + methods: { handleToggleVisibilityButtonClick() { this.valueIsVisible = !this.valueIsVisible; this.$emit('visibility-change', this.valueIsVisible); }, - handleClick() { - this.$refs.input.$el.select(); + async handleClick() { + if (this.readonly) { + this.$refs.input.$el.select(); + } else if (!this.valueIsVisible) { + const { selectionStart, selectionEnd } = this.$refs.input.$el; + this.handleToggleVisibilityButtonClick(); + + setTimeout(() => { + // When the input type is changed from 'password'' to 'text', cursor position is reset in some browsers. + // This makes clicking to edit difficult due to typing in unexpected location, so we preserve the cursor position / selection + this.$refs.input.$el.setSelectionRange(selectionStart, selectionEnd); + }, 0); + } }, handleCopyButtonClick() { this.$emit('copy'); }, - handleFormInputCopy(event) { - this.handleCopyButtonClick(); - + async handleFormInputCopy() { + // Value will be copied by native browser behavior if (this.computedValueIsVisible) { return; } - event.clipboardData.setData('text/plain', this.value); - event.preventDefault(); + try { + // user is trying to copy from the password input, set their clipboard for them + await navigator.clipboard?.writeText(this.value); + this.handleCopyButtonClick(); + } catch (e) { + // Nothing we can do here, best effort to set clipboard value + } + }, + handleInput(newValue) { + this.$emit('input', newValue); }, }, + mousetrap: null, }; </script> <template> @@ -111,11 +150,12 @@ export default { <gl-form-input-group> <gl-form-input ref="input" - readonly + :readonly="readonly" class="gl-font-monospace! gl-cursor-default!" v-bind="formInputGroupProps" - :value="displayedValue" - @copy="handleFormInputCopy" + :value="value" + :type="inputType" + @input="handleInput" @click="handleClick" /> |