feat(ux): copyable input
This commit is contained in:
		
							parent
							
								
									7a7372df19
								
							
						
					
					
						commit
						1859a9a174
					
				
							
								
								
									
										49
									
								
								src/components/InputCopyable.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/components/InputCopyable.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | <template> | ||||||
|  |   <n-input v-model:value="value"> | ||||||
|  |     <template #suffix> | ||||||
|  |       <n-tooltip trigger="hover"> | ||||||
|  |         <template #trigger> | ||||||
|  |           <n-button | ||||||
|  |             quaternary | ||||||
|  |             circle | ||||||
|  |             @click="onCopyClicked" | ||||||
|  |           > | ||||||
|  |             <n-icon :component="ContentCopyFilled" /> | ||||||
|  |           </n-button> | ||||||
|  |         </template> | ||||||
|  |         {{ tooltipText }} | ||||||
|  |       </n-tooltip> | ||||||
|  |     </template>  | ||||||
|  |   </n-input> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useVModel } from '@vueuse/core' | ||||||
|  | import { ContentCopyFilled } from '@vicons/material' | ||||||
|  | 
 | ||||||
|  | import { useClipboard } from '@vueuse/core'; | ||||||
|  | import { ref } from 'vue'; | ||||||
|  | 
 | ||||||
|  | const props = defineProps<{ value: string, }>() | ||||||
|  | const emit = defineEmits(['update:value']) | ||||||
|  | 
 | ||||||
|  | const value = useVModel(props, 'value', emit) | ||||||
|  | const tooltipText = ref('Copy to clipboard') | ||||||
|  | 
 | ||||||
|  | const {copy} = useClipboard({source: value}) | ||||||
|  | 
 | ||||||
|  | function onCopyClicked() { | ||||||
|  |     copy(); | ||||||
|  |     tooltipText.value = 'Copied !' | ||||||
|  | 
 | ||||||
|  |     setTimeout(() => { | ||||||
|  |         tooltipText.value = 'Copy to clipboard' | ||||||
|  |     }, 2000) | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | ::v-deep(.n-input-wrapper) { | ||||||
|  |     padding-right: 5px; | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -11,39 +11,38 @@ | |||||||
| 
 | 
 | ||||||
|       <n-divider /> |       <n-divider /> | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|       <n-form-item label="Camelcase:"> |       <n-form-item label="Camelcase:"> | ||||||
|         <n-input :value="camelCase(input)" /> |         <input-copyable :value="camelCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Capitalcase:"> |       <n-form-item label="Capitalcase:"> | ||||||
|         <n-input :value="capitalCase(input)" /> |         <input-copyable :value="capitalCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Constantcase:"> |       <n-form-item label="Constantcase:"> | ||||||
|         <n-input :value="constantCase(input)" /> |         <input-copyable :value="constantCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Dotcase:"> |       <n-form-item label="Dotcase:"> | ||||||
|         <n-input :value="dotCase(input)" /> |         <input-copyable :value="dotCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Headercase:"> |       <n-form-item label="Headercase:"> | ||||||
|         <n-input :value="headerCase(input)" /> |         <input-copyable :value="headerCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Nocase:"> |       <n-form-item label="Nocase:"> | ||||||
|         <n-input :value="noCase(input)" /> |         <input-copyable :value="noCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Paramcase:"> |       <n-form-item label="Paramcase:"> | ||||||
|         <n-input :value="paramCase(input)" /> |         <input-copyable :value="paramCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Pascalcase:"> |       <n-form-item label="Pascalcase:"> | ||||||
|         <n-input :value="pascalCase(input)" /> |         <input-copyable :value="pascalCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Pathcase:"> |       <n-form-item label="Pathcase:"> | ||||||
|         <n-input :value="pathCase(input)" /> |         <input-copyable :value="pathCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Sentencecase:"> |       <n-form-item label="Sentencecase:"> | ||||||
|         <n-input :value="sentenceCase(input)" /> |         <input-copyable :value="sentenceCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="Snakecase:"> |       <n-form-item label="Snakecase:"> | ||||||
|         <n-input :value="snakeCase(input)" /> |         <input-copyable :value="snakeCase(input)" /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|     </n-form> |     </n-form> | ||||||
|   </n-card> |   </n-card> | ||||||
| @ -51,6 +50,8 @@ | |||||||
| 
 | 
 | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { ref } from 'vue'; | import { ref } from 'vue'; | ||||||
|  | import InputCopyable from "../../components/InputCopyable.vue"; | ||||||
|  | 
 | ||||||
| import { | import { | ||||||
|   camelCase, |   camelCase, | ||||||
|   capitalCase, |   capitalCase, | ||||||
|  | |||||||
| @ -12,43 +12,43 @@ | |||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="color name:"> |       <n-form-item label="color name:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="name" |           v-model:value="name" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'name')" |           :on-input="(v: string) => onInputUpdated(v, 'name')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="hex:"> |       <n-form-item label="hex:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="hex" |           v-model:value="hex" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'hex')" |           :on-input="(v: string) => onInputUpdated(v, 'hex')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="rgb:"> |       <n-form-item label="rgb:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="rgb" |           v-model:value="rgb" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'rgb')" |           :on-input="(v: string) => onInputUpdated(v, 'rgb')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="hsl:"> |       <n-form-item label="hsl:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="hsl" |           v-model:value="hsl" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'hsl')" |           :on-input="(v: string) => onInputUpdated(v, 'hsl')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="hwb:"> |       <n-form-item label="hwb:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="hwb" |           v-model:value="hwb" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'hwb')" |           :on-input="(v: string) => onInputUpdated(v, 'hwb')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="lch:"> |       <n-form-item label="lch:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="lch" |           v-model:value="lch" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'lch')" |           :on-input="(v: string) => onInputUpdated(v, 'lch')" | ||||||
|         /> |         /> | ||||||
|       </n-form-item> |       </n-form-item> | ||||||
|       <n-form-item label="cmyk:"> |       <n-form-item label="cmyk:"> | ||||||
|         <n-input |         <input-copyable | ||||||
|           v-model:value="cmyk" |           v-model:value="cmyk" | ||||||
|           :on-input="(v: string) => onInputUpdated(v, 'cmyk')" |           :on-input="(v: string) => onInputUpdated(v, 'cmyk')" | ||||||
|         /> |         /> | ||||||
| @ -60,6 +60,7 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { ref } from 'vue'; | import { ref } from 'vue'; | ||||||
| import { colord, extend } from "colord"; | import { colord, extend } from "colord"; | ||||||
|  | import InputCopyable from "../../components/InputCopyable.vue"; | ||||||
| 
 | 
 | ||||||
| import cmykPlugin from "colord/plugins/cmyk"; | import cmykPlugin from "colord/plugins/cmyk"; | ||||||
| import hwbPlugin from "colord/plugins/hwb"; | import hwbPlugin from "colord/plugins/hwb"; | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ | |||||||
|           <n-input-group-label style="width: 150px;"> |           <n-input-group-label style="width: 150px;"> | ||||||
|             {{ name }} |             {{ name }} | ||||||
|           </n-input-group-label> |           </n-input-group-label> | ||||||
|           <n-input :value="fromDate(date)" /> |           <input-copyable :value="fromDate(date)" /> | ||||||
|         </n-input-group> |         </n-input-group> | ||||||
|       </div> |       </div> | ||||||
|     </n-card> |     </n-card> | ||||||
| @ -51,6 +51,7 @@ | |||||||
| import { useRafFn } from '@vueuse/core'; | import { useRafFn } from '@vueuse/core'; | ||||||
| import { formatISO, formatISO9075, formatRFC3339, formatRFC7231, fromUnixTime, getTime, getUnixTime, isDate, parseISO, parseJSON } from 'date-fns'; | import { formatISO, formatISO9075, formatRFC3339, formatRFC7231, fromUnixTime, getTime, getUnixTime, isDate, parseISO, parseJSON } from 'date-fns'; | ||||||
| import { ref } from 'vue' | import { ref } from 'vue' | ||||||
|  | import InputCopyable from "../../components/InputCopyable.vue"; | ||||||
| 
 | 
 | ||||||
| const useCurrentDate = ref(true) | const useCurrentDate = ref(true) | ||||||
| const inputDate = ref('') | const inputDate = ref('') | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ | |||||||
|         <n-input-group-label style="width: 200px;"> |         <n-input-group-label style="width: 200px;"> | ||||||
|           Binary (2): |           Binary (2): | ||||||
|         </n-input-group-label> |         </n-input-group-label> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 2 })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 2 })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -38,7 +38,7 @@ | |||||||
|         <n-input-group-label style="width: 200px;"> |         <n-input-group-label style="width: 200px;"> | ||||||
|           Octale (8): |           Octale (8): | ||||||
|         </n-input-group-label> |         </n-input-group-label> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 8 })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 8 })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -48,7 +48,7 @@ | |||||||
|         <n-input-group-label style="width: 200px;"> |         <n-input-group-label style="width: 200px;"> | ||||||
|           Decimal (10): |           Decimal (10): | ||||||
|         </n-input-group-label> |         </n-input-group-label> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 10 })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 10 })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -58,7 +58,7 @@ | |||||||
|         <n-input-group-label style="width: 200px;"> |         <n-input-group-label style="width: 200px;"> | ||||||
|           Hexadecimal (16): |           Hexadecimal (16): | ||||||
|         </n-input-group-label> |         </n-input-group-label> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 16 })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 16 })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -68,7 +68,7 @@ | |||||||
|         <n-input-group-label style="width: 200px;"> |         <n-input-group-label style="width: 200px;"> | ||||||
|           Base64 (64): |           Base64 (64): | ||||||
|         </n-input-group-label> |         </n-input-group-label> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 64 })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: 64 })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -83,7 +83,7 @@ | |||||||
|           max="64" |           max="64" | ||||||
|           min="2" |           min="2" | ||||||
|         /> |         /> | ||||||
|         <n-input |         <input-copyable | ||||||
|           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: outputBase })" |           :value="convertBase({ value: String(inputNumber), fromBase: inputBase, toBase: outputBase })" | ||||||
|           readonly |           readonly | ||||||
|         /> |         /> | ||||||
| @ -95,6 +95,7 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { ref } from 'vue' | import { ref } from 'vue' | ||||||
| import { convertBase } from './integer-base-converter.model' | import { convertBase } from './integer-base-converter.model' | ||||||
|  | import InputCopyable from "../../components/InputCopyable.vue"; | ||||||
| 
 | 
 | ||||||
| const inputNumber = ref(42) | const inputNumber = ref(42) | ||||||
| const inputBase = ref(10) | const inputBase = ref(10) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user