1
0
Fork 0
mirror of https://github.com/CorentinTh/it-tools.git synced 2025-08-09 15:35:19 +02:00

feat(new tools): Text Case Converter

This commit is contained in:
Jeffrey 2024-05-28 10:34:51 +08:00
parent b430baef40
commit 316da760c9
No known key found for this signature in database
GPG key ID: 4EBDD62196D54E75
6 changed files with 117 additions and 0 deletions

8
components.d.ts vendored
View file

@ -89,7 +89,9 @@ declare module '@vue/runtime-core' {
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default'] HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default'] IbanValidatorAndParser: typeof import('./src/tools/iban-validator-and-parser/iban-validator-and-parser.vue')['default']
'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default'] 'IconMdi:brushVariant': typeof import('~icons/mdi/brush-variant')['default']
'IconMdi:contentCopy': typeof import('~icons/mdi/content-copy')['default']
'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default'] 'IconMdi:kettleSteamOutline': typeof import('~icons/mdi/kettle-steam-outline')['default']
IconMdiArrowDown: typeof import('~icons/mdi/arrow-down')['default']
IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default'] IconMdiChevronDown: typeof import('~icons/mdi/chevron-down')['default']
IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default'] IconMdiChevronRight: typeof import('~icons/mdi/chevron-right')['default']
IconMdiClose: typeof import('~icons/mdi/close')['default'] IconMdiClose: typeof import('~icons/mdi/close')['default']
@ -127,6 +129,7 @@ declare module '@vue/runtime-core' {
MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default'] MetaTagGenerator: typeof import('./src/tools/meta-tag-generator/meta-tag-generator.vue')['default']
MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default'] MimeTypes: typeof import('./src/tools/mime-types/mime-types.vue')['default']
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default'] NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
NButton: typeof import('naive-ui')['NButton']
NCode: typeof import('naive-ui')['NCode'] NCode: typeof import('naive-ui')['NCode']
NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] NCollapseTransition: typeof import('naive-ui')['NCollapseTransition']
NConfigProvider: typeof import('naive-ui')['NConfigProvider'] NConfigProvider: typeof import('naive-ui')['NConfigProvider']
@ -138,13 +141,17 @@ declare module '@vue/runtime-core' {
NH1: typeof import('naive-ui')['NH1'] NH1: typeof import('naive-ui')['NH1']
NH3: typeof import('naive-ui')['NH3'] NH3: typeof import('naive-ui')['NH3']
NIcon: typeof import('naive-ui')['NIcon'] NIcon: typeof import('naive-ui')['NIcon']
NInput: typeof import('naive-ui')['NInput']
NInputNumber: typeof import('naive-ui')['NInputNumber'] NInputNumber: typeof import('naive-ui')['NInputNumber']
NLabel: typeof import('naive-ui')['NLabel'] NLabel: typeof import('naive-ui')['NLabel']
NLayout: typeof import('naive-ui')['NLayout'] NLayout: typeof import('naive-ui')['NLayout']
NLayoutSider: typeof import('naive-ui')['NLayoutSider'] NLayoutSider: typeof import('naive-ui')['NLayoutSider']
NMenu: typeof import('naive-ui')['NMenu'] NMenu: typeof import('naive-ui')['NMenu']
NScrollbar: typeof import('naive-ui')['NScrollbar'] NScrollbar: typeof import('naive-ui')['NScrollbar']
NSlider: typeof import('naive-ui')['NSlider']
NSpin: typeof import('naive-ui')['NSpin'] NSpin: typeof import('naive-ui')['NSpin']
NStatistic: typeof import('naive-ui')['NStatistic']
NSwitch: typeof import('naive-ui')['NSwitch']
NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default'] NumeronymGenerator: typeof import('./src/tools/numeronym-generator/numeronym-generator.vue')['default']
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default'] OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default'] PasswordStrengthAnalyser: typeof import('./src/tools/password-strength-analyser/password-strength-analyser.vue')['default']
@ -167,6 +174,7 @@ declare module '@vue/runtime-core' {
SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default'] SvgPlaceholderGenerator: typeof import('./src/tools/svg-placeholder-generator/svg-placeholder-generator.vue')['default']
TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default'] TemperatureConverter: typeof import('./src/tools/temperature-converter/temperature-converter.vue')['default']
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default'] TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
TextCaseConverter: typeof import('./src/tools/text-case-converter/text-case-converter.vue')['default']
TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default'] TextDiff: typeof import('./src/tools/text-diff/text-diff.vue')['default']
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default'] TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default'] TextToBinary: typeof import('./src/tools/text-to-binary/text-to-binary.vue')['default']

View file

@ -391,3 +391,6 @@ tools:
text-to-binary: text-to-binary:
title: Text to ASCII binary title: Text to ASCII binary
description: Convert text to its ASCII binary representation and vice-versa. description: Convert text to its ASCII binary representation and vice-versa.
text-case-converter:
title: Text Case Converter
description: Convert your text or string to uppercase, lowercase, title case & sentence case.

View file

@ -387,3 +387,6 @@ tools:
text-to-binary: text-to-binary:
title: 文本到 ASCII 二进制 title: 文本到 ASCII 二进制
description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。 description: 将文本转换为其 ASCII 二进制表示形式,反之亦然。
text-case-converter:
title: 文本大小写转换器
description: 将文本或字符串转换为大写、小写、标题大小写和句子大小写。

View file

@ -81,6 +81,7 @@ import { tool as uuidGenerator } from './uuid-generator';
import { tool as macAddressLookup } from './mac-address-lookup'; import { tool as macAddressLookup } from './mac-address-lookup';
import { tool as xmlFormatter } from './xml-formatter'; import { tool as xmlFormatter } from './xml-formatter';
import { tool as yamlViewer } from './yaml-viewer'; import { tool as yamlViewer } from './yaml-viewer';
import { tool as textCaseConverter } from './text-case-converter';
export const toolsByCategory: ToolCategory[] = [ export const toolsByCategory: ToolCategory[] = [
{ {
@ -172,6 +173,7 @@ export const toolsByCategory: ToolCategory[] = [
textDiff, textDiff,
numeronymGenerator, numeronymGenerator,
asciiTextDrawer, asciiTextDrawer,
textCaseConverter,
], ],
}, },
{ {

View file

@ -0,0 +1,13 @@
import { LetterCase } from '@vicons/tabler';
import { defineTool } from '../tool';
import { translate } from '@/plugins/i18n.plugin';
export const tool = defineTool({
name: translate('tools.text-case-converter.title'),
path: '/text-case-converter',
description: translate('tools.text-case-converter.description'),
keywords: ['text', 'case', 'converter'],
component: () => import('./text-case-converter.vue'),
icon: LetterCase,
createdAt: new Date('2024-5-28'),
});

View file

@ -0,0 +1,88 @@
<script setup lang="ts">
const inputValue = ref('');
const outputValue = ref('');
function toSentenceCase(input: string) {
return input.replace(/.+?[\.\?\!](\s|$)/g, (sentence) => {
return sentence.charAt(0).toUpperCase() + sentence.substr(1).toLowerCase();
});
}
function toTitleCase(input: string) {
return input.toLowerCase().replace(/\b\w/g, char => char.toUpperCase());
}
function toMixedCase(input: string) {
return input.split('').map((char, index) => {
return index % 2 === 0 ? char.toUpperCase() : char.toLowerCase();
}).join('');
}
function toInverseCase(input: string) {
return input.split('').map((char) => {
return char === char.toUpperCase() ? char.toLowerCase() : char.toUpperCase();
}).join('');
}
function handleCaseChange(type: string) {
switch (type) {
case 'sentence':
outputValue.value = toSentenceCase(inputValue.value);
break;
case 'upper':
outputValue.value = inputValue.value.toUpperCase();
break;
case 'lower':
outputValue.value = inputValue.value.toLowerCase();
break;
case 'title':
outputValue.value = toTitleCase(inputValue.value);
break;
case 'mixed':
outputValue.value = toMixedCase(inputValue.value);
break;
case 'inverse':
outputValue.value = toInverseCase(inputValue.value);
break;
}
}
</script>
<template>
<div>
<c-input-text
v-model:value="inputValue" rows="3" placeholder="Enter your text..."
multiline monospace autosize mt-5
/>
</div>
<div flex>
<div flex flex-wrap gap-5>
<c-button @click="() => handleCaseChange('sentence')">
Sentence case
</c-button>
<c-button @click="() => handleCaseChange('upper')">
UPPER CASE
</c-button>
<c-button @click="() => handleCaseChange('lower')">
lower case
</c-button>
<c-button @click="() => handleCaseChange('title')">
Title Case
</c-button>
<c-button @click="() => handleCaseChange('mixed')">
MiXeD CaSe
</c-button>
<c-button @click="() => handleCaseChange('inverse')">
iNvErSecAsE
</c-button>
</div>
<div flex justify-center gap-3>
<c-button autofocus @click="() => inputValue = ''">
Reset
</c-button>
</div>
</div>
<div>
<TextareaCopyable :value="outputValue" mb-1 mt-1 copy-placement="outside" />
</div>
</template>