Skip to content
This repository has been archived by the owner on Aug 25, 2024. It is now read-only.

Commit

Permalink
feat: add copy url button
Browse files Browse the repository at this point in the history
  • Loading branch information
elonehoo committed Jan 1, 2024
1 parent 4bf1b9b commit 121afa8
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 6 deletions.
1 change: 1 addition & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default defineNuxtConfig({
css: [
'@unocss/reset/tailwind.css',
'~/styles/splitpanes.css',
'~/styles/input.css',
],
colorMode: {
classSuffix: '',
Expand Down
12 changes: 11 additions & 1 deletion pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ const linkQuery = useRouteQuery('link')

<template>
<div>
<Input v-model="linkQuery" />
<div class="w-full relative">
<Input v-model="linkQuery" />
<div class="absolute right-2 top-1.5 flex flex-gap-1">
<ButtonBase
title="Copy URL"
app="xs blue"
icon="carbon:copy"
:border="false"
/>
</div>
</div>
</div>
</template>
3 changes: 3 additions & 0 deletions styles/input.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:root {
--app-ui-c-context: 125, 125, 125;
}
32 changes: 32 additions & 0 deletions ui/button/Base.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script setup lang="ts">
import { NuxtLink } from '#components'
withDefaults(defineProps<{
to?: string
icon?: string
border?: boolean
disabled?: boolean
type?: 'submit' | 'reset' | 'button'
}>(), {
border: true,
type: 'button',
})
</script>

<template>
<Component
:is="to ? NuxtLink : 'button'"
:to="to"
v-bind="{ ...$attrs, ...(!to && { type }) }"
:class="[
{ 'app-button-base active:app-button-active focus-visible:app-focus-base hover:app-button-hover': border },
{ 'app-icon-button': !$slots.default },
]"
class="app-button app-transition app-disabled:app-disabled"
>
<slot name="icon">
<IconBase v-if="icon" :icon="icon" :class="{ 'app-button-icon': $slots.default }" />
</slot>
<slot />
</Component>
</template>
9 changes: 9 additions & 0 deletions ui/icon/Base.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
defineProps<{
icon?: string
}>()
</script>

<template>
<div class="app-icon" :class="icon" />
</template>
4 changes: 2 additions & 2 deletions ui/input/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defineOptions({
const props = withDefaults(
defineProps<{
modelValue?: string | number
modelValue?: string | number | string[] | null
icon?: string
placeholder?: string
disabled?: boolean
Expand All @@ -28,7 +28,7 @@ const input = useVModel(props, 'modelValue', emit, { passive: true })
<template>
<div class="n-text-input flex flex items-center border app-border-base rounded py-1 pl-1 pr-2 focus-within:app-focus-base focus-within:border-context app-bg-base">
<slot name="icon">
<NIcon v-if="icon" :icon="icon" class="ml-0.3em mr-0.1em text-1.1em op50" />
<IconBase v-if="icon" :icon="icon" class="ml-0.3em mr-0.1em text-1.1em op50" />
</slot>
<input
v-model="input"
Expand Down
47 changes: 44 additions & 3 deletions unocss.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { RuleContext } from '@unocss/core'
import type { Theme } from '@unocss/preset-uno'
import { parseColor } from '@unocss/preset-mini/utils'
import { theme as unoTheme } from '@unocss/preset-mini'
import { fonts } from '@unocss/preset-mini/rules'
import {
defineConfig,
mergeDeep,
Expand All @@ -17,18 +18,45 @@ import {
export default defineConfig({
theme: mergeDeep<Theme>(unoTheme, {
colors: {
context: 'rgba(var(--nui-c-context),%alpha)',
context: 'rgba(var(--app-ui-c-context),%alpha)',
},
}),
rules: [
[/^n-(.*)$/, ([, body]: string[], { theme }: RuleContext<Theme>) => {
[/^app-(.*)$/, ([, body]: string[], { theme }: RuleContext<Theme>) => {
const color = parseColor(body, theme)
if (color?.cssColor?.type === 'rgb' && color.cssColor.components) {
return {
'--nui-c-context': `${color.cssColor.components.join(',')}`,
'--app-ui-c-context': `${color.cssColor.components.join(',')}`,
}
}
}],
[/^app-(.*)$/, fonts[1][1] as any],
['app-dashed', { 'border-style': 'dashed' }],
['app-disabled', {
'opacity': 0.6,
'pointer-events': 'none',
'filter': 'saturate(0)',
}],
],
variants: [
(input: string) => {
const prefix = 'app-disabled:'
if (input.startsWith(prefix)) {
return {
matcher: input.slice(prefix.length),
selector: input => `[disabled] ${input}, ${input}[disabled]`,
}
}
},
(input: string) => {
const prefix = 'app-checked:'
if (input.startsWith(prefix)) {
return {
matcher: input.slice(prefix.length),
selector: input => `[checked] ${input}, ${input}[checked]`,
}
}
},
],
shortcuts: [
['btn', 'px-4 py-1 rounded inline-block bg-teal-600 text-white cursor-pointer hover:bg-teal-700 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
Expand All @@ -41,12 +69,25 @@ export default defineConfig({
['app-bg-base', 'bg-white dark:bg-[#151515]'],
['app-border-base', 'border-gray/20'],
['app-focus-base', 'ring-2 ring-context/50'],
// button
['app-button-base', 'border n-border-base rounded shadow-sm px-1em py-0.25em inline-flex items-center gap-1 op80 !outline-none touch-manipulation'],
['app-button-hover', 'op100 !border-context text-context'],
['app-button-active', 'n-active-base bg-context/5'],
['app-button-icon', '-ml-0.2em mr-0.2em text-1.1em'],
['app-icon-button', 'aspect-1/1 w-1.6em h-1.6em flex items-center justify-center rounded op50 hover:op100 hover:n-bg-active'],
['app-transition', 'transition-all duration-200'],
['app-icon', 'flex-none'],
],
presets: [
presetUno(),
presetAttributify(),
presetIcons({
prefix: ['i-', ''],
scale: 1.2,
extraProperties: {
'display': 'inline-block',
'vertical-align': 'middle',
},
}),
presetTypography(),
presetWebFonts({
Expand Down

0 comments on commit 121afa8

Please sign in to comment.