mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-04-20 06:55:06 -04:00
refactor(ui): getting ride of naive ui buttons
This commit is contained in:
parent
df989e24b3
commit
c45bce36f9
44 changed files with 738 additions and 204 deletions
72
components.d.ts
vendored
72
components.d.ts
vendored
|
@ -9,13 +9,62 @@ export {}
|
|||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
'404.page': typeof import('./src/pages/404.page.vue')['default']
|
||||
About: typeof import('./src/pages/About.vue')['default']
|
||||
App: typeof import('./src/App.vue')['default']
|
||||
'Base.layout': typeof import('./src/layouts/base.layout.vue')['default']
|
||||
Base64FileConverter: typeof import('./src/tools/base64-file-converter/base64-file-converter.vue')['default']
|
||||
Base64StringConverter: typeof import('./src/tools/base64-string-converter/base64-string-converter.vue')['default']
|
||||
BasicAuthGenerator: typeof import('./src/tools/basic-auth-generator/basic-auth-generator.vue')['default']
|
||||
Bcrypt: typeof import('./src/tools/bcrypt/bcrypt.vue')['default']
|
||||
BenchmarkBuilder: typeof import('./src/tools/benchmark-builder/benchmark-builder.vue')['default']
|
||||
Bip39Generator: typeof import('./src/tools/bip39-generator/bip39-generator.vue')['default']
|
||||
CaseConverter: typeof import('./src/tools/case-converter/case-converter.vue')['default']
|
||||
CButton: typeof import('./src/ui/c-button/c-button.vue')['default']
|
||||
ChmodCalculator: typeof import('./src/tools/chmod-calculator/chmod-calculator.vue')['default']
|
||||
Chronometer: typeof import('./src/tools/chronometer/chronometer.vue')['default']
|
||||
CLink: typeof import('./src/ui/c-link/c-link.vue')['default']
|
||||
CollapsibleToolMenu: typeof import('./src/components/CollapsibleToolMenu.vue')['default']
|
||||
ColorConverter: typeof import('./src/tools/color-converter/color-converter.vue')['default']
|
||||
ColoredCard: typeof import('./src/components/ColoredCard.vue')['default']
|
||||
CopyableIpLike: typeof import('./src/tools/ipv4-subnet-calculator/copyable-ip-like.vue')['default']
|
||||
CrontabGenerator: typeof import('./src/tools/crontab-generator/crontab-generator.vue')['default']
|
||||
DateTimeConverter: typeof import('./src/tools/date-time-converter/date-time-converter.vue')['default']
|
||||
DeviceInformation: typeof import('./src/tools/device-information/device-information.vue')['default']
|
||||
DockerRunToDockerComposeConverter: typeof import('./src/tools/docker-run-to-docker-compose-converter/docker-run-to-docker-compose-converter.vue')['default']
|
||||
DynamicValues: typeof import('./src/tools/benchmark-builder/dynamic-values.vue')['default']
|
||||
Editor: typeof import('./src/tools/html-wysiwyg-editor/editor/editor.vue')['default']
|
||||
Encryption: typeof import('./src/tools/encryption/encryption.vue')['default']
|
||||
EtaCalculator: typeof import('./src/tools/eta-calculator/eta-calculator.vue')['default']
|
||||
FavoriteButton: typeof import('./src/components/FavoriteButton.vue')['default']
|
||||
FormatTransformer: typeof import('./src/components/FormatTransformer.vue')['default']
|
||||
GitMemo: typeof import('./src/tools/git-memo/git-memo.md')['default']
|
||||
HashText: typeof import('./src/tools/hash-text/hash-text.vue')['default']
|
||||
HmacGenerator: typeof import('./src/tools/hmac-generator/hmac-generator.vue')['default']
|
||||
'Home.page': typeof import('./src/pages/Home.page.vue')['default']
|
||||
HtmlEntities: typeof import('./src/tools/html-entities/html-entities.vue')['default']
|
||||
HtmlWysiwygEditor: typeof import('./src/tools/html-wysiwyg-editor/html-wysiwyg-editor.vue')['default']
|
||||
HttpStatusCodes: typeof import('./src/tools/http-status-codes/http-status-codes.vue')['default']
|
||||
InputCopyable: typeof import('./src/components/InputCopyable.vue')['default']
|
||||
IntegerBaseConverter: typeof import('./src/tools/integer-base-converter/integer-base-converter.vue')['default']
|
||||
Ipv4AddressConverter: typeof import('./src/tools/ipv4-address-converter/ipv4-address-converter.vue')['default']
|
||||
Ipv4RangeExpander: typeof import('./src/tools/ipv4-range-expander/ipv4-range-expander.vue')['default']
|
||||
Ipv4SubnetCalculator: typeof import('./src/tools/ipv4-subnet-calculator/ipv4-subnet-calculator.vue')['default']
|
||||
Ipv6UlaGenerator: typeof import('./src/tools/ipv6-ula-generator/ipv6-ula-generator.vue')['default']
|
||||
JsonMinify: typeof import('./src/tools/json-minify/json-minify.vue')['default']
|
||||
JsonToYaml: typeof import('./src/tools/json-to-yaml-converter/json-to-yaml.vue')['default']
|
||||
JsonViewer: typeof import('./src/tools/json-viewer/json-viewer.vue')['default']
|
||||
JwtParser: typeof import('./src/tools/jwt-parser/jwt-parser.vue')['default']
|
||||
KeycodeInfo: typeof import('./src/tools/keycode-info/keycode-info.vue')['default']
|
||||
LoremIpsumGenerator: typeof import('./src/tools/lorem-ipsum-generator/lorem-ipsum-generator.vue')['default']
|
||||
MacAddressLookup: typeof import('./src/tools/mac-address-lookup/mac-address-lookup.vue')['default']
|
||||
MathEvaluator: typeof import('./src/tools/math-evaluator/math-evaluator.vue')['default']
|
||||
MenuBar: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar.vue')['default']
|
||||
MenuBarItem: typeof import('./src/tools/html-wysiwyg-editor/editor/menu-bar-item.vue')['default']
|
||||
MenuIconItem: typeof import('./src/components/MenuIconItem.vue')['default']
|
||||
MenuLayout: typeof import('./src/components/MenuLayout.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']
|
||||
NAlert: typeof import('naive-ui')['NAlert']
|
||||
NAutoComplete: typeof import('naive-ui')['NAutoComplete']
|
||||
NavbarButtons: typeof import('./src/components/NavbarButtons.vue')['default']
|
||||
|
@ -37,7 +86,6 @@ declare module '@vue/runtime-core' {
|
|||
NH1: typeof import('naive-ui')['NH1']
|
||||
NH2: typeof import('naive-ui')['NH2']
|
||||
NH3: typeof import('naive-ui')['NH3']
|
||||
NH4: typeof import('naive-ui')['NH4']
|
||||
NIcon: typeof import('naive-ui')['NIcon']
|
||||
NImage: typeof import('naive-ui')['NImage']
|
||||
NInput: typeof import('naive-ui')['NInput']
|
||||
|
@ -50,7 +98,6 @@ declare module '@vue/runtime-core' {
|
|||
NP: typeof import('naive-ui')['NP']
|
||||
NPageHeader: typeof import('naive-ui')['NPageHeader']
|
||||
NProgress: typeof import('naive-ui')['NProgress']
|
||||
NResult: typeof import('naive-ui')['NResult']
|
||||
NScrollbar: typeof import('naive-ui')['NScrollbar']
|
||||
NSelect: typeof import('naive-ui')['NSelect']
|
||||
NSlider: typeof import('naive-ui')['NSlider']
|
||||
|
@ -63,12 +110,33 @@ declare module '@vue/runtime-core' {
|
|||
NTooltip: typeof import('naive-ui')['NTooltip']
|
||||
NUpload: typeof import('naive-ui')['NUpload']
|
||||
NUploadDragger: typeof import('naive-ui')['NUploadDragger']
|
||||
OtpCodeGeneratorAndValidator: typeof import('./src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')['default']
|
||||
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
|
||||
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
|
||||
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
|
||||
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
RsaKeyPairGenerator: typeof import('./src/tools/rsa-key-pair-generator/rsa-key-pair-generator.vue')['default']
|
||||
SearchBar: typeof import('./src/components/SearchBar.vue')['default']
|
||||
SearchBarItem: typeof import('./src/components/SearchBarItem.vue')['default']
|
||||
SlugifyString: typeof import('./src/tools/slugify-string/slugify-string.vue')['default']
|
||||
SpanCopyable: typeof import('./src/components/SpanCopyable.vue')['default']
|
||||
SqlPrettify: typeof import('./src/tools/sql-prettify/sql-prettify.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']
|
||||
TextareaCopyable: typeof import('./src/components/TextareaCopyable.vue')['default']
|
||||
TextStatistics: typeof import('./src/tools/text-statistics/text-statistics.vue')['default']
|
||||
TextToNatoAlphabet: typeof import('./src/tools/text-to-nato-alphabet/text-to-nato-alphabet.vue')['default']
|
||||
TokenDisplay: typeof import('./src/tools/otp-code-generator-and-validator/token-display.vue')['default']
|
||||
'TokenGenerator.tool': typeof import('./src/tools/token-generator/token-generator.tool.vue')['default']
|
||||
'Tool.layout': typeof import('./src/layouts/tool.layout.vue')['default']
|
||||
ToolCard: typeof import('./src/components/ToolCard.vue')['default']
|
||||
UrlEncoder: typeof import('./src/tools/url-encoder/url-encoder.vue')['default']
|
||||
UrlParser: typeof import('./src/tools/url-parser/url-parser.vue')['default']
|
||||
UserAgentParser: typeof import('./src/tools/user-agent-parser/user-agent-parser.vue')['default']
|
||||
UserAgentResultCards: typeof import('./src/tools/user-agent-parser/user-agent-result-cards.vue')['default']
|
||||
UuidGenerator: typeof import('./src/tools/uuid-generator/uuid-generator.vue')['default']
|
||||
YamlToJson: typeof import('./src/tools/yaml-to-json-converter/yaml-to-json.vue')['default']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
<template>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button circle quaternary :type="buttonType" :style="{ opacity: isFavorite ? 1 : 0.2 }" @click="toggleFavorite">
|
||||
<template #icon>
|
||||
<c-button
|
||||
variant="text"
|
||||
circle
|
||||
:type="buttonType"
|
||||
:style="{ opacity: isFavorite ? 1 : 0.2 }"
|
||||
@click="toggleFavorite"
|
||||
>
|
||||
<n-icon :component="FavoriteFilled" />
|
||||
</template>
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
{{ isFavorite ? 'Remove from favorites' : 'Add to favorites' }}
|
||||
</n-tooltip>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<template #suffix>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button quaternary circle @click="onCopyClicked">
|
||||
<c-button circle variant="text" @click="onCopyClicked">
|
||||
<n-icon :component="ContentCopyFilled" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
{{ tooltipText }}
|
||||
</n-tooltip>
|
||||
|
|
|
@ -1,56 +1,50 @@
|
|||
<template>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
size="large"
|
||||
<c-button
|
||||
circle
|
||||
quaternary
|
||||
tag="a"
|
||||
variant="text"
|
||||
href="https://github.com/CorentinTh/it-tools"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label="IT-Tools' GitHub repository"
|
||||
>
|
||||
<n-icon size="25" :component="BrandGithub" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
Github repository
|
||||
</n-tooltip>
|
||||
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
size="large"
|
||||
<c-button
|
||||
circle
|
||||
quaternary
|
||||
tag="a"
|
||||
variant="text"
|
||||
href="https://twitter.com/ittoolsdottech"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
aria-label="IT Tools' Twitter account"
|
||||
>
|
||||
<n-icon size="25" :component="BrandTwitter" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
IT Tools' Twitter account
|
||||
</n-tooltip>
|
||||
|
||||
<router-link to="/about" #="{ navigate, href }" custom>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button tag="a" :href="href" circle quaternary size="large" aria-label="About" @click="navigate">
|
||||
<c-button circle variant="text" to="/about" aria-label="About">
|
||||
<n-icon size="25" :component="InfoCircle" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
About
|
||||
</n-tooltip>
|
||||
</router-link>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button size="large" circle quaternary aria-label="Toggle dark/light mode" @click="isDarkTheme = !isDarkTheme">
|
||||
<c-button circle variant="text" aria-label="Toggle dark/light mode" @click="toggleDarkTheme">
|
||||
<n-icon v-if="isDarkTheme" size="25" :component="Sun" />
|
||||
<n-icon v-else size="25" :component="Moon" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
<span v-if="isDarkTheme">Light mode</span>
|
||||
<span v-else>Dark mode</span>
|
||||
|
@ -59,11 +53,20 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { useStyleStore } from '@/stores/style.store';
|
||||
import { useThemeStore } from '@/ui/theme/theme.store';
|
||||
import { BrandGithub, BrandTwitter, InfoCircle, Moon, Sun } from '@vicons/tabler';
|
||||
import { toRefs } from 'vue';
|
||||
|
||||
const styleStore = useStyleStore();
|
||||
const { isDarkTheme } = toRefs(styleStore);
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
function toggleDarkTheme() {
|
||||
isDarkTheme.value = !isDarkTheme.value;
|
||||
|
||||
themeStore.toggleTheme();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
@ -13,16 +13,16 @@
|
|||
<n-tooltip v-if="value" trigger="hover">
|
||||
<template #trigger>
|
||||
<div class="copy-button" :class="[copyPlacement]">
|
||||
<n-button circle secondary size="large" @click="onCopyClicked">
|
||||
<c-button circle important:h-10 important:w-10 @click="onCopyClicked">
|
||||
<n-icon size="22" :component="Copy" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</div>
|
||||
</template>
|
||||
<span>{{ tooltipText }}</span>
|
||||
</n-tooltip>
|
||||
</n-card>
|
||||
<n-space v-if="copyPlacement === 'outside'" justify="center" mt-4>
|
||||
<n-button secondary @click="onCopyClicked"> {{ tooltipText }} </n-button>
|
||||
<c-button @click="onCopyClicked"> {{ tooltipText }} </c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -53,38 +53,25 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
<div>
|
||||
IT-Tools
|
||||
|
||||
<n-button
|
||||
text
|
||||
tag="a"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
type="primary"
|
||||
depth="3"
|
||||
:href="`https://github.com/CorentinTh/it-tools/tree/v${version}`"
|
||||
>
|
||||
<c-link target="_blank" rel="noopener" :href="`https://github.com/CorentinTh/it-tools/tree/v${version}`">
|
||||
v{{ version }}
|
||||
</n-button>
|
||||
</c-link>
|
||||
|
||||
<template v-if="commitSha && commitSha.length > 0">
|
||||
-
|
||||
<n-button
|
||||
text
|
||||
tag="a"
|
||||
<c-link
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
type="primary"
|
||||
depth="3"
|
||||
:href="`https://github.com/CorentinTh/it-tools/tree/${commitSha}`"
|
||||
>
|
||||
{{ commitSha }}
|
||||
</n-button>
|
||||
</c-link>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
© {{ new Date().getFullYear() }}
|
||||
<n-button text tag="a" target="_blank" rel="noopener" type="primary" href="https://github.com/CorentinTh">
|
||||
Corentin Thomasset
|
||||
</n-button>
|
||||
<c-link target="_blank" rel="noopener" href="https://github.com/CorentinTh"> Corentin Thomasset </c-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -92,34 +79,24 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
|
||||
<template #content>
|
||||
<div class="navigation">
|
||||
<n-button
|
||||
<c-button
|
||||
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
|
||||
circle
|
||||
quaternary
|
||||
variant="text"
|
||||
aria-label="Toggle menu"
|
||||
@click="styleStore.isMenuCollapsed = !styleStore.isMenuCollapsed"
|
||||
>
|
||||
<n-icon size="25" :component="Menu2" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
|
||||
<router-link to="/" #="{ navigate, href }" custom>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
tag="a"
|
||||
:href="href"
|
||||
:size="styleStore.isSmallScreen ? 'medium' : 'large'"
|
||||
circle
|
||||
quaternary
|
||||
aria-label="Home"
|
||||
@click="navigate"
|
||||
>
|
||||
<c-button to="/" circle variant="text" aria-label="Home">
|
||||
<n-icon size="25" :component="Home2" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
Home
|
||||
</n-tooltip>
|
||||
</router-link>
|
||||
|
||||
<search-bar />
|
||||
|
||||
|
@ -127,10 +104,8 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
<c-button
|
||||
round
|
||||
type="primary"
|
||||
tag="a"
|
||||
href="https://www.buymeacoffee.com/cthmsst"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
|
@ -140,7 +115,7 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
>
|
||||
Buy me a coffee
|
||||
<n-icon v-if="!styleStore.isSmallScreen" :component="Heart" ml-2 />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
❤ Support IT Tools development !
|
||||
</n-tooltip>
|
||||
|
@ -165,8 +140,8 @@ const tools = computed<ToolCategory[]>(() => [
|
|||
.support-button {
|
||||
background: rgb(37, 99, 108);
|
||||
background: linear-gradient(48deg, rgba(37, 99, 108, 1) 0%, rgba(59, 149, 111, 1) 60%, rgba(20, 160, 88, 1) 100%);
|
||||
color: #fff;
|
||||
transition: all ease 0.2s;
|
||||
color: #fff !important;
|
||||
transition: padding ease 0.2s !important;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
|
|
|
@ -13,8 +13,6 @@ useHead({ title: 'Page not found - IT Tools' });
|
|||
<n-text mt-4 block depth="3">Sorry, this page does not seem to exist</n-text>
|
||||
<n-text mb-8 block depth="3">Maybe the cache is doing tricky things, try force-refreshing?</n-text>
|
||||
|
||||
<router-link to="/" #="{ navigate, href }" custom>
|
||||
<n-button tag="a" :href="href" secondary @click="navigate"> Back home </n-button>
|
||||
</router-link>
|
||||
<c-button to="/"> Back home </c-button>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -11,25 +11,21 @@ const { tracker } = useTracker();
|
|||
<n-h1>About</n-h1>
|
||||
<n-p>
|
||||
This wonderful website, made with ❤ by
|
||||
<n-button text tag="a" href="https://github.com/CorentinTh" target="_blank" rel="noopener" type="primary">
|
||||
Corentin Thomasset </n-button
|
||||
>, aggregates useful tools for developer and people working in IT. If you find it useful, please fell free to
|
||||
share it to people you think may find it useful too and don't forget to pin it in your shortcut bar !
|
||||
<c-link href="https://github.com/CorentinTh" target="_blank" rel="noopener"> Corentin Thomasset </c-link>,
|
||||
aggregates useful tools for developer and people working in IT. If you find it useful, please fell free to share
|
||||
it to people you think may find it useful too and don't forget to pin it in your shortcut bar !
|
||||
</n-p>
|
||||
<n-p>
|
||||
IT Tools is open-source (under the MIT license) and free, and will always be, but it cost me money to host and
|
||||
renew the domain name, if you want to support my work, and encourage me to add more tools, please consider
|
||||
supporting by
|
||||
<n-button
|
||||
type="primary"
|
||||
tag="a"
|
||||
text
|
||||
<c-link
|
||||
href="https://www.buymeacoffee.com/cthmsst"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
@click="() => tracker.trackEvent({ eventName: 'Support button clicked' })"
|
||||
>
|
||||
sponsoring me </n-button
|
||||
sponsoring me </c-link
|
||||
>.
|
||||
</n-p>
|
||||
|
||||
|
@ -37,16 +33,9 @@ const { tracker } = useTracker();
|
|||
<n-p>
|
||||
IT Tools is made in Vue JS (vue 3) with the the naive-ui component library and is hosted and continuously deployed
|
||||
by Vercel. Third party open-source libraries are used in some tools, you may find the complete list in the
|
||||
<n-button
|
||||
type="primary"
|
||||
tag="a"
|
||||
text
|
||||
href="https://github.com/CorentinTh/it-tools/blob/main/package.json"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>
|
||||
<c-link href="https://github.com/CorentinTh/it-tools/blob/main/package.json" rel="noopener" target="_blank">
|
||||
package.json
|
||||
</n-button>
|
||||
</c-link>
|
||||
file of the repository.
|
||||
</n-p>
|
||||
|
||||
|
@ -54,30 +43,24 @@ const { tracker } = useTracker();
|
|||
<n-p>
|
||||
If you need a tool that is currently not present here, and you think can be relevant, you are welcome to submit a
|
||||
feature request in the
|
||||
<n-button
|
||||
type="primary"
|
||||
tag="a"
|
||||
text
|
||||
<c-link
|
||||
href="https://github.com/CorentinTh/it-tools/issues/new?assignees=CorentinTh&labels=enhancement&template=feature_request.md&title=%5BFEAT%5D%20My%20feature"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>
|
||||
issues section
|
||||
</n-button>
|
||||
</c-link>
|
||||
in the GitHub repository.
|
||||
</n-p>
|
||||
<n-p>
|
||||
And if you found a bug, or something broken that doesn't work as expected, please fill a bug report in the
|
||||
<n-button
|
||||
type="primary"
|
||||
tag="a"
|
||||
text
|
||||
<c-link
|
||||
href="https://github.com/CorentinTh/it-tools/issues/new?assignees=CorentinTh&labels=bug&template=bug_report.md&title=%5BBUG%5D%20My%20bug"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>
|
||||
issues section
|
||||
</n-button>
|
||||
</c-link>
|
||||
in the GitHub repository.
|
||||
</n-p>
|
||||
</div>
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
<n-input v-model:value="base64Input" type="textarea" placeholder="Put your base64 file string here..." rows="5" />
|
||||
</n-form-item>
|
||||
<n-space justify="center">
|
||||
<n-button :disabled="base64Input === '' || !base64InputValidation.isValid" secondary @click="downloadFile()">
|
||||
<c-button :disabled="base64Input === '' || !base64InputValidation.isValid" @click="downloadFile()">
|
||||
Download file
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
<n-input :value="fileBase64" type="textarea" readonly placeholder="File in base64 will be here" />
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyFileBase64()"> Copy </n-button>
|
||||
<c-button @click="copyFileBase64()"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyTextBase64()"> Copy base64 </n-button>
|
||||
<c-button @click="copyTextBase64()"> Copy base64 </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyText()"> Copy decoded string </n-button>
|
||||
<c-button @click="copyText()"> Copy decoded string </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</n-card>
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copy">Copy header</n-button>
|
||||
<c-button @click="copy">Copy header</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</n-form>
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copy"> Copy hash </n-button>
|
||||
<c-button @click="copy"> Copy hash </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
|
|
|
@ -14,18 +14,17 @@
|
|||
</n-card>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button v-if="suites.length > 1" quaternary @click="suites.splice(index, 1)">
|
||||
<template #icon>
|
||||
<n-icon :component="Trash" depth="3" />
|
||||
</template>
|
||||
<c-button v-if="suites.length > 1" variant="text" @click="suites.splice(index, 1)">
|
||||
<n-icon :component="Trash" depth="3" mr-2 size="18" />
|
||||
Delete suite
|
||||
</n-button>
|
||||
<n-button quaternary @click="suites.splice(index + 1, 0, { data: [0], title: `Suite ${suites.length + 1}` })">
|
||||
<template #icon>
|
||||
<n-icon :component="Plus" depth="3" />
|
||||
</template>
|
||||
</c-button>
|
||||
<c-button
|
||||
variant="text"
|
||||
@click="suites.splice(index + 1, 0, { data: [0], title: `Suite ${suites.length + 1}` })"
|
||||
>
|
||||
<n-icon :component="Plus" depth="3" mr-2 size="18" />
|
||||
Add suite
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-space>
|
||||
|
@ -39,15 +38,14 @@
|
|||
<n-input v-model:value="unit" placeholder="Unit (eg: ms)" />
|
||||
</n-form-item>
|
||||
|
||||
<n-button
|
||||
tertiary
|
||||
<c-button
|
||||
@click="
|
||||
suites = [
|
||||
{ title: 'Suite 1', data: [] },
|
||||
{ title: 'Suite 2', data: [] },
|
||||
]
|
||||
"
|
||||
>Reset suites</n-button
|
||||
>Reset suites</c-button
|
||||
>
|
||||
</n-space>
|
||||
|
||||
|
@ -73,8 +71,8 @@
|
|||
</n-table>
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button tertiary @click="copyAsMarkdown">Copy as markdown table</n-button>
|
||||
<n-button tertiary @click="copyAsBulletList">Copy as bullet list</n-button>
|
||||
<c-button @click="copyAsMarkdown">Copy as markdown table</c-button>
|
||||
<c-button @click="copyAsBulletList">Copy as bullet list</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -11,22 +11,18 @@
|
|||
/>
|
||||
<n-tooltip>
|
||||
<template #trigger>
|
||||
<n-button circle quaternary @click="values.splice(index, 1)">
|
||||
<template #icon>
|
||||
<n-icon :component="Trash" depth="3" />
|
||||
</template>
|
||||
</n-button>
|
||||
<c-button circle variant="text" @click="values.splice(index, 1)">
|
||||
<n-icon :component="Trash" depth="3" size="18" />
|
||||
</c-button>
|
||||
</template>
|
||||
Delete value
|
||||
</n-tooltip>
|
||||
</n-space>
|
||||
|
||||
<n-button tertiary @click="addValue">
|
||||
<template #icon>
|
||||
<n-icon :component="Plus" />
|
||||
</template>
|
||||
<c-button @click="addValue">
|
||||
<n-icon :component="Plus" depth="3" mr-2 size="18" />
|
||||
Add a measure
|
||||
</n-button>
|
||||
</c-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -18,16 +18,16 @@
|
|||
>
|
||||
<n-input-group>
|
||||
<n-input v-model:value="entropy" placeholder="Your string..." />
|
||||
<n-button @click="refreshEntropy">
|
||||
<c-button @click="refreshEntropy">
|
||||
<n-icon size="22">
|
||||
<Refresh />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
<n-button @click="copyEntropy">
|
||||
</c-button>
|
||||
<c-button @click="copyEntropy">
|
||||
<n-icon size="22">
|
||||
<Copy />
|
||||
</n-icon>
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-input-group>
|
||||
</n-form-item>
|
||||
</n-gi>
|
||||
|
@ -48,9 +48,9 @@
|
|||
spellcheck="false"
|
||||
/>
|
||||
|
||||
<n-button @click="copyPassphrase">
|
||||
<c-button @click="copyPassphrase">
|
||||
<n-icon size="22" :component="Copy" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-input-group>
|
||||
</n-form-item>
|
||||
</n-card>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
</n-card>
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button v-if="!isRunning" secondary type="primary" @click="resume">Start</n-button>
|
||||
<n-button v-else secondary type="warning" @click="pause">Stop</n-button>
|
||||
<c-button v-if="!isRunning" secondary type="primary" @click="resume">Start</c-button>
|
||||
<c-button v-else secondary type="warning" @click="pause">Stop</c-button>
|
||||
|
||||
<n-button secondary @click="counter = 0">Reset</n-button>
|
||||
<c-button @click="counter = 0">Reset</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<br />
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button :disabled="dockerCompose === ''" secondary @click="download"> Download docker-compose.yml </n-button>
|
||||
<c-button :disabled="dockerCompose === ''" secondary @click="download"> Download docker-compose.yml </c-button>
|
||||
</n-space>
|
||||
|
||||
<div v-if="notComposable.length > 0">
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
<n-input readonly :value="hmac" type="textarea" placeholder="The result of the HMAC..." />
|
||||
</n-form-item>
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copy()">Copy HMAC</n-button>
|
||||
<c-button @click="copy()">Copy HMAC</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyEscaped"> Copy </n-button>
|
||||
<c-button @click="copyEscaped"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card title="Unescape html entities">
|
||||
|
@ -44,7 +44,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyUnescaped"> Copy </n-button>
|
||||
<c-button @click="copyUnescaped"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<template>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button circle quaternary :type="isActive?.() ? 'primary' : 'default'" @click="action">
|
||||
<template #icon>
|
||||
<c-button circle variant="text" :type="isActive?.() ? 'primary' : 'default'" @click="action">
|
||||
<n-icon :component="icon" />
|
||||
</template>
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
|
||||
{{ title }}
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
The end IPv4 address is lower than the start IPv4 address. This is not valid and no result could be
|
||||
calculated. In the most cases the solution to solve this problem is to change start and end address.
|
||||
</n-text>
|
||||
<n-button quaternary @click="onSwitchStartEndClicked">
|
||||
<n-icon :component="ChangeCircleOutlined" />
|
||||
Switch start and end IPv4 address
|
||||
</n-button>
|
||||
<c-button @click="onSwitchStartEndClicked">
|
||||
<n-icon mr-2 :component="Exchange" depth="3" size="22" />
|
||||
Switch start and end IPv4 address
|
||||
</c-button>
|
||||
</n-space>
|
||||
</n-alert>
|
||||
</div>
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { useValidation } from '@/composable/validation';
|
||||
import { ChangeCircleOutlined } from '@vicons/material';
|
||||
import { Exchange } from '@vicons/tabler';
|
||||
import { isValidIpv4 } from '../ipv4-address-converter/ipv4-address-converter.service';
|
||||
import type { Ipv4RangeExpanderResult } from './ipv4-range-expander.types';
|
||||
import { calculateCidr } from './ipv4-range-expander.service';
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
</n-table>
|
||||
|
||||
<n-space style="margin-top: 14px" justify="space-between">
|
||||
<n-button tertiary @click="switchToBlock({ count: -1 })">
|
||||
<c-button @click="switchToBlock({ count: -1 })">
|
||||
<n-icon :component="ArrowLeft" />
|
||||
Previous block
|
||||
</n-button>
|
||||
<n-button tertiary @click="switchToBlock({ count: 1 })">
|
||||
</c-button>
|
||||
<c-button @click="switchToBlock({ count: 1 })">
|
||||
Next block
|
||||
<n-icon :component="ArrowRight" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<br />
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button secondary autofocus @click="copy"> Copy </n-button>
|
||||
<c-button autofocus @click="copy"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button :disabled="!details" tertiary> Copy vendor info </n-button>
|
||||
<c-button :disabled="!details"> Copy vendor info </c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<template #suffix>
|
||||
<n-tooltip trigger="hover">
|
||||
<template #trigger>
|
||||
<n-button quaternary circle @click="refreshSecret">
|
||||
<c-button circle variant="text" @click="refreshSecret">
|
||||
<n-icon :component="Refresh" />
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
Generate secret token
|
||||
</n-tooltip>
|
||||
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
<n-space justify="center" vertical align="center" style="margin-top: 10px">
|
||||
<n-image :src="qrcode"></n-image>
|
||||
<n-button secondary tag="a" :href="keyUri" target="_blank">Open Key URI in new tab</n-button>
|
||||
<c-button :href="keyUri" target="_blank">Open Key URI in new tab</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
<div style="max-width: 350px">
|
||||
|
|
|
@ -8,31 +8,30 @@
|
|||
<n-input-group>
|
||||
<n-tooltip trigger="hover" placement="bottom">
|
||||
<template #trigger>
|
||||
<n-button data-test-id="previous-otp" secondary @click.prevent="copyPrevious(tokens.previous)">{{
|
||||
tokens.previous
|
||||
}}</n-button>
|
||||
<c-button important:h-12 data-test-id="previous-otp" @click.prevent="copyPrevious(tokens.previous)">
|
||||
{{ tokens.previous }}
|
||||
</c-button>
|
||||
</template>
|
||||
<div>{{ previousCopied ? 'Copied !' : 'Copy previous OTP' }}</div>
|
||||
</n-tooltip>
|
||||
<n-tooltip trigger="hover" placement="bottom">
|
||||
<template #trigger>
|
||||
<n-button
|
||||
tertiary
|
||||
type="primary"
|
||||
<c-button
|
||||
data-test-id="current-otp"
|
||||
class="current-otp"
|
||||
important:h-12
|
||||
@click.prevent="copyCurrent(tokens.current)"
|
||||
>
|
||||
{{ tokens.current }}
|
||||
</n-button>
|
||||
</c-button>
|
||||
</template>
|
||||
<div>{{ currentCopied ? 'Copied !' : 'Copy current OTP' }}</div>
|
||||
</n-tooltip>
|
||||
<n-tooltip trigger="hover" placement="bottom">
|
||||
<template #trigger>
|
||||
<n-button secondary data-test-id="next-otp" @click.prevent="copyNext(tokens.next)">{{
|
||||
<c-button important:h-12 data-test-id="next-otp" @click.prevent="copyNext(tokens.next)">{{
|
||||
tokens.next
|
||||
}}</n-button>
|
||||
}}</c-button>
|
||||
</template>
|
||||
<div>{{ nextCopied ? 'Copied !' : 'Copy next OTP' }}</div>
|
||||
</n-tooltip>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<n-gi>
|
||||
<n-space justify="center" align="center" vertical>
|
||||
<n-image :src="qrcode" width="200" />
|
||||
<n-button secondary @click="download"> Download qr-code </n-button>
|
||||
<c-button @click="download"> Download qr-code </c-button>
|
||||
</n-space>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
{{ port }}
|
||||
</div>
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copy"> Copy </n-button>
|
||||
<n-button secondary @click="refreshPort"> Refresh </n-button>
|
||||
<c-button @click="copy"> Copy </c-button>
|
||||
<c-button @click="refreshPort"> Refresh </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
<div class="result">
|
||||
{{ outputRoman }}
|
||||
</div>
|
||||
<n-button secondary autofocus :disabled="validationNumeral.validationStatus === 'error'" @click="copyRoman">
|
||||
<c-button autofocus :disabled="validationNumeral.validationStatus === 'error'" @click="copyRoman">
|
||||
Copy
|
||||
</n-button>
|
||||
</c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<br />
|
||||
|
@ -22,9 +22,7 @@
|
|||
<div class="result">
|
||||
{{ outputNumeral }}
|
||||
</div>
|
||||
<n-button secondary autofocus :disabled="validationRoman.validationStatus === 'error'" @click="copyArabic">
|
||||
Copy
|
||||
</n-button>
|
||||
<c-button :disabled="validationRoman.validationStatus === 'error'" @click="copyArabic"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<n-input-number v-model:value="bits" min="256" max="16384" step="8" />
|
||||
</n-form-item>
|
||||
|
||||
<n-button tertiary @click="refreshCerts">Refresh key-pair</n-button>
|
||||
<c-button @click="refreshCerts">Refresh key-pair</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary :disabled="slug.length === 0" @click="copy">Copy slug</n-button>
|
||||
<c-button :disabled="slug.length === 0" @click="copy">Copy slug</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copySVG()">Copy svg</n-button>
|
||||
<n-button secondary @click="copyBase64()">Copy base64</n-button>
|
||||
<n-button secondary @click="download()">Download svg</n-button>
|
||||
<c-button @click="copySVG()">Copy svg</c-button>
|
||||
<c-button @click="copyBase64()">Copy base64</c-button>
|
||||
<c-button @click="download()">Download svg</c-button>
|
||||
</n-space>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</n-card>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary autofocus @click="copy"> Copy NATO string </n-button>
|
||||
<c-button autofocus @click="copy"> Copy NATO string </c-button>
|
||||
</n-space>
|
||||
</n-space>
|
||||
</div>
|
||||
|
|
|
@ -44,8 +44,8 @@
|
|||
<br />
|
||||
<br />
|
||||
<n-space justify="center">
|
||||
<n-button secondary autofocus @click="copy"> Copy </n-button>
|
||||
<n-button secondary @click="refreshToken"> Refresh </n-button>
|
||||
<c-button @click="copy"> Copy </c-button>
|
||||
<c-button @click="refreshToken"> Refresh </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyEncoded"> Copy </n-button>
|
||||
<c-button @click="copyEncoded"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card title="Decode">
|
||||
|
@ -52,7 +52,7 @@
|
|||
</n-form-item>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary @click="copyDecoded"> Copy </n-button>
|
||||
<c-button @click="copyDecoded"> Copy </c-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</template>
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
/>
|
||||
|
||||
<n-space justify="center">
|
||||
<n-button secondary autofocus @click="copy"> Copy </n-button>
|
||||
<n-button secondary @click="refreshUUIDs"> Refresh </n-button>
|
||||
<c-button autofocus @click="copy"> Copy </c-button>
|
||||
<c-button @click="refreshUUIDs"> Refresh </c-button>
|
||||
</n-space>
|
||||
</n-space>
|
||||
</template>
|
||||
|
|
240
src/ui/c-button/c-button.theme.ts
Normal file
240
src/ui/c-button/c-button.theme.ts
Normal file
|
@ -0,0 +1,240 @@
|
|||
import { defineThemes } from '../theme/theme.models';
|
||||
import { appThemes } from '../theme/themes';
|
||||
|
||||
export const { useTheme } = defineThemes({
|
||||
dark: {
|
||||
basic: {
|
||||
default: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.08)',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.12)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.24)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
primary: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
warning: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.warning.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
text: {
|
||||
default: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.12)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.82)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
primary: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.primary.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
warning: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.dark.warning.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.warning.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
light: {
|
||||
basic: {
|
||||
default: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.05)',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.09)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.22)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
primary: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.primary.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.primary.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.primary.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.primary.color,
|
||||
},
|
||||
},
|
||||
|
||||
warning: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.warning.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.warning.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.text.baseColor,
|
||||
backgroundColor: appThemes.light.warning.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.warning.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
text: {
|
||||
default: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.09)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.light.text.baseColor,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.13)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.primary.color,
|
||||
},
|
||||
},
|
||||
primary: {
|
||||
textColor: appThemes.light.primary.color,
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.light.primary.colorHover,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.09)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.light.primary.colorPressed,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.13)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.primary.color,
|
||||
},
|
||||
},
|
||||
warning: {
|
||||
textColor: appThemes.light.warning.color,
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.light.warning.colorHover,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.09)',
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.light.warning.colorPressed,
|
||||
backgroundColor: 'rgba(46, 51, 56, 0.13)',
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.warning.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
113
src/ui/c-button/c-button.vue
Normal file
113
src/ui/c-button/c-button.vue
Normal file
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
:href="href ?? to"
|
||||
class="c-button"
|
||||
:class="{ disabled, round, circle }"
|
||||
:to="to"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { RouteLocationRaw } from 'vue-router';
|
||||
import { useTheme } from './c-button.theme';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
type?: 'default' | 'primary';
|
||||
variant?: 'basic' | 'text';
|
||||
disabled?: boolean;
|
||||
round?: boolean;
|
||||
circle?: boolean;
|
||||
href?: string;
|
||||
to?: RouteLocationRaw;
|
||||
}>(),
|
||||
{
|
||||
type: 'default',
|
||||
variant: 'basic',
|
||||
disabled: false,
|
||||
round: false,
|
||||
circle: false,
|
||||
href: undefined,
|
||||
to: undefined,
|
||||
},
|
||||
);
|
||||
const { variant, disabled, round, circle, href, type, to } = toRefs(props);
|
||||
|
||||
const emits = defineEmits(['click']);
|
||||
|
||||
function handleClick(event: MouseEvent) {
|
||||
if (!disabled.value) {
|
||||
emits('click', event);
|
||||
}
|
||||
}
|
||||
|
||||
const theme = useTheme();
|
||||
const variantTheme = computed(() => theme.value[variant.value][type.value]);
|
||||
const tag = computed(() => {
|
||||
if (href.value) {
|
||||
return 'a';
|
||||
}
|
||||
if (to.value) {
|
||||
return 'router-link';
|
||||
}
|
||||
return 'button';
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.c-button {
|
||||
margin: 0;
|
||||
line-height: 1;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
border: none;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
height: 34px;
|
||||
font-weight: 400;
|
||||
color: v-bind('variantTheme.textColor');
|
||||
padding: 0 14px;
|
||||
border-radius: 4px;
|
||||
transition: background-color cubic-bezier(0.4, 0, 0.2, 1) 0.3s;
|
||||
|
||||
background-color: v-bind('variantTheme.backgroundColor');
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
// outline-offset: 1px;
|
||||
&.round {
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
&.circle {
|
||||
border-radius: 40px;
|
||||
width: 34px;
|
||||
}
|
||||
|
||||
&:not(.disabled) {
|
||||
&:hover {
|
||||
background-color: v-bind('variantTheme.hover.backgroundColor');
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: v-bind('variantTheme.pressed.backgroundColor');
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 2px solid v-bind('variantTheme.outline.color');
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
</style>
|
39
src/ui/c-link/c-link.theme.ts
Normal file
39
src/ui/c-link/c-link.theme.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { defineThemes } from '../theme/theme.models';
|
||||
import { appThemes } from '../theme/themes';
|
||||
|
||||
export const { useTheme } = defineThemes({
|
||||
dark: {
|
||||
default: {
|
||||
textColor: appThemes.dark.primary.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.dark.primary.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.dark.primary.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.dark.primary.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
light: {
|
||||
default: {
|
||||
textColor: appThemes.light.primary.color,
|
||||
|
||||
hover: {
|
||||
textColor: appThemes.light.primary.colorHover,
|
||||
},
|
||||
|
||||
pressed: {
|
||||
textColor: appThemes.light.primary.colorPressed,
|
||||
},
|
||||
|
||||
outline: {
|
||||
color: appThemes.light.primary.color,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
49
src/ui/c-link/c-link.vue
Normal file
49
src/ui/c-link/c-link.vue
Normal file
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<component :is="tag" :href="href ?? to" class="c-link" :to="to">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { RouterLink, type RouteLocationRaw } from 'vue-router';
|
||||
import { useTheme } from './c-link.theme';
|
||||
|
||||
const props = defineProps<{
|
||||
href?: string;
|
||||
to?: RouteLocationRaw;
|
||||
}>();
|
||||
|
||||
const { href, to } = toRefs(props);
|
||||
|
||||
const theme = useTheme();
|
||||
const tag = computed(() => (href?.value ? 'a' : RouterLink));
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.c-link {
|
||||
line-height: inherit;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
color: v-bind('theme.default.textColor');
|
||||
border-radius: 4px;
|
||||
transition: color cubic-bezier(0.4, 0, 0.2, 1) 0.3s;
|
||||
|
||||
outline-offset: 1px;
|
||||
|
||||
&:hover {
|
||||
color: v-bind('theme.default.hover.textColor');
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: v-bind('theme.default.textColor');
|
||||
}
|
||||
|
||||
&:focus {
|
||||
color: v-bind('theme.default.outline.color');
|
||||
}
|
||||
}
|
||||
</style>
|
13
src/ui/theme/theme.models.ts
Normal file
13
src/ui/theme/theme.models.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { useThemeStore } from './theme.store';
|
||||
|
||||
export { defineThemes };
|
||||
|
||||
function defineThemes<Theme>(themes: { light: Theme; dark: Theme }) {
|
||||
return {
|
||||
themes,
|
||||
useTheme() {
|
||||
const themeStore = useThemeStore();
|
||||
return computed(() => themes[themeStore.themeType]);
|
||||
},
|
||||
};
|
||||
}
|
20
src/ui/theme/theme.store.ts
Normal file
20
src/ui/theme/theme.store.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
export const useThemeStore = defineStore('ui-theme', {
|
||||
state: () => ({
|
||||
themeType: useStorage<'dark' | 'light'>('ui-store:theme-type', 'dark') as Ref<'dark' | 'light'>,
|
||||
}),
|
||||
getters: {
|
||||
isDarkTheme(): boolean {
|
||||
return this.themeType === 'dark';
|
||||
},
|
||||
isLightTheme(): boolean {
|
||||
return this.themeType === 'light';
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
toggleTheme() {
|
||||
this.themeType = this.isDarkTheme ? 'light' : 'dark';
|
||||
},
|
||||
},
|
||||
});
|
37
src/ui/theme/themes.ts
Normal file
37
src/ui/theme/themes.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { defineThemes } from './theme.models';
|
||||
|
||||
export const { themes: appThemes, useTheme: useAppTheme } = defineThemes({
|
||||
light: {
|
||||
text: {
|
||||
baseColor: 'rgb(51, 54, 57)',
|
||||
},
|
||||
|
||||
primary: {
|
||||
color: '#18a058',
|
||||
colorHover: '#1ea54c',
|
||||
colorPressed: '#0C7A43',
|
||||
},
|
||||
|
||||
warning: {
|
||||
color: '#f59e0b',
|
||||
colorHover: '#f59e0b',
|
||||
colorPressed: '#f59e0b',
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
text: {
|
||||
baseColor: 'rgba(255, 255, 255, 0.82)',
|
||||
},
|
||||
|
||||
primary: {
|
||||
color: '#1ea54c',
|
||||
colorHover: '#36AD6A',
|
||||
colorPressed: '#0C7A43',
|
||||
},
|
||||
warning: {
|
||||
color: '#f59e0b',
|
||||
colorHover: '#f59e0b',
|
||||
colorPressed: '#f59e0b',
|
||||
},
|
||||
},
|
||||
});
|
|
@ -73,6 +73,9 @@ export default defineConfig({
|
|||
},
|
||||
}),
|
||||
Components({
|
||||
dirs: ['src/'],
|
||||
extensions: ['vue', 'md'],
|
||||
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
|
||||
resolvers: [NaiveUiResolver()],
|
||||
}),
|
||||
Unocss(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue