mirror of
https://github.com/HoshinoSuzumi/rayine-ui.git
synced 2025-05-11 05:12:27 +08:00
Compare commits
No commits in common. "main" and "v1.3.2" have entirely different histories.
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: 'Bug: '
|
|
||||||
labels: bug
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
10
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: 'Feat: '
|
|
||||||
labels: enhancement
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
@ -1,29 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## [1.3.9](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.8...v1.3.9) (2024-11-27)
|
|
||||||
|
|
||||||
## [1.3.8](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.7...v1.3.8) (2024-11-27)
|
|
||||||
|
|
||||||
## [1.3.7](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.6...v1.3.7) (2024-11-26)
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **button:** add `icon` and `loadingIcon` prop support ([2996866](https://github.com/HoshinoSuzumi/rayine-ui/commit/2996866b9adfed79fa64afa8ccd7c1fbfa88d059))
|
|
||||||
|
|
||||||
## [1.3.6](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.5...v1.3.6) (2024-11-26)
|
|
||||||
|
|
||||||
## [1.3.5](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.4...v1.3.5) (2024-11-26)
|
|
||||||
|
|
||||||
## [1.3.4](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.3...v1.3.4) (2024-11-25)
|
|
||||||
|
|
||||||
## [1.3.3](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.3-beta.1...v1.3.3) (2024-11-24)
|
|
||||||
|
|
||||||
## [1.3.3-beta.1](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.2...v1.3.3-beta.1) (2024-11-24)
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **input:** update InputType in input.d.ts ([e9b9b07](https://github.com/HoshinoSuzumi/rayine-ui/commit/e9b9b070f75bd4b1c401801986e3208bf5b6aa0c))
|
|
||||||
|
|
||||||
## [1.3.2](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.1...v1.3.2) (2024-11-23)
|
## [1.3.2](https://github.com/HoshinoSuzumi/rayine-ui/compare/v1.3.1...v1.3.2) (2024-11-23)
|
||||||
|
|
||||||
## v1.3.1
|
## v1.3.1
|
||||||
|
21
LICENSE
21
LICENSE
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 Timothy Yin
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
@ -1,7 +1,5 @@
|
|||||||
# Rayine UI
|
# Rayine UI
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
[![npm version][npm-version-src]][npm-version-href]
|
[![npm version][npm-version-src]][npm-version-href]
|
||||||
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
||||||
[![License][license-src]][license-href]
|
[![License][license-src]][license-href]
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import { defineBuildConfig } from 'unbuild'
|
|
||||||
|
|
||||||
export default defineBuildConfig({
|
|
||||||
externals: ['#ray-colors'],
|
|
||||||
})
|
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg
|
<svg
|
||||||
class="w-8 h-8"
|
class="w-9 h-9"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
viewBox="0 0 970 1008"
|
viewBox="0 0 970 1008"
|
||||||
|
@ -11,7 +11,7 @@ const runtimeConfig = useRuntimeConfig().public
|
|||||||
:class="[route.path !== '/' ? 'border-b-neutral-200 dark:border-b-neutral-700' : 'border-b-transparent dark:border-b-transparent']"
|
:class="[route.path !== '/' ? 'border-b-neutral-200 dark:border-b-neutral-700' : 'border-b-transparent dark:border-b-transparent']"
|
||||||
>
|
>
|
||||||
<NuxtLink to="/" class="flex items-center gap-2 text-neutral-900 dark:text-neutral-100 group">
|
<NuxtLink to="/" class="flex items-center gap-2 text-neutral-900 dark:text-neutral-100 group">
|
||||||
<Logo class="-mt-0.5" />
|
<Logo />
|
||||||
<h1 class="flex flex-col">
|
<h1 class="flex flex-col">
|
||||||
<span class="block font-medium text-xl leading-none">
|
<span class="block font-medium text-xl leading-none">
|
||||||
RayineUI
|
RayineUI
|
||||||
@ -23,9 +23,11 @@ const runtimeConfig = useRuntimeConfig().public
|
|||||||
</h1>
|
</h1>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<RayButton to="https://github.com/HoshinoSuzumi/rayine-ui" target="_blank" icon="tabler:brand-github" variant="ghost">
|
<NuxtLink
|
||||||
GitHub
|
to="https://github.com/HoshinoSuzumi/rayine-ui"
|
||||||
</RayButton>
|
target="_blank"
|
||||||
|
class="text-neutral-400 dark:text-neutral-500"
|
||||||
|
>GitHub</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { camelCase, upperFirst } from 'scule'
|
import { camelCase, upperFirst } from 'scule'
|
||||||
import json5 from 'json5'
|
import json5 from 'json5'
|
||||||
import * as config from '#rayui/themes'
|
import * as config from '#rayui/ui.config'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { camelCase, kebabCase, upperFirst } from 'scule'
|
import { camelCase, kebabCase, upperFirst } from 'scule'
|
||||||
|
import FileTypeVue from '../icon/VscodeIconsFileTypeVue.vue'
|
||||||
|
import FileTypeTypescript from '../icon/VscodeIconsFileTypeTypescriptOfficial.vue'
|
||||||
|
import FileTypeJavascript from '../icon/VscodeIconsFileTypeJsOfficial.vue'
|
||||||
|
import TablerTerminal from '../icon/TablerTerminal.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const appConfig = useAppConfig()
|
const appConfig = useAppConfig()
|
||||||
const { $prettier } = useNuxtApp()
|
|
||||||
|
const IconComponents = {
|
||||||
|
'vue': FileTypeVue,
|
||||||
|
'vue-html': FileTypeVue,
|
||||||
|
'sh': TablerTerminal,
|
||||||
|
'ts': FileTypeTypescript,
|
||||||
|
'js': FileTypeJavascript,
|
||||||
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
slug: {
|
slug: {
|
||||||
@ -14,38 +25,25 @@ const props = defineProps({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
privateProps: {
|
slots: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
},
|
},
|
||||||
excludedProps: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
slots: {
|
|
||||||
type: Object,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
options: {
|
options: {
|
||||||
type: Array as PropType<{ name: string, values: string[], restriction: 'expected' | 'included' | 'excluded' | 'only' }[]>,
|
type: Array as PropType<{ name: string, values: string[], restriction: 'expected' | 'included' | 'excluded' | 'only' }[]>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
excludedProps: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const componentName = props.slug || `Ray${upperFirst(camelCase(route.params.slug[route.params.slug.length - 1]))}`
|
const componentName = props.slug || `Ray${upperFirst(camelCase(route.params.slug[route.params.slug.length - 1]))}`
|
||||||
const componentMeta = await fetchComponentMeta(componentName)
|
const componentMeta = await fetchComponentMeta(componentName)
|
||||||
|
|
||||||
const privateProps = reactive({ ...props.privateProps })
|
|
||||||
const componentProps = reactive({ ...props.props })
|
const componentProps = reactive({ ...props.props })
|
||||||
|
|
||||||
const componentFullProps = computed(() => ({ ...componentProps, ...privateProps }))
|
|
||||||
const componentVModel = computed({
|
|
||||||
get: () => privateProps.modelValue,
|
|
||||||
set: (value) => {
|
|
||||||
privateProps.modelValue = value
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const customizableOptions = (key: string, schema: { kind: string, type: string, schema: [] }) => {
|
const customizableOptions = (key: string, schema: { kind: string, type: string, schema: [] }) => {
|
||||||
let options: string[] = []
|
let options: string[] = []
|
||||||
const optionItem = props?.options?.find(item => item?.name === key) || null
|
const optionItem = props?.options?.find(item => item?.name === key) || null
|
||||||
@ -101,7 +99,7 @@ const customizableProps = computed(() => Object.keys(componentProps).map((k) =>
|
|||||||
return {
|
return {
|
||||||
name: k,
|
name: k,
|
||||||
type: prop?.type || 'string',
|
type: prop?.type || 'string',
|
||||||
label: k === 'modelValue' ? 'value' : camelCase(k),
|
label: camelCase(k),
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
}).filter(prop => prop !== null))
|
}).filter(prop => prop !== null))
|
||||||
@ -111,47 +109,18 @@ const code = computed(() => {
|
|||||||
<template>
|
<template>
|
||||||
<${componentName}`
|
<${componentName}`
|
||||||
|
|
||||||
for (const [k, v] of Object.entries(componentFullProps.value)) {
|
for (const [k, v] of Object.entries(componentProps)) {
|
||||||
if (v === 'undefined' || v === null) {
|
code += ` ${typeof v === 'boolean' || typeof v === 'number' || typeof v === 'object' ? ':' : ''}${kebabCase(k)}="${typeof v === 'object' ? renderObject(v) : v}"`
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
code += ` ${(typeof v === 'boolean' && (k === 'modelValue' || v !== true)) || typeof v === 'number' || typeof v === 'object' ? ':' : ''}${k === 'modelValue' ? 'model-value' : kebabCase(k)}${k !== 'modelValue' && typeof v === 'boolean' && !!v ? '' : `="${typeof v === 'object' ? renderObject(v) : v}"`}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.slots) {
|
code += `/>\n</template>
|
||||||
code += `>
|
|
||||||
${Object.entries(props.slots).map(([key, value]) => {
|
|
||||||
return key === 'default'
|
|
||||||
? value
|
|
||||||
: `<template #${key}>
|
|
||||||
${value}
|
|
||||||
</template>`
|
|
||||||
}).join('\n ')}
|
|
||||||
</${componentName}>`
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
code += ' />'
|
|
||||||
}
|
|
||||||
|
|
||||||
code += `\n</template>
|
|
||||||
\`\`\`
|
\`\`\`
|
||||||
`
|
`
|
||||||
return code
|
return code
|
||||||
})
|
})
|
||||||
|
|
||||||
const { data: codeRender } = await useAsyncData(`${componentName}-code-renderer-${JSON.stringify({ props: componentProps, slots: props.slots, code: code.value })}`, async () => {
|
const { data: codeRender } = await useAsyncData(`${componentName}-code-renderer-${JSON.stringify({ props: componentProps, slots: props.slots, code: code.value })}`, async () => {
|
||||||
let fortmattedCode = ''
|
return parseMarkdown(code.value, {})
|
||||||
try {
|
|
||||||
fortmattedCode = await $prettier.format(code.value, {
|
|
||||||
semi: false,
|
|
||||||
singleQuote: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
fortmattedCode = code.value
|
|
||||||
}
|
|
||||||
return parseMarkdown(fortmattedCode)
|
|
||||||
}, {
|
}, {
|
||||||
watch: [code],
|
watch: [code],
|
||||||
})
|
})
|
||||||
@ -159,12 +128,9 @@ const { data: codeRender } = await useAsyncData(`${componentName}-code-renderer-
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="border border-neutral-200 dark:border-neutral-700 rounded-lg not-prose my-2 overflow-hidden">
|
<div class="border border-neutral-200 dark:border-neutral-700 rounded-lg not-prose my-2 overflow-hidden">
|
||||||
<div :class="['p-4 overflow-auto flex', !!codeRender ? 'border-b border-neutral-200 dark:border-neutral-700' : '']">
|
<div :class="['p-4 overflow-auto', !!codeRender ? 'border-b border-neutral-200 dark:border-neutral-700' : '']">
|
||||||
<component :is="componentName" v-model="componentVModel" v-bind="componentFullProps">
|
<component :is="componentName" v-bind="componentProps">
|
||||||
<ContentSlot v-if="$slots.default" :use="$slots.default" />
|
<slot />
|
||||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
|
||||||
<ContentSlot :name="slot" unwrap="p" />
|
|
||||||
</template>
|
|
||||||
</component>
|
</component>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -187,22 +153,17 @@ const { data: codeRender } = await useAsyncData(`${componentName}-code-renderer-
|
|||||||
{{ option }}
|
{{ option }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<RayInput
|
<input
|
||||||
v-else
|
v-else
|
||||||
:id="`${prop.name}-prop`"
|
:id="`${prop.name}-prop`"
|
||||||
:model-value="componentProps[prop.name]"
|
v-model="componentProps[prop.name]"
|
||||||
:type="prop.type.includes('number') ? 'number' : 'text'"
|
type="text"
|
||||||
variant="plain"
|
placeholder="type something..."
|
||||||
:padded="false"
|
>
|
||||||
:ui="{ rounded: 'rounded-none' }"
|
|
||||||
:placeholder="prop.type"
|
|
||||||
autocomplete="off"
|
|
||||||
@update:model-value="val => componentProps[prop.name] = prop.type === 'number' ? Number(val) : val"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ContentRenderer v-if="codeRender" :value="codeRender" class="[&_.pre]:rounded-none [&_.pre]:border-none" />
|
<ContentRenderer v-if="codeRender" :value="codeRender" class="overflow-auto [&_.pre]:rounded-none [&_.pre]:border-none" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import type { ComponentMeta } from 'vue-component-meta'
|
|
||||||
import { camelCase, upperFirst } from 'scule'
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
slug: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const slug = props.slug || route.params.slug[route.params.slug.length - 1]
|
|
||||||
const componentCamelName = camelCase(slug)
|
|
||||||
const componentName = `Ray${upperFirst(componentCamelName)}`
|
|
||||||
|
|
||||||
const meta = await fetchComponentMeta(componentName)
|
|
||||||
const metaProps: ComputedRef<ComponentMeta['props']> = computed(() => meta?.meta?.props || [])
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<ProseTable>
|
|
||||||
<ProseThead>
|
|
||||||
<ProseTr>
|
|
||||||
<ProseTh>Prop</ProseTh>
|
|
||||||
<ProseTh>Default</ProseTh>
|
|
||||||
<ProseTh>Type</ProseTh>
|
|
||||||
</ProseTr>
|
|
||||||
</ProseThead>
|
|
||||||
<ProseTbody>
|
|
||||||
<ProseTr v-for="prop in metaProps" :key="prop.name">
|
|
||||||
<ProseTd>
|
|
||||||
{{ prop.name }}
|
|
||||||
</ProseTd>
|
|
||||||
<ProseTd>
|
|
||||||
<ProseCodeInline v-if="prop.default">
|
|
||||||
{{ prop.default }}
|
|
||||||
</ProseCodeInline>
|
|
||||||
</ProseTd>
|
|
||||||
<ProseTd>
|
|
||||||
<ProseCodeInline v-if="prop.type">
|
|
||||||
{{ prop.type }}
|
|
||||||
</ProseCodeInline>
|
|
||||||
<MDC v-if="prop.description" :value="prop.description" class="text-gray-500 dark:text-gray-400" />
|
|
||||||
</ProseTd>
|
|
||||||
</ProseTr>
|
|
||||||
</ProseTbody>
|
|
||||||
</ProseTable>
|
|
||||||
</template>
|
|
@ -1,26 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import { camelCase, upperFirst } from 'scule'
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
slug: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const slug = props.slug || route.params.slug[route.params.slug.length - 1]
|
|
||||||
const componentCamelName = camelCase(slug)
|
|
||||||
const componentName = `Ray${upperFirst(componentCamelName)}`
|
|
||||||
|
|
||||||
const meta = await fetchComponentMeta(componentName)
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="flex flex-col not-prose font-mono divide-y divide-gray-100 dark:divide-gray-800">
|
|
||||||
<div v-for="(slot, k) in meta?.meta?.slots" :key="k" class="py-2">
|
|
||||||
<pre>{{ slot }}</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,4 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import FileTypeVue from '../../icon/VscodeIconsFileTypeVue.vue'
|
||||||
|
import FileTypeTypescript from '../../icon/VscodeIconsFileTypeTypescriptOfficial.vue'
|
||||||
|
import FileTypeJavascript from '../../icon/VscodeIconsFileTypeJsOfficial.vue'
|
||||||
|
import TablerTerminal from '../../icon/TablerTerminal.vue'
|
||||||
|
import TablerFile from '~/components/icon/TablerFile.vue'
|
||||||
|
import VscodeIconsFileTypeJson from '~/components/icon/VscodeIconsFileTypeJson.vue'
|
||||||
|
import VscodeIconsFileTypeNuxt from '~/components/icon/VscodeIconsFileTypeNuxt.vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
code: {
|
code: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -30,39 +38,29 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconNameLangMapping: Record<string, string> = {
|
const mapIconLanguage = {
|
||||||
'default': 'tabler:file',
|
'default': TablerFile,
|
||||||
'vue': 'vscode-icons:file-type-vue',
|
'vue': FileTypeVue,
|
||||||
'vue-html': 'vscode-icons:file-type-vue',
|
'vue-html': FileTypeVue,
|
||||||
'bash': 'tabler:terminal',
|
'bash': TablerTerminal,
|
||||||
'sh': 'tabler:terminal',
|
'sh': TablerTerminal,
|
||||||
'ts': 'vscode-icons:file-type-typescript-official',
|
'ts': FileTypeTypescript,
|
||||||
'js': 'vscode-icons:file-type-js-official',
|
'js': FileTypeJavascript,
|
||||||
'json': 'vscode-icons:file-type-json',
|
'json': VscodeIconsFileTypeJson,
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconNameFilenameMapping: Record<string, string> = {
|
const mapIconFilename = {
|
||||||
'nuxt.config.ts': 'vscode-icons:file-type-nuxt',
|
'nuxt.config.ts': VscodeIconsFileTypeNuxt,
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolvedIconName = computed(() => {
|
const resolveIcon = computed(() => {
|
||||||
if (!props.language) {
|
if (props.filename) {
|
||||||
return iconNameLangMapping['default']
|
if (props.filename.endsWith('.vue')) return FileTypeVue
|
||||||
}
|
|
||||||
|
|
||||||
if (props.filename.endsWith('.vue')) {
|
const icon = mapIconFilename[props.filename as keyof typeof mapIconFilename]
|
||||||
return iconNameLangMapping['vue']
|
if (icon) return icon
|
||||||
}
|
}
|
||||||
|
return mapIconLanguage[props.language as keyof typeof mapIconLanguage]
|
||||||
if (iconNameFilenameMapping[props.filename]) {
|
|
||||||
return iconNameFilenameMapping[props.filename]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconNameLangMapping[props.language]) {
|
|
||||||
return iconNameLangMapping[props.language]
|
|
||||||
}
|
|
||||||
|
|
||||||
return iconNameLangMapping['default']
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -70,7 +68,7 @@ const resolvedIconName = computed(() => {
|
|||||||
<div data-prose-pre class="pre rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700">
|
<div data-prose-pre class="pre rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700">
|
||||||
<div v-if="filename" class="p-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
|
<div v-if="filename" class="p-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
|
||||||
<span class="flex items-center gap-1">
|
<span class="flex items-center gap-1">
|
||||||
<RayIcon v-if="resolvedIconName" :name="resolvedIconName" class="inline" />
|
<component :is="resolveIcon" v-if="language" class="inline" />
|
||||||
<span class="text-sm text-neutral-500 dark:text-neutral-400">{{ filename }}</span>
|
<span class="text-sm text-neutral-500 dark:text-neutral-400">{{ filename }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
9
docs/components/icon/TablerFile.vue
Normal file
9
docs/components/icon/TablerFile.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21H7a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2" /></g></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TablerFile',
|
||||||
|
}
|
||||||
|
</script>
|
16
docs/components/icon/TablerTerminal.vue
Normal file
16
docs/components/icon/TablerTerminal.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24"><path
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="m5 7l5 5l-5 5m7 2h7"
|
||||||
|
/></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TablerTerminal',
|
||||||
|
}
|
||||||
|
</script>
|
9
docs/components/icon/VscodeIconsFileTypeJsOfficial.vue
Normal file
9
docs/components/icon/VscodeIconsFileTypeJsOfficial.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M2 2h28v28H2z" /><path d="M20.809 23.875a2.87 2.87 0 0 0 2.6 1.6c1.09 0 1.787-.545 1.787-1.3c0-.9-.716-1.222-1.916-1.747l-.658-.282c-1.9-.809-3.16-1.822-3.16-3.964c0-1.973 1.5-3.476 3.853-3.476a3.89 3.89 0 0 1 3.742 2.107L25 18.128A1.79 1.79 0 0 0 23.311 17a1.145 1.145 0 0 0-1.259 1.128c0 .789.489 1.109 1.618 1.6l.658.282c2.236.959 3.5 1.936 3.5 4.133c0 2.369-1.861 3.667-4.36 3.667a5.06 5.06 0 0 1-4.795-2.691Zm-9.295.228c.413.733.789 1.353 1.693 1.353c.864 0 1.41-.338 1.41-1.653v-8.947h2.631v8.982c0 2.724-1.6 3.964-3.929 3.964a4.085 4.085 0 0 1-3.947-2.4Z" /></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'VscodeIconsFileTypeJsOfficial',
|
||||||
|
}
|
||||||
|
</script>
|
9
docs/components/icon/VscodeIconsFileTypeJson.vue
Normal file
9
docs/components/icon/VscodeIconsFileTypeJson.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#f5de19" d="M4.014 14.976a2.5 2.5 0 0 0 1.567-.518a2.38 2.38 0 0 0 .805-1.358a15.3 15.3 0 0 0 .214-2.944q.012-2.085.075-2.747a5.2 5.2 0 0 1 .418-1.686a3 3 0 0 1 .755-1.018A3.05 3.05 0 0 1 9 4.125A6.8 6.8 0 0 1 10.544 4h.7v1.96h-.387a2.34 2.34 0 0 0-1.723.468a3.4 3.4 0 0 0-.425 2.092a36 36 0 0 1-.137 4.133a4.7 4.7 0 0 1-.768 2.06A4.6 4.6 0 0 1 6.1 16a3.8 3.8 0 0 1 1.992 1.754a8.9 8.9 0 0 1 .618 3.865q0 2.435.05 2.9a1.76 1.76 0 0 0 .504 1.181a2.64 2.64 0 0 0 1.592.337h.387V28h-.7a5.7 5.7 0 0 1-1.773-.2a2.97 2.97 0 0 1-1.324-.93a3.35 3.35 0 0 1-.681-1.63a24 24 0 0 1-.165-3.234a16.5 16.5 0 0 0-.214-3.106a2.4 2.4 0 0 0-.805-1.361a2.5 2.5 0 0 0-1.567-.524Zm23.972 2.035a2.5 2.5 0 0 0-1.567.524a2.4 2.4 0 0 0-.805 1.361a16.5 16.5 0 0 0-.212 3.109a24 24 0 0 1-.169 3.234a3.35 3.35 0 0 1-.681 1.63a2.97 2.97 0 0 1-1.324.93a5.7 5.7 0 0 1-1.773.2h-.7V26.04h.387a2.64 2.64 0 0 0 1.592-.337a1.76 1.76 0 0 0 .506-1.186q.05-.462.05-2.9a8.9 8.9 0 0 1 .618-3.865A3.8 3.8 0 0 1 25.9 16a4.6 4.6 0 0 1-1.7-1.286a4.7 4.7 0 0 1-.768-2.06a36 36 0 0 1-.137-4.133a3.4 3.4 0 0 0-.425-2.092a2.34 2.34 0 0 0-1.723-.468h-.387V4h.7a6.8 6.8 0 0 1 1.54.125a3.05 3.05 0 0 1 1.149.581a3 3 0 0 1 .755 1.018a5.2 5.2 0 0 1 .418 1.686q.062.662.075 2.747a15.3 15.3 0 0 0 .212 2.947a2.38 2.38 0 0 0 .805 1.355a2.5 2.5 0 0 0 1.567.518Z" /></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'VscodeIconsFileTypeJson',
|
||||||
|
}
|
||||||
|
</script>
|
9
docs/components/icon/VscodeIconsFileTypeNuxt.vue
Normal file
9
docs/components/icon/VscodeIconsFileTypeNuxt.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#00DC82" d="M17.708 25h10.409c.33 0 .655-.088.942-.254a1.9 1.9 0 0 0 .689-.696a1.91 1.91 0 0 0 0-1.9L22.756 9.936a1.87 1.87 0 0 0-3.261 0l-1.788 3.125l-3.494-6.111a1.871 1.871 0 0 0-3.262 0l-8.7 15.2a1.91 1.91 0 0 0 .69 2.595c.286.167.61.255.941.255h6.534c2.589 0 4.498-1.147 5.811-3.385l3.19-5.572l1.708-2.982l5.127 8.957h-6.835zm-7.398-2.985l-4.56-.001l6.836-11.942l3.41 5.97l-2.283 3.992c-.873 1.452-1.864 1.981-3.403 1.981" /></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'VscodeIconsFileTypeNuxt',
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><rect
|
||||||
|
width="28"
|
||||||
|
height="28"
|
||||||
|
x="2"
|
||||||
|
y="2"
|
||||||
|
fill="#3178c6"
|
||||||
|
rx="1.312"
|
||||||
|
/><path fill="#fff" fillRule="evenodd" d="M18.245 23.759v3.068a6.5 6.5 0 0 0 1.764.575a11.6 11.6 0 0 0 2.146.192a10 10 0 0 0 2.088-.211a5.1 5.1 0 0 0 1.735-.7a3.54 3.54 0 0 0 1.181-1.266a4.47 4.47 0 0 0 .186-3.394a3.4 3.4 0 0 0-.717-1.117a5.2 5.2 0 0 0-1.123-.877a12 12 0 0 0-1.477-.734q-.6-.249-1.08-.484a5.5 5.5 0 0 1-.813-.479a2.1 2.1 0 0 1-.516-.518a1.1 1.1 0 0 1-.181-.618a1.04 1.04 0 0 1 .162-.571a1.4 1.4 0 0 1 .459-.436a2.4 2.4 0 0 1 .726-.283a4.2 4.2 0 0 1 .956-.1a6 6 0 0 1 .808.058a6 6 0 0 1 .856.177a6 6 0 0 1 .836.3a4.7 4.7 0 0 1 .751.422V13.9a7.5 7.5 0 0 0-1.525-.4a12.4 12.4 0 0 0-1.9-.129a8.8 8.8 0 0 0-2.064.235a5.2 5.2 0 0 0-1.716.733a3.66 3.66 0 0 0-1.171 1.271a3.73 3.73 0 0 0-.431 1.845a3.6 3.6 0 0 0 .789 2.34a6 6 0 0 0 2.395 1.639q.63.26 1.175.509a6.5 6.5 0 0 1 .942.517a2.5 2.5 0 0 1 .626.585a1.2 1.2 0 0 1 .23.719a1.1 1.1 0 0 1-.144.552a1.3 1.3 0 0 1-.435.441a2.4 2.4 0 0 1-.726.292a4.4 4.4 0 0 1-1.018.105a5.8 5.8 0 0 1-1.969-.35a5.9 5.9 0 0 1-1.805-1.045m-5.154-7.638h4v-2.527H5.938v2.527H9.92v11.254h3.171Z" /></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'VscodeIconsFileTypeTypescriptOfficial',
|
||||||
|
}
|
||||||
|
</script>
|
9
docs/components/icon/VscodeIconsFileTypeVue.vue
Normal file
9
docs/components/icon/VscodeIconsFileTypeVue.vue
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 32 32"><path fill="#41b883" d="M24.4 3.925H30l-14 24.15L2 3.925h10.71l3.29 5.6l3.22-5.6Z" /><path fill="#41b883" d="m2 3.925l14 24.15l14-24.15h-5.6L16 18.415L7.53 3.925Z" /><path fill="#35495e" d="M7.53 3.925L16 18.485l8.4-14.56h-5.18L16 9.525l-3.29-5.6Z" /></svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'VscodeIconsFileTypeVue',
|
||||||
|
}
|
||||||
|
</script>
|
@ -12,4 +12,3 @@ This project aims to facilitate sharing a component library across multiple proj
|
|||||||
- Fully customizable components
|
- Fully customizable components
|
||||||
- TailwindCSS inside
|
- TailwindCSS inside
|
||||||
- Full TypeScript support
|
- Full TypeScript support
|
||||||
- 200,000+ icons from [Iconify](https://iconify.design/)
|
|
||||||
|
@ -91,18 +91,6 @@ props:
|
|||||||
Button
|
Button
|
||||||
::
|
::
|
||||||
|
|
||||||
### Icon
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
icon: tabler:adjustments
|
|
||||||
size: sm
|
|
||||||
loading: false
|
|
||||||
---
|
|
||||||
Settings
|
|
||||||
::
|
|
||||||
|
|
||||||
### Loading
|
### Loading
|
||||||
|
|
||||||
::ComponentPreview
|
::ComponentPreview
|
||||||
@ -114,14 +102,7 @@ props:
|
|||||||
Button
|
Button
|
||||||
::
|
::
|
||||||
|
|
||||||
## API
|
## Config
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
::ComponentDefaults
|
||||||
::
|
::
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
description: Add icons to your app. Based on Iconify
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
This component is a wrapper based on the `@nuxt/icon` library, which is based on Iconify. So you can use any icon name available on [icones.js.org](https://icones.js.org/).
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
class: w-6 h-6
|
|
||||||
props:
|
|
||||||
name: tabler:brand-github
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
## Collections
|
|
||||||
|
|
||||||
It's recommended to install the icon collection you want to use locally. You can do this by running:
|
|
||||||
|
|
||||||
```bash [Terminal]
|
|
||||||
pnpm i @iconify-icons/[collection_name]
|
|
||||||
```
|
|
@ -1,155 +0,0 @@
|
|||||||
---
|
|
||||||
description: The input component is used to get user input
|
|
||||||
since: 1.3.2
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
The basic usage.
|
|
||||||
|
|
||||||
:::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Type something..."
|
|
||||||
---
|
|
||||||
:::
|
|
||||||
|
|
||||||
### Sizes
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Type something..."
|
|
||||||
props:
|
|
||||||
size: sm
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Colors
|
|
||||||
|
|
||||||
The `color` prop affects the color of the border.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
color: primary
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Variants
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Search..."
|
|
||||||
props:
|
|
||||||
variant: outline
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Type
|
|
||||||
|
|
||||||
The `type` prop changes the type of the input. All the aviailable types can be found at [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Type anything..."
|
|
||||||
props:
|
|
||||||
type: text
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Placeholder
|
|
||||||
|
|
||||||
The `placeholder` prop sets the placeholder text. It is shown when the input is empty.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
placeholder: "Type anything..."
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Padded
|
|
||||||
|
|
||||||
Inputs can be with no padding.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Search..."
|
|
||||||
variant: plain
|
|
||||||
props:
|
|
||||||
padded: false
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Disabled
|
|
||||||
|
|
||||||
Inputs can be disabled.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: "Search..."
|
|
||||||
props:
|
|
||||||
disabled: true
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Model Modifiers
|
|
||||||
|
|
||||||
#### .trim
|
|
||||||
|
|
||||||
The `.trim` modifier trims the input value.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<string>("");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayInput v-model.trim="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### .number
|
|
||||||
|
|
||||||
The `.number` modifier converts the input value to a number. Non-numeric values are ignored.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<number>(0);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayInput v-model.number="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### .lazy
|
|
||||||
|
|
||||||
The `.lazy` modifier syncs the input value with the model only on `change` event.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<string>("");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayInput v-model.lazy="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
|
||||||
::
|
|
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
description: Display a keyboard keys such as shortcuts or hotkeys
|
|
||||||
since: 1.3.3
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use the default slot to display the keyboard key.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
K
|
|
||||||
::
|
|
||||||
|
|
||||||
The `label` prop also can be used to do so.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
label: K
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Sizes
|
|
||||||
|
|
||||||
The `size` prop changes the size of the `kbd`.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
size: sm
|
|
||||||
---
|
|
||||||
K
|
|
||||||
::
|
|
||||||
|
|
||||||
### Shadow
|
|
||||||
|
|
||||||
Add a shadow to the `kbd`.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
shadow: true
|
|
||||||
---
|
|
||||||
K
|
|
||||||
::
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
|
||||||
::
|
|
@ -1,95 +0,0 @@
|
|||||||
---
|
|
||||||
description: Display a indicator with or without counts on any component
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use the default slot to add any component you want to display the indicator on.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
slots:
|
|
||||||
default: |
|
|
||||||
<RayButton icon="tabler:message" label="messages" color="invert" />
|
|
||||||
---
|
|
||||||
#default
|
|
||||||
:RayButton{icon="tabler:message" label="messages" color="invert"}
|
|
||||||
::
|
|
||||||
|
|
||||||
### Styles
|
|
||||||
|
|
||||||
You can change the color and size of the indicator by using the `color` and `size` props.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
color: amber
|
|
||||||
size: sm
|
|
||||||
slots:
|
|
||||||
default: |
|
|
||||||
<RayButton icon="tabler:message" label="messages" color="invert" />
|
|
||||||
---
|
|
||||||
#default
|
|
||||||
:RayButton{icon="tabler:message" label="messages" color="invert"}
|
|
||||||
::
|
|
||||||
|
|
||||||
### Position
|
|
||||||
|
|
||||||
Use the `position` prop to change the position of the indicator.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
position: top-right
|
|
||||||
slots:
|
|
||||||
default: |
|
|
||||||
<RayButton icon="tabler:message" label="messages" color="invert" />
|
|
||||||
---
|
|
||||||
#default
|
|
||||||
:RayButton{icon="tabler:message" label="messages" color="invert"}
|
|
||||||
::
|
|
||||||
|
|
||||||
### Count
|
|
||||||
|
|
||||||
Add a count to the indicator by using the `value` prop.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
value: 5
|
|
||||||
slots:
|
|
||||||
default: |
|
|
||||||
<RayButton icon="tabler:message" label="messages" color="invert" />
|
|
||||||
---
|
|
||||||
#default
|
|
||||||
:RayButton{icon="tabler:message" label="messages" color="invert"}
|
|
||||||
::
|
|
||||||
|
|
||||||
#### Overflow
|
|
||||||
|
|
||||||
Set `max` prop to handle overflow situation.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
value: 110
|
|
||||||
max: 99
|
|
||||||
slots:
|
|
||||||
default: |
|
|
||||||
<RayButton icon="tabler:message" label="messages" color="invert" />
|
|
||||||
---
|
|
||||||
#default
|
|
||||||
:RayButton{icon="tabler:message" label="messages" color="invert"}
|
|
||||||
::
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
|
||||||
::
|
|
@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
description: The message component is used to display a message to the user
|
description: The message component is used to display a message to the user
|
||||||
since: 1.2.0
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@ -48,20 +47,6 @@ props:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
### Icon
|
|
||||||
|
|
||||||
Or you can use the `icon` prop to change the icon of the message.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
content: Thanks for activating
|
|
||||||
props:
|
|
||||||
icon: tabler:circle-key
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
### Color
|
### Color
|
||||||
|
|
||||||
Use the `color` prop to change the color of the message.
|
Use the `color` prop to change the color of the message.
|
||||||
@ -74,14 +59,7 @@ props:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
## API
|
## Config
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
::ComponentDefaults
|
||||||
::
|
::
|
||||||
|
@ -1,189 +0,0 @@
|
|||||||
---
|
|
||||||
description: Create a textarea component
|
|
||||||
since: 1.3.5
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
The basic usage.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Sizes
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
size: sm
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Colors
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
color: primary
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Variants
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
variant: outline
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Placeholder
|
|
||||||
|
|
||||||
You can also set a placeholder.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
placeholder: "Description here..."
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Padded
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
variant: plain
|
|
||||||
props:
|
|
||||||
padded: false
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Rows
|
|
||||||
|
|
||||||
Set the number of rows of the textarea.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
rows: 4
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Resize
|
|
||||||
|
|
||||||
Enable the resize control.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
resize: true
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Auto Resize
|
|
||||||
|
|
||||||
The `autosize` prop enables the auto resizing of the textarea. The textarea will grow in height as the user types.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
autosize: true
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
The `maxrows` prop can be used to set the maximum number of rows the textarea can grow to.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
autosize: true
|
|
||||||
maxrows: 8
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Disabled
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
placeholder: Description
|
|
||||||
props:
|
|
||||||
disabled: true
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Model Modifiers
|
|
||||||
|
|
||||||
#### .trim
|
|
||||||
|
|
||||||
The `.trim` modifier trims the input value.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<string>("");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayTextarea v-model.trim="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### .number
|
|
||||||
|
|
||||||
The `.number` modifier converts the input value to a number. Non-numeric values are ignored.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<number>(0);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayTextarea v-model.number="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
#### .lazy
|
|
||||||
|
|
||||||
The `.lazy` modifier syncs the input value with the model only on `change` event.
|
|
||||||
|
|
||||||
```vue [page]
|
|
||||||
<script lang="ts" setup>
|
|
||||||
const modal = ref<string>("");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<RayTextarea v-model.lazy="modal" />
|
|
||||||
</template>
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
|
||||||
::
|
|
@ -1,76 +0,0 @@
|
|||||||
---
|
|
||||||
description: Get a dynamic switch component
|
|
||||||
since: 1.3.4
|
|
||||||
---
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Use the `v-model` directive to make it reactive.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
v-model: checked
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Colors
|
|
||||||
|
|
||||||
The `color` prop affects the background color of the toggle.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
modelValue: true
|
|
||||||
props:
|
|
||||||
color: primary
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Sizes
|
|
||||||
|
|
||||||
The default size of the toggle is `md`.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
size: md
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Rounded
|
|
||||||
|
|
||||||
You can make the toggle rounded by setting the `rounded` prop to `true`.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
props:
|
|
||||||
rounded: true
|
|
||||||
size: md
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
### Disabled
|
|
||||||
|
|
||||||
Disable it.
|
|
||||||
|
|
||||||
::ComponentPreview
|
|
||||||
---
|
|
||||||
privateProps:
|
|
||||||
modelValue: true
|
|
||||||
props:
|
|
||||||
disabled: true
|
|
||||||
---
|
|
||||||
::
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Props
|
|
||||||
|
|
||||||
::ComponentProps
|
|
||||||
::
|
|
||||||
|
|
||||||
### Theme
|
|
||||||
|
|
||||||
::ComponentDefaults
|
|
||||||
::
|
|
@ -50,7 +50,6 @@ export default defineNuxtConfig({
|
|||||||
componentMeta: {
|
componentMeta: {
|
||||||
exclude: [
|
exclude: [
|
||||||
'@nuxt/content',
|
'@nuxt/content',
|
||||||
'@nuxt/icon',
|
|
||||||
'@nuxtjs/color-mode',
|
'@nuxtjs/color-mode',
|
||||||
'@nuxtjs/mdc',
|
'@nuxtjs/mdc',
|
||||||
'nuxt/dist',
|
'nuxt/dist',
|
||||||
@ -60,15 +59,10 @@ export default defineNuxtConfig({
|
|||||||
type: false,
|
type: false,
|
||||||
props: true,
|
props: true,
|
||||||
slots: true,
|
slots: true,
|
||||||
events: true,
|
events: false,
|
||||||
exposed: false,
|
exposed: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
icon: {
|
|
||||||
clientBundle: {
|
|
||||||
scan: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rayui: {
|
rayui: {
|
||||||
globalComponents: true,
|
globalComponents: true,
|
||||||
safeColors: [...excludeColors(colors)],
|
safeColors: [...excludeColors(colors)],
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "rayine-ui-docs",
|
"name": "rayine-ui-docs",
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nuxt build",
|
"build": "nuxt build",
|
||||||
@ -10,15 +9,13 @@
|
|||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/vscode-icons": "^1.2.2",
|
|
||||||
"@nuxt/content": "^2.13.4",
|
"@nuxt/content": "^2.13.4",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
"@nuxtjs/mdc": "^0.9.2",
|
"@nuxtjs/mdc": "^0.9.2",
|
||||||
"nuxt": "^3.14.159",
|
"nuxt": "^3.14.159",
|
||||||
"nuxt-component-meta": "^0.9.0",
|
"nuxt-component-meta": "^0.9.0",
|
||||||
"nuxt-shiki": "^0.3.0",
|
"nuxt-shiki": "^0.3.0",
|
||||||
"prettier": "^3.3.3",
|
"rayine-ui": "workspace:rayine-ui",
|
||||||
"rayine-ui": "latest",
|
|
||||||
"ufo": "^1.5.4",
|
"ufo": "^1.5.4",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
"vue-router": "latest"
|
"vue-router": "latest"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { withoutTrailingSlash } from 'ufo'
|
import { withoutTrailingSlash } from 'ufo'
|
||||||
import { standard } from '#rayui/themes'
|
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
@ -41,10 +40,10 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
|
|||||||
<li v-for="child in link.children" :key="child._path">
|
<li v-for="child in link.children" :key="child._path">
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
:to="child._path"
|
:to="child._path"
|
||||||
class="text-sm text-neutral-500 dark:text-neutral-400 flex items-center gap-1"
|
class="text-sm text-neutral-500 dark:text-neutral-400"
|
||||||
active-class="text-primary dark:text-primary font-medium"
|
active-class="text-primary dark:text-primary font-medium"
|
||||||
>
|
>
|
||||||
<span>{{ child.title }}</span>
|
{{ child.title }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -56,19 +55,9 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
|
|||||||
|
|
||||||
<div class="col-span-12" :class="[hasToc ? 'md:col-span-8' : 'md:col-span-10']">
|
<div class="col-span-12" :class="[hasToc ? 'md:col-span-8' : 'md:col-span-10']">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between items-center">
|
<h1 class="text-3xl text-primary font-medium">
|
||||||
<h1 class="text-3xl text-primary font-medium">
|
{{ page?.title || 'untitled' }}
|
||||||
{{ page?.title || 'untitled' }}
|
</h1>
|
||||||
</h1>
|
|
||||||
<div
|
|
||||||
v-if="page?.since"
|
|
||||||
class="ring-1 ring-inset ring-primary-200 dark:ring-primary-900 text-primary-500 dark:text-primary-400 rounded-md bg-primary-50 dark:bg-primary-900 font-medium flex items-center gap-1"
|
|
||||||
:class="[standard.padding['sm'], standard.size['2xs']]"
|
|
||||||
>
|
|
||||||
<RayIcon name="tabler:git-merge" class="text-sm -mt-0.5" />
|
|
||||||
v{{ page.since }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p v-if="page?.description" class="text-lg text-neutral-500 dark:text-neutral-400 mt-2">
|
<p v-if="page?.description" class="text-lg text-neutral-500 dark:text-neutral-400 mt-2">
|
||||||
{{ page.description }}
|
{{ page.description }}
|
||||||
</p>
|
</p>
|
||||||
@ -137,7 +126,7 @@ const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.surround-btn {
|
.surround-btn {
|
||||||
@apply font-medium;
|
@apply font-medium;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
@apply bg-neutral-100 dark:bg-neutral-800 rounded-lg px-8 py-6 w-full h-full flex flex-col gap-0 border border-transparent;
|
@apply bg-neutral-100 dark:bg-neutral-800 rounded-lg px-8 py-6 w-full h-full flex flex-col gap-0 border border-transparent;
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
// ref: https://github.com/nuxt/ui/blob/f3632ddee511f0fccb24d4fc37403421e84ffdae/docs/plugins/prettier.ts
|
|
||||||
import type { Options } from 'prettier'
|
|
||||||
import { defu } from 'defu'
|
|
||||||
import PrettierWorker from '@/workers/prettier.js?worker&inline'
|
|
||||||
|
|
||||||
export interface SimplePrettier {
|
|
||||||
format: (source: string, options?: Options) => Promise<string>
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPrettierWorkerApi(worker: Worker): SimplePrettier {
|
|
||||||
let counter = 0
|
|
||||||
const handlers: any = {}
|
|
||||||
|
|
||||||
worker.addEventListener('message', (event) => {
|
|
||||||
const { uid, message, error } = event.data
|
|
||||||
|
|
||||||
if (!handlers[uid]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const [resolve, reject] = handlers[uid]
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
||||||
delete handlers[uid]
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
reject(error)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(message)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
function postMessage<T>(message: any) {
|
|
||||||
const uid = ++counter
|
|
||||||
return new Promise<T>((resolve, reject) => {
|
|
||||||
handlers[uid] = [resolve, reject]
|
|
||||||
worker.postMessage({ uid, message })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
format(source: string, options?: Options) {
|
|
||||||
return postMessage({ type: 'format', source, options })
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default defineNuxtPlugin(async () => {
|
|
||||||
let prettier: SimplePrettier
|
|
||||||
if (import.meta.server) {
|
|
||||||
const prettierModule = await import('prettier')
|
|
||||||
prettier = {
|
|
||||||
format(source, options = {}) {
|
|
||||||
return prettierModule.format(
|
|
||||||
source,
|
|
||||||
defu(options, {
|
|
||||||
parser: 'markdown',
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const worker = new PrettierWorker()
|
|
||||||
prettier = createPrettierWorkerApi(worker)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
provide: {
|
|
||||||
prettier,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
6378
docs/pnpm-lock.yaml
generated
Normal file
6378
docs/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg id="rayine" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024">
|
|
||||||
<defs>
|
|
||||||
<style>
|
|
||||||
.cls-1 {
|
|
||||||
fill: #3f3f46;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cls-1, .cls-2, .cls-3 {
|
|
||||||
stroke-width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cls-2 {
|
|
||||||
fill: #71717a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cls-3 {
|
|
||||||
fill: #a5b4fc;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</defs>
|
|
||||||
<g id="r_leg">
|
|
||||||
<path class="cls-1" d="m949.3,851.91v121.45c0,15.27-12.38,27.64-27.64,27.64h-122.51c-7.33,0-14.36-2.91-19.55-8.1l-384.22-384.22,262.61-3.69c18.78,0,28.64-6.04,46.42-9.42l236.79,236.79c5.18,5.18,8.1,12.22,8.1,19.55Z"/>
|
|
||||||
</g>
|
|
||||||
<path id="r_head" class="cls-2" d="m949.3,316.84c0,142.4-102,260.99-236.93,286.69-17.79,3.38-36.14,5.16-54.91,5.16h-262.07v-208.38h207.85c20.44,0,39.18-7.36,53.69-19.57,18.2-15.3,29.77-38.24,29.77-63.89s-11.57-48.59-29.77-63.89c-14.51-12.22-33.25-19.57-53.69-19.57-.18,0-.35,0-.53.01h0s-207.32-.01-207.32-.01V25h262.07c161.18,0,291.84,130.66,291.84,291.84Z"/>
|
|
||||||
<g id="cube_3">
|
|
||||||
<rect class="cls-1" x="76.7" y="691.61" width="249.85" height="309.39" rx="26" ry="26"/>
|
|
||||||
</g>
|
|
||||||
<rect id="cube_2" class="cls-3" x="76.7" y="400.3" width="249.85" height="208.38" rx="26" ry="26"/>
|
|
||||||
<g id="cube_1">
|
|
||||||
<rect class="cls-1" x="76.7" y="25" width="249.85" height="292.37" rx="26" ry="26"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,34 +0,0 @@
|
|||||||
// ref: https://github.com/nuxt/ui/blob/f3632ddee511f0fccb24d4fc37403421e84ffdae/docs/workers/prettier.js
|
|
||||||
/* eslint-disable no-undef */
|
|
||||||
self.onmessage = async function (event) {
|
|
||||||
self.postMessage({
|
|
||||||
uid: event.data.uid,
|
|
||||||
message: await handleMessage(event.data.message),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleMessage(message) {
|
|
||||||
switch (message.type) {
|
|
||||||
case 'format':
|
|
||||||
return handleFormatMessage(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleFormatMessage(message) {
|
|
||||||
if (!globalThis.prettier) {
|
|
||||||
await Promise.all([
|
|
||||||
import('https://unpkg.com/prettier@3.3.3/standalone.js'),
|
|
||||||
import('https://unpkg.com/prettier@3.3.3/plugins/html.js'),
|
|
||||||
import('https://unpkg.com/prettier@3.3.3/plugins/markdown.js'),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
const { options, source } = message
|
|
||||||
const formatted = await prettier.format(source, {
|
|
||||||
parser: 'markdown',
|
|
||||||
plugins: prettierPlugins,
|
|
||||||
...options,
|
|
||||||
})
|
|
||||||
|
|
||||||
return formatted
|
|
||||||
}
|
|
@ -10,7 +10,7 @@ export default createConfigForNuxt({
|
|||||||
stylistic: true,
|
stylistic: true,
|
||||||
},
|
},
|
||||||
dirs: {
|
dirs: {
|
||||||
src: ['./playground', './docs'],
|
src: ['./playground'],
|
||||||
},
|
},
|
||||||
}).overrideRules({
|
}).overrideRules({
|
||||||
'@typescript-eslint/no-unused-expressions': [
|
'@typescript-eslint/no-unused-expressions': [
|
||||||
|
11
package.json
11
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rayine-ui",
|
"name": "rayine-ui",
|
||||||
"version": "1.3.9",
|
"version": "1.3.2",
|
||||||
"description": "RayineSoft UI Components",
|
"description": "RayineSoft UI Components",
|
||||||
"repository": "HoshinoSuzumi/rayine-ui",
|
"repository": "HoshinoSuzumi/rayine-ui",
|
||||||
"homepage": "https://rayui.uniiem.com",
|
"homepage": "https://rayui.uniiem.com",
|
||||||
@ -31,9 +31,6 @@
|
|||||||
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
|
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify-json/svg-spinners": "^1.2.1",
|
|
||||||
"@iconify-json/tabler": "^1.2.8",
|
|
||||||
"@nuxt/icon": "^1.8.2",
|
|
||||||
"@nuxt/kit": "^3.14.159",
|
"@nuxt/kit": "^3.14.159",
|
||||||
"@nuxtjs/tailwindcss": "^6.12.2",
|
"@nuxtjs/tailwindcss": "^6.12.2",
|
||||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||||
@ -57,12 +54,8 @@
|
|||||||
"nuxt": "^3.14.159",
|
"nuxt": "^3.14.159",
|
||||||
"release-it": "^17.10.0",
|
"release-it": "^17.10.0",
|
||||||
"release-it-pnpm": "^4.6.3",
|
"release-it-pnpm": "^4.6.3",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "latest",
|
||||||
"vitest": "^2.1.5",
|
"vitest": "^2.1.5",
|
||||||
"vue-tsc": "^2.1.10"
|
"vue-tsc": "^2.1.10"
|
||||||
},
|
|
||||||
"resolutions": {
|
|
||||||
"rayine-ui": "workspace:*",
|
|
||||||
"typescript": "5.6.3"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
1362
pnpm-lock.yaml
generated
1362
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -6,11 +6,10 @@ import {
|
|||||||
addPlugin,
|
addPlugin,
|
||||||
addComponentsDir,
|
addComponentsDir,
|
||||||
addImportsDir,
|
addImportsDir,
|
||||||
installModule,
|
|
||||||
} from '@nuxt/kit'
|
} from '@nuxt/kit'
|
||||||
import { name, version } from '../package.json'
|
import { name, version } from '../package.json'
|
||||||
import { installTailwind } from './tailwind'
|
import { installTailwind } from './tailwind'
|
||||||
import type { Strategy, DeepPartial } from './runtime/types/index'
|
import type { Strategy, DeepPartial } from './runtime/types/utils'
|
||||||
import { createTemplates } from './template'
|
import { createTemplates } from './template'
|
||||||
|
|
||||||
const _require = createRequire(import.meta.url)
|
const _require = createRequire(import.meta.url)
|
||||||
@ -66,7 +65,6 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
createTemplates(_nuxt)
|
createTemplates(_nuxt)
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
await installModule('@nuxt/icon')
|
|
||||||
installTailwind(_options, _nuxt, resolve)
|
installTailwind(_options, _nuxt, resolve)
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
import { twJoin, twMerge } from 'tailwind-merge'
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
||||||
|
import type { DeepPartial, Strategy } from '../../types/utils'
|
||||||
|
import type { ButtonColor, ButtonSize, ButtonVariant } from '../../types/button'
|
||||||
import { getNonUndefinedValuesFromObject } from '../../utils'
|
import { getNonUndefinedValuesFromObject } from '../../utils'
|
||||||
import { nuxtLinkProps } from '../../utils/link'
|
import { nuxtLinkProps } from '../../utils/link'
|
||||||
import { button } from '../../themes'
|
import { button } from '../../ui.config'
|
||||||
import type { ButtonColor, ButtonSize, ButtonVariant, DeepPartial, Strategy } from '../../types/index'
|
|
||||||
import { useRayUI } from '#build/imports'
|
import { useRayUI } from '#build/imports'
|
||||||
|
|
||||||
const config = button
|
const config = button
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
props: {
|
||||||
...nuxtLinkProps,
|
...nuxtLinkProps,
|
||||||
class: {
|
class: {
|
||||||
@ -61,10 +61,6 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
default: () => config.default.loadingIcon,
|
default: () => config.default.loadingIcon,
|
||||||
},
|
},
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
ui: {
|
ui: {
|
||||||
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
||||||
default: () => ({}),
|
default: () => ({}),
|
||||||
@ -82,7 +78,6 @@ export default defineComponent({
|
|||||||
ui.value.base,
|
ui.value.base,
|
||||||
ui.value.font,
|
ui.value.font,
|
||||||
ui.value.rounded,
|
ui.value.rounded,
|
||||||
ui.value.gap[props.size],
|
|
||||||
ui.value.size[props.size],
|
ui.value.size[props.size],
|
||||||
props.padded && ui.value.padding[props.size],
|
props.padded && ui.value.padding[props.size],
|
||||||
variant?.replaceAll('{color}', props.color),
|
variant?.replaceAll('{color}', props.color),
|
||||||
@ -90,23 +85,12 @@ export default defineComponent({
|
|||||||
), props.class)
|
), props.class)
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconClass = computed(() => {
|
|
||||||
return twJoin(
|
|
||||||
ui.value.icon.base,
|
|
||||||
ui.value.icon.size[props.size],
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const leadingIconName = computed(() => props.loading ? props.loadingIcon : props.icon)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
ui,
|
ui,
|
||||||
attrs,
|
attrs,
|
||||||
extProps,
|
extProps,
|
||||||
buttonClass,
|
buttonClass,
|
||||||
iconClass,
|
|
||||||
leadingIconName,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -115,7 +99,7 @@ export default defineComponent({
|
|||||||
<template>
|
<template>
|
||||||
<RayLink type="button" :disabled="disabled || loading" :class="buttonClass" v-bind="{ ...extProps, ...attrs }">
|
<RayLink type="button" :disabled="disabled || loading" :class="buttonClass" v-bind="{ ...extProps, ...attrs }">
|
||||||
<slot name="leading" :disabled="disabled" :loading="loading">
|
<slot name="leading" :disabled="disabled" :loading="loading">
|
||||||
<RayIcon v-if="leadingIconName" :name="leadingIconName" :class="iconClass" />
|
<IconSpinner v-if="loading" class="mr-1" />
|
||||||
</slot>
|
</slot>
|
||||||
<slot>
|
<slot>
|
||||||
<span v-if="label">{{ label }}</span>
|
<span v-if="label">{{ label }}</span>
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { defineComponent, type PropType } from 'vue'
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
mode: {
|
|
||||||
type: String as PropType<'svg' | 'css'>,
|
|
||||||
required: false,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: [String, Number],
|
|
||||||
required: false,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
customize: {
|
|
||||||
type: Function,
|
|
||||||
required: false,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<Icon v-bind="$props" />
|
|
||||||
</template>
|
|
@ -1,63 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
|
||||||
import { kbd } from '../../themes'
|
|
||||||
import type { DeepPartial, KbdSize, Strategy } from '../../types'
|
|
||||||
import { useRayUI } from '#build/imports'
|
|
||||||
|
|
||||||
const config = kbd
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<KbdSize>,
|
|
||||||
default: config.default.size,
|
|
||||||
},
|
|
||||||
shadow: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const { ui, attrs } = useRayUI('kbd', toRef(props, 'ui'), config)
|
|
||||||
|
|
||||||
const kbdClass = computed(() => {
|
|
||||||
return twMerge(twJoin(
|
|
||||||
ui.value.base,
|
|
||||||
ui.value.background,
|
|
||||||
ui.value.rounded,
|
|
||||||
ui.value.font,
|
|
||||||
ui.value.padding,
|
|
||||||
ui.value.ring,
|
|
||||||
props.shadow && ui.value.shadow,
|
|
||||||
ui.value.size[props.size],
|
|
||||||
), props.class)
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
|
||||||
ui,
|
|
||||||
attrs,
|
|
||||||
kbdClass,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<kbd :class="kbdClass" v-bind="attrs">
|
|
||||||
<slot>{{ label }}</slot>
|
|
||||||
</kbd>
|
|
||||||
</template>
|
|
@ -1,90 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
|
||||||
import { mark } from '../../themes'
|
|
||||||
import type { MarkColor, MarkPosition, MarkSize } from '../../types'
|
|
||||||
import { useRayUI } from '#build/imports'
|
|
||||||
|
|
||||||
const config = mark
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
max: {
|
|
||||||
type: Number,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<MarkSize>,
|
|
||||||
default: config.default.size,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String as PropType<MarkColor>,
|
|
||||||
default: config.default.color,
|
|
||||||
},
|
|
||||||
position: {
|
|
||||||
type: String as PropType<MarkPosition>,
|
|
||||||
default: config.default.position,
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
type: Object as PropType<typeof config>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const { ui, attrs } = useRayUI('mark', toRef(props, 'ui'), config)
|
|
||||||
|
|
||||||
const markClass = computed(() => {
|
|
||||||
return twMerge(twJoin(
|
|
||||||
ui.value.base,
|
|
||||||
ui.value.rounded,
|
|
||||||
ui.value.ring,
|
|
||||||
ui.value.position[props.position],
|
|
||||||
ui.value.background.replaceAll('{color}', props.color),
|
|
||||||
props.value ? ui.value.value.size[props.size] : ui.value.size[props.size],
|
|
||||||
props.value ? ui.value.value.translate[props.position] : ui.value.translate[props.position],
|
|
||||||
), props.class)
|
|
||||||
})
|
|
||||||
|
|
||||||
const isOverMax = computed(() => {
|
|
||||||
if (props.max === null) return false
|
|
||||||
if (typeof props.value === 'string') return false
|
|
||||||
return props.value > props.max
|
|
||||||
})
|
|
||||||
|
|
||||||
// consider string value
|
|
||||||
const countValue = computed(() => {
|
|
||||||
if (typeof props.value === 'string') return props.value
|
|
||||||
return isOverMax.value ? `${props.max}+` : props.value
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
|
||||||
ui,
|
|
||||||
attrs,
|
|
||||||
markClass,
|
|
||||||
isOverMax,
|
|
||||||
countValue,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="ui.wrapper">
|
|
||||||
<span :class="markClass">
|
|
||||||
<Transition v-bind="ui.transition">
|
|
||||||
<span v-if="value" :key="countValue" class="leading-none">{{ countValue }}</span>
|
|
||||||
</Transition>
|
|
||||||
</span>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,164 +1,14 @@
|
|||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
|
||||||
import defu from 'defu'
|
|
||||||
import { input } from '../../themes'
|
|
||||||
import type { DeepPartial, InputColor, InputModelModifiers, InputSize, InputType, InputVariant, Strategy } from '../../types/index'
|
|
||||||
import { onMounted, ref, useRayUI } from '#build/imports'
|
|
||||||
|
|
||||||
const config = input
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
|
||||||
modelValue: {
|
|
||||||
type: [String, Number] as PropType<string | number | null>,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String as PropType<InputType>,
|
|
||||||
default: 'text',
|
|
||||||
},
|
|
||||||
autofocus: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
autofocusDelay: {
|
|
||||||
type: Number,
|
|
||||||
default: 100,
|
|
||||||
},
|
|
||||||
required: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
padded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<InputSize>,
|
|
||||||
default: () => config.default.size,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String as PropType<InputColor>,
|
|
||||||
default: () => config.default.color,
|
|
||||||
},
|
|
||||||
variant: {
|
|
||||||
type: String as PropType<InputVariant>,
|
|
||||||
default: () => config.default.variant,
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
modelModifiers: {
|
|
||||||
type: Object as PropType<InputModelModifiers>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ['update:modelValue', 'change', 'blur'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const { ui, attrs } = useRayUI('input', toRef(props, 'ui'), config)
|
|
||||||
const modelModifiers = ref(defu({}, props.modelModifiers, { lazy: false, number: false, trim: false }))
|
|
||||||
|
|
||||||
const input = ref<HTMLInputElement | null>(null)
|
|
||||||
|
|
||||||
const baseClass = computed(() => {
|
|
||||||
return twMerge(twJoin(
|
|
||||||
ui.value.base,
|
|
||||||
ui.value.rounded,
|
|
||||||
ui.value.placeholder,
|
|
||||||
ui.value.size[props.size],
|
|
||||||
props.padded && ui.value.padding[props.size],
|
|
||||||
ui.value.variant[props.variant].replaceAll('{color}', props.color),
|
|
||||||
), props.class)
|
|
||||||
})
|
|
||||||
|
|
||||||
const updateValue = (value: string) => {
|
|
||||||
if (modelModifiers.value.trim) {
|
|
||||||
value = value.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelModifiers.value.number || props.type === 'number') {
|
|
||||||
const n = Number.parseFloat(value)
|
|
||||||
value = (Number.isNaN(n) ? value : n) as any
|
|
||||||
}
|
|
||||||
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onInput = (e: Event) => {
|
|
||||||
if (modelModifiers.value.lazy) return
|
|
||||||
updateValue((e.target as HTMLInputElement).value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onChange = (e: Event) => {
|
|
||||||
if (props.type === 'file') {
|
|
||||||
emit('change', (e.target as HTMLInputElement).files)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const value = (e.target as HTMLInputElement).value
|
|
||||||
emit('change', value)
|
|
||||||
if (modelModifiers.value.lazy) {
|
|
||||||
updateValue(value)
|
|
||||||
}
|
|
||||||
if (modelModifiers.value.trim) {
|
|
||||||
(e.target as HTMLInputElement).value = value.trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onBlur = (e: Event) => {
|
|
||||||
emit('blur', e)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.autofocus) {
|
|
||||||
setTimeout(() => {
|
|
||||||
input.value?.focus()
|
|
||||||
}, props.autofocusDelay)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
|
||||||
ui,
|
|
||||||
attrs,
|
|
||||||
baseClass,
|
|
||||||
input,
|
|
||||||
onInput,
|
|
||||||
onChange,
|
|
||||||
onBlur,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="type === 'hidden' ? 'hidden' : ui.wrapper">
|
<input
|
||||||
<input
|
placeholder="test from rayine"
|
||||||
ref="input"
|
class="rounded-lg border border-neutral-200 px-2 py-1"
|
||||||
:type="type"
|
>
|
||||||
:class="baseClass"
|
|
||||||
:disabled="disabled"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:required="required"
|
|
||||||
v-bind="type === 'file' ? attrs : { ...attrs, value: modelValue }"
|
|
||||||
@input="onInput"
|
|
||||||
@change="onChange"
|
|
||||||
@blur="onBlur"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
@ -1,195 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, onMounted, ref, toRef, watch, type PropType } from 'vue'
|
|
||||||
import { twMerge, twJoin } from 'tailwind-merge'
|
|
||||||
import defu from 'defu'
|
|
||||||
import { textarea } from '../../themes'
|
|
||||||
import type { DeepPartial, Strategy, TextareaColor, TextareaModelModifiers, TextareaSize, TextareaVariant } from '../../types'
|
|
||||||
import { useRayUI } from '#build/imports'
|
|
||||||
|
|
||||||
const config = textarea
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
|
||||||
modelValue: {
|
|
||||||
type: [String, Number] as PropType<string | number | null>,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<TextareaSize>,
|
|
||||||
default: config.default.size,
|
|
||||||
},
|
|
||||||
variant: {
|
|
||||||
type: String as PropType<TextareaVariant>,
|
|
||||||
default: config.default.variant,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String as PropType<TextareaColor>,
|
|
||||||
default: config.default.color,
|
|
||||||
},
|
|
||||||
autofocus: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
autofocusDelay: {
|
|
||||||
type: Number,
|
|
||||||
default: 100,
|
|
||||||
},
|
|
||||||
placeholder: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
rows: {
|
|
||||||
type: Number,
|
|
||||||
default: 3,
|
|
||||||
},
|
|
||||||
autosize: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
maxrows: {
|
|
||||||
type: Number,
|
|
||||||
default: 0,
|
|
||||||
},
|
|
||||||
padded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
resize: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
modelModifiers: {
|
|
||||||
type: Object as PropType<TextareaModelModifiers>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: [
|
|
||||||
'update:modelValue',
|
|
||||||
'blur',
|
|
||||||
'change',
|
|
||||||
],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const { ui, attrs } = useRayUI('textarea', toRef(props, 'ui'), config)
|
|
||||||
const modelModifiers = ref(defu({}, props.modelModifiers, { lazy: false, number: false, trim: false }))
|
|
||||||
|
|
||||||
const textarea = ref<HTMLTextAreaElement | null>(null)
|
|
||||||
|
|
||||||
const baseClass = computed(() => {
|
|
||||||
return twMerge(twJoin(
|
|
||||||
ui.value.base,
|
|
||||||
ui.value.rounded,
|
|
||||||
ui.value.placeholder,
|
|
||||||
ui.value.size[props.size],
|
|
||||||
props.padded && ui.value.padding[props.size],
|
|
||||||
ui.value.variant[props.variant].replaceAll('{color}', props.color),
|
|
||||||
!props.resize && 'resize-none',
|
|
||||||
), props.class)
|
|
||||||
})
|
|
||||||
|
|
||||||
const autoResize = () => {
|
|
||||||
if (!props.autosize) return
|
|
||||||
if (!textarea.value) return
|
|
||||||
textarea.value.rows = props.rows
|
|
||||||
const overflowBefore = textarea.value.style.overflow
|
|
||||||
textarea.value.style.overflow = 'hidden'
|
|
||||||
|
|
||||||
const style = window.getComputedStyle(textarea.value)
|
|
||||||
const padding = Number.parseInt(style.paddingTop) + Number.parseInt(style.paddingBottom)
|
|
||||||
const lineHeight = Number.parseInt(style.lineHeight)
|
|
||||||
const { scrollHeight, clientHeight } = textarea.value
|
|
||||||
const computedRows = Math.floor((scrollHeight - padding) / lineHeight)
|
|
||||||
if (computedRows > props.rows) {
|
|
||||||
textarea.value.rows = props.maxrows ? Math.min(computedRows, props.maxrows) : computedRows
|
|
||||||
}
|
|
||||||
textarea.value.style.overflow = overflowBefore
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateValue = (value: string) => {
|
|
||||||
if (modelModifiers.value.trim) {
|
|
||||||
value = value.trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modelModifiers.value.number) {
|
|
||||||
const n = Number.parseFloat(value)
|
|
||||||
value = (Number.isNaN(n) ? value : n) as any
|
|
||||||
}
|
|
||||||
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onInput = (e: Event) => {
|
|
||||||
autoResize()
|
|
||||||
if (modelModifiers.value.lazy) return
|
|
||||||
updateValue((e.target as HTMLInputElement).value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onChange = (e: Event) => {
|
|
||||||
const value = (e.target as HTMLInputElement).value
|
|
||||||
emit('change', value)
|
|
||||||
if (modelModifiers.value.lazy) {
|
|
||||||
updateValue(value)
|
|
||||||
}
|
|
||||||
if (modelModifiers.value.trim) {
|
|
||||||
(e.target as HTMLInputElement).value = value.trim()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onBlur = (e: Event) => {
|
|
||||||
emit('blur', e)
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(() => props.modelValue, () => {
|
|
||||||
autoResize()
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (props.autofocus) {
|
|
||||||
setTimeout(() => {
|
|
||||||
textarea.value?.focus()
|
|
||||||
}, props.autofocusDelay)
|
|
||||||
}
|
|
||||||
autoResize()
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
|
||||||
ui,
|
|
||||||
attrs,
|
|
||||||
textarea,
|
|
||||||
baseClass,
|
|
||||||
onInput,
|
|
||||||
onChange,
|
|
||||||
onBlur,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="ui.wrapper">
|
|
||||||
<textarea
|
|
||||||
ref="textarea"
|
|
||||||
:class="baseClass"
|
|
||||||
:rows="rows"
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:disabled="disabled"
|
|
||||||
:value="modelValue"
|
|
||||||
v-bind="attrs"
|
|
||||||
@input="onInput"
|
|
||||||
@change="onChange"
|
|
||||||
@blur="onBlur"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
@ -1,100 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
|
||||||
import { toggle } from '../../themes'
|
|
||||||
import type { DeepPartial, Strategy, ToggleColor, ToggleSize } from '../../types'
|
|
||||||
import { useRayUI } from '#build/imports'
|
|
||||||
|
|
||||||
const config = toggle
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
props: {
|
|
||||||
modelValue: {
|
|
||||||
type: Boolean as PropType<boolean | null>,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
rounded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<ToggleSize>,
|
|
||||||
default: config.default.size,
|
|
||||||
},
|
|
||||||
color: {
|
|
||||||
type: String as PropType<ToggleColor>,
|
|
||||||
default: config.default.color,
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
ui: {
|
|
||||||
type: Object as PropType<DeepPartial<typeof config> & { strategy?: Strategy }>,
|
|
||||||
default: () => ({}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: [
|
|
||||||
'update:modelValue',
|
|
||||||
'change',
|
|
||||||
],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const { ui, attrs } = useRayUI('toggle', toRef(props, 'ui'), config)
|
|
||||||
|
|
||||||
const checked = computed({
|
|
||||||
get: () => props.modelValue,
|
|
||||||
set: (value: boolean) => {
|
|
||||||
emit('update:modelValue', value)
|
|
||||||
emit('change', value)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const toggleClass = computed(() => {
|
|
||||||
return twMerge(twJoin(
|
|
||||||
ui.value.base,
|
|
||||||
props.rounded ? 'rounded-full' : ui.value.rounded,
|
|
||||||
ui.value.size[props.size],
|
|
||||||
ui.value.ring.replaceAll('{color}', props.color),
|
|
||||||
checked.value ? ui.value.active.replaceAll('{color}', props.color) : ui.value.inactive,
|
|
||||||
), props.class)
|
|
||||||
})
|
|
||||||
|
|
||||||
const bulletClass = computed(() => {
|
|
||||||
return twJoin(
|
|
||||||
ui.value.bullet.base,
|
|
||||||
props.rounded ? 'rounded-full' : ui.value.bullet.rounded,
|
|
||||||
ui.value.bullet.shadow,
|
|
||||||
ui.value.bullet.size[props.size],
|
|
||||||
!props.disabled && ui.value.bullet.translate[props.size],
|
|
||||||
checked.value ? ui.value.bullet.active[props.size] : ui.value.bullet.inactive,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
const handleClick = () => {
|
|
||||||
if (!props.disabled) {
|
|
||||||
checked.value = !checked.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
|
||||||
ui,
|
|
||||||
attrs,
|
|
||||||
checked,
|
|
||||||
toggleClass,
|
|
||||||
bulletClass,
|
|
||||||
handleClick,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<button :class="toggleClass" :disabled="disabled" v-bind="attrs" @click="handleClick">
|
|
||||||
<span :class="bulletClass" />
|
|
||||||
</button>
|
|
||||||
</template>
|
|
@ -1,8 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMounted, defineComponent, type PropType, toRef, computed } from 'vue'
|
import { ref, onMounted, defineComponent, type PropType, toRef, computed } from 'vue'
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
import { twJoin, twMerge } from 'tailwind-merge'
|
||||||
import { message } from '../../themes'
|
import type { Message, MessageColor, MessageType } from '../../types/message'
|
||||||
import type { DeepPartial, Message, MessageColor, MessageType, Strategy } from '../../types/index'
|
import { message } from '../../ui.config'
|
||||||
|
import type { DeepPartial, Strategy } from '../../types'
|
||||||
import { useMessage, useRayUI } from '#build/imports'
|
import { useMessage, useRayUI } from '#build/imports'
|
||||||
|
|
||||||
const config = message
|
const config = message
|
||||||
@ -17,10 +18,6 @@ export default defineComponent({
|
|||||||
type: String as PropType<MessageColor>,
|
type: String as PropType<MessageColor>,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
},
|
},
|
||||||
icon: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
duration: {
|
duration: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: config.default.duration,
|
default: config.default.duration,
|
||||||
@ -67,10 +64,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const iconName = computed(() => {
|
|
||||||
return props.icon || ui.value.type[props.type]?.icon || null
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
message.remove(messageBody.value.id)
|
message.remove(messageBody.value.id)
|
||||||
@ -83,7 +76,6 @@ export default defineComponent({
|
|||||||
attrs,
|
attrs,
|
||||||
messageBody,
|
messageBody,
|
||||||
containerClass,
|
containerClass,
|
||||||
iconName,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -92,7 +84,10 @@ export default defineComponent({
|
|||||||
<template>
|
<template>
|
||||||
<div :class="ui.wrapper" v-bind="attrs">
|
<div :class="ui.wrapper" v-bind="attrs">
|
||||||
<div :class="containerClass">
|
<div :class="containerClass">
|
||||||
<RayIcon v-if="iconName" :name="iconName" class="text-xl" />
|
<IconCircleSuccess v-if="messageBody?.type === 'success'" class="text-xl" />
|
||||||
|
<IconCircleWarning v-if="messageBody?.type === 'warning'" class="text-xl" />
|
||||||
|
<IconCircleError v-if="messageBody?.type === 'error'" class="text-xl" />
|
||||||
|
<IconCircleInfo v-if="messageBody?.type === 'info'" class="text-xl" />
|
||||||
<span>
|
<span>
|
||||||
{{ messageBody.content }}
|
{{ messageBody.content }}
|
||||||
</span>
|
</span>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, toRef, type PropType } from 'vue'
|
import { computed, defineComponent, ref, toRef, type PropType } from 'vue'
|
||||||
import { twJoin, twMerge } from 'tailwind-merge'
|
import { twJoin, twMerge } from 'tailwind-merge'
|
||||||
import { messages } from '../../themes'
|
import type { Message, MessageType } from '../../types/message'
|
||||||
import type { DeepPartial, Message, Strategy } from '../../types/index'
|
import { messages } from '../../ui.config'
|
||||||
|
import type { DeepPartial, Strategy } from '../../types'
|
||||||
import { useState } from '#imports'
|
import { useState } from '#imports'
|
||||||
import { useRayUI } from '#build/imports'
|
import { useRayUI } from '#build/imports'
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import type { Message } from '../types/message'
|
import type { Message, MessageType } from '../types/message'
|
||||||
import { useState } from '#imports'
|
import { useState } from '#imports'
|
||||||
|
|
||||||
export const useMessage = () => {
|
export const useMessage = () => {
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
export default {
|
|
||||||
base: 'inline-flex justify-center items-center text-gray-900 dark:text-gray-100 leading-none',
|
|
||||||
rounded: 'rounded',
|
|
||||||
font: 'font-medium',
|
|
||||||
background: 'bg-gray-100 dark:bg-gray-800',
|
|
||||||
ring: 'ring-1 ring-inset ring-gray-300 dark:ring-gray-700',
|
|
||||||
padding: 'px-1',
|
|
||||||
shadow: 'shadow-sm',
|
|
||||||
size: {
|
|
||||||
xs: 'h-4 min-w-4 text-[10px]',
|
|
||||||
sm: 'h-5 min-w-5 text-[11px]',
|
|
||||||
md: 'h-6 min-w-6 text-xs',
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
size: 'sm',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
export default {
|
|
||||||
wrapper: 'relative',
|
|
||||||
base: 'absolute text-white rounded-full inline-flex justify-center items-center',
|
|
||||||
ring: 'ring-2 ring-white dark:ring-gray-900',
|
|
||||||
rounded: 'rounded-full',
|
|
||||||
background: 'bg-{color}-500',
|
|
||||||
position: {
|
|
||||||
'top-left': 'top-0 left-0',
|
|
||||||
'top-right': 'top-0 right-0',
|
|
||||||
'bottom-left': 'bottom-0 left-0',
|
|
||||||
'bottom-right': 'bottom-0 right-0',
|
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
'top-left': '-translate-x-0.5 -translate-y-0.5',
|
|
||||||
'top-right': 'translate-x-0.5 -translate-y-0.5',
|
|
||||||
'bottom-left': '-translate-x-0.5 translate-y-0.5',
|
|
||||||
'bottom-right': 'translate-x-0.5 translate-y-0.5',
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
xs: 'w-1.5 h-1.5',
|
|
||||||
sm: 'w-2 h-2',
|
|
||||||
md: 'w-2.5 h-2.5',
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
size: {
|
|
||||||
xs: 'px-1 h-3 leading-none text-xs',
|
|
||||||
sm: 'px-1.5 h-4 leading-none text-xs',
|
|
||||||
md: 'px-2 h-5 leading-none text-sm',
|
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
'top-left': '-translate-x-1/3 -translate-y-1/3',
|
|
||||||
'top-right': 'translate-x-1/3 -translate-y-1/3',
|
|
||||||
'bottom-left': '-translate-x-1/3 translate-y-1/3',
|
|
||||||
'bottom-right': 'translate-x-1/3 translate-y-1/3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
transition: {
|
|
||||||
moveClass: 'transform ease-out duration-300 transition',
|
|
||||||
enterActiveClass: 'transform ease-out duration-300 transition',
|
|
||||||
leaveActiveClass: 'transform ease-out duration-300 transition absolute',
|
|
||||||
enterFromClass: 'translate-y-2 opacity-0',
|
|
||||||
enterToClass: 'translate-y-0 opacity-100',
|
|
||||||
leaveFromClass: 'translate-y-0 opacity-100',
|
|
||||||
leaveToClass: '-translate-y-2 opacity-0',
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
size: 'sm',
|
|
||||||
color: 'primary',
|
|
||||||
position: 'top-right',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
import { standard } from '..'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
wrapper: 'relative',
|
|
||||||
base: 'relative w-full block focus:outline-none disabled:cursor-not-allowed disabled:opacity-70 transition',
|
|
||||||
placeholder: 'placeholder:text-gray-400 dark:placeholder:text-gray-500',
|
|
||||||
rounded: 'rounded-md',
|
|
||||||
size: {
|
|
||||||
...standard.size,
|
|
||||||
},
|
|
||||||
padding: {
|
|
||||||
...standard.padding,
|
|
||||||
},
|
|
||||||
variant: {
|
|
||||||
outline: 'shadow-sm bg-transparent text-gray-900 dark:text-white ring ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-{color}-500 dark:focus:ring-{color}-400',
|
|
||||||
plain: 'bg-transparent',
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
size: 'sm',
|
|
||||||
color: 'primary',
|
|
||||||
variant: 'outline',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
import { standard } from '..'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
wrapper: 'relative',
|
|
||||||
base: 'relative w-full block focus:outline-none disabled:cursor-not-allowed disabled:opacity-70 transition',
|
|
||||||
placeholder: 'placeholder:text-gray-400 dark:placeholder:text-gray-500',
|
|
||||||
rounded: 'rounded-md',
|
|
||||||
size: {
|
|
||||||
...standard.size,
|
|
||||||
},
|
|
||||||
padding: {
|
|
||||||
...standard.padding,
|
|
||||||
},
|
|
||||||
variant: {
|
|
||||||
outline:
|
|
||||||
'shadow-sm bg-transparent text-gray-900 dark:text-white ring ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-{color}-500 dark:focus:ring-{color}-400',
|
|
||||||
plain: 'bg-transparent',
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
size: 'sm',
|
|
||||||
color: 'primary',
|
|
||||||
variant: 'outline',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
export default {
|
|
||||||
base: 'relative inline-flex flex-shrink-0 shadow-inner disabled:cursor-not-allowed disabled:opacity-50 focus:outline-none transition ease-in-out duration-200 group',
|
|
||||||
rounded: 'rounded-md',
|
|
||||||
ring: 'focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-{color}-500 dark:focus-visible:ring-{color}-400 focus-visible:ring-offset-white dark:focus-visible:ring-offset-gray-900',
|
|
||||||
active: 'bg-{color}-500 dark:bg-{color}-400',
|
|
||||||
inactive: 'bg-gray-100 dark:bg-gray-800',
|
|
||||||
size: {
|
|
||||||
'2xs': 'h-3 w-5',
|
|
||||||
'xs': 'h-3.5 w-6',
|
|
||||||
'sm': 'h-4 w-7',
|
|
||||||
'md': 'h-5 w-9',
|
|
||||||
'lg': 'h-6 w-11',
|
|
||||||
'xl': 'h-7 w-[3.25rem]',
|
|
||||||
'2xl': 'h-8 w-[3.75rem]',
|
|
||||||
},
|
|
||||||
bullet: {
|
|
||||||
base: 'relative inline-block m-0.5 bg-white dark:bg-gray-900 pointer-events-none transform transition ease-in-out duration-300 group-active:scale-90 group-disabled:scale-100',
|
|
||||||
shadow: 'shadow',
|
|
||||||
rounded: 'rounded',
|
|
||||||
size: {
|
|
||||||
'2xs': 'h-2 w-2',
|
|
||||||
'xs': 'h-2.5 w-2.5',
|
|
||||||
'sm': 'h-3 w-3',
|
|
||||||
'md': 'h-4 w-4',
|
|
||||||
'lg': 'h-5 w-5',
|
|
||||||
'xl': 'h-6 w-6',
|
|
||||||
'2xl': 'h-7 w-7',
|
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
'2xs': 'group-active:translate-x-1',
|
|
||||||
'xs': 'group-active:translate-x-1.5',
|
|
||||||
'sm': 'group-active:translate-x-2',
|
|
||||||
'md': 'group-active:translate-x-2.5',
|
|
||||||
'lg': 'group-active:translate-x-3',
|
|
||||||
'xl': 'group-active:translate-x-3.5',
|
|
||||||
'2xl': 'group-active:translate-x-4',
|
|
||||||
},
|
|
||||||
active: {
|
|
||||||
'2xs': 'translate-x-2',
|
|
||||||
'xs': 'translate-x-2.5',
|
|
||||||
'sm': 'translate-x-3',
|
|
||||||
'md': 'translate-x-4',
|
|
||||||
'lg': 'translate-x-5',
|
|
||||||
'xl': 'translate-x-6',
|
|
||||||
'2xl': 'translate-x-7',
|
|
||||||
},
|
|
||||||
inactive: 'translate-x-0',
|
|
||||||
},
|
|
||||||
default: {
|
|
||||||
size: 'md',
|
|
||||||
color: 'primary',
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
// universal
|
|
||||||
export { default as standard } from './standard'
|
|
||||||
|
|
||||||
// elements
|
|
||||||
export { default as button } from './elements/button'
|
|
||||||
export { default as kbd } from './elements/kbd'
|
|
||||||
export { default as mark } from './elements/mark'
|
|
||||||
|
|
||||||
// forms
|
|
||||||
export { default as input } from './forms/input'
|
|
||||||
export { default as textarea } from './forms/textarea'
|
|
||||||
export { default as toggle } from './forms/toggle'
|
|
||||||
|
|
||||||
// overlays
|
|
||||||
export { default as message } from './overlays/message'
|
|
||||||
export { default as messages } from './overlays/messages'
|
|
@ -1,34 +0,0 @@
|
|||||||
export default {
|
|
||||||
size: {
|
|
||||||
'2xs': 'text-xs',
|
|
||||||
'xs': 'text-xs',
|
|
||||||
'sm': 'text-sm',
|
|
||||||
'md': 'text-sm',
|
|
||||||
'lg': 'text-sm',
|
|
||||||
'xl': 'text-base',
|
|
||||||
},
|
|
||||||
gap: {
|
|
||||||
'2xs': 'gap-x-1',
|
|
||||||
'xs': 'gap-x-1.5',
|
|
||||||
'sm': 'gap-x-1.5',
|
|
||||||
'md': 'gap-x-2',
|
|
||||||
'lg': 'gap-x-2.5',
|
|
||||||
'xl': 'gap-x-2.5',
|
|
||||||
},
|
|
||||||
padding: {
|
|
||||||
'2xs': 'px-2 py-1',
|
|
||||||
'xs': 'px-2.5 py-1.5',
|
|
||||||
'sm': 'px-2.5 py-1.5',
|
|
||||||
'md': 'px-3 py-2',
|
|
||||||
'lg': 'px-3.5 py-2.5',
|
|
||||||
'xl': 'px-3.5 py-2.5',
|
|
||||||
},
|
|
||||||
square: {
|
|
||||||
'2xs': 'p-1',
|
|
||||||
'xs': 'p-1.5',
|
|
||||||
'sm': 'p-1.5',
|
|
||||||
'md': 'p-2',
|
|
||||||
'lg': 'p-2.5',
|
|
||||||
'xl': 'p-2.5',
|
|
||||||
},
|
|
||||||
} as const
|
|
2
src/runtime/types/button.d.ts
vendored
2
src/runtime/types/button.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
import type { AppConfig } from 'nuxt/schema'
|
import type { AppConfig } from 'nuxt/schema'
|
||||||
import type { button } from '../themes'
|
import type { button } from '../ui.config'
|
||||||
import type { ExtractDeepObject, NestedKeyOf, ExtractDeepKey } from './utils'
|
import type { ExtractDeepObject, NestedKeyOf, ExtractDeepKey } from './utils'
|
||||||
import type colors from '#ray-colors'
|
import type colors from '#ray-colors'
|
||||||
|
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
export * from './button'
|
export * from './button'
|
||||||
export * from './message'
|
export * from './message'
|
||||||
export * from './input'
|
|
||||||
export * from './textarea'
|
|
||||||
export * from './kbd'
|
|
||||||
export * from './toggle'
|
|
||||||
export * from './mark'
|
|
||||||
|
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
|
20
src/runtime/types/input.d.ts
vendored
20
src/runtime/types/input.d.ts
vendored
@ -1,20 +0,0 @@
|
|||||||
import type { AppConfig } from 'nuxt/schema'
|
|
||||||
import type { input } from '../themes'
|
|
||||||
import type { ExtractDeepKey } from './utils'
|
|
||||||
import type colors from '#ray-colors'
|
|
||||||
|
|
||||||
export type InputSize =
|
|
||||||
| keyof typeof input.size
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'input', 'size']>
|
|
||||||
export type InputColor =
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'input', 'color']>
|
|
||||||
| (typeof colors)[number]
|
|
||||||
export type InputVariant =
|
|
||||||
| keyof typeof input.variant
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'input', 'variant']>
|
|
||||||
export type InputType = 'text' | 'password' | 'number' | 'url' | 'email' | 'search' | 'file' | 'hidden'
|
|
||||||
export type InputModelModifiers = {
|
|
||||||
number?: boolean
|
|
||||||
trim?: boolean
|
|
||||||
lazy?: boolean
|
|
||||||
}
|
|
7
src/runtime/types/kbd.d.ts
vendored
7
src/runtime/types/kbd.d.ts
vendored
@ -1,7 +0,0 @@
|
|||||||
import type { AppConfig } from 'nuxt/schema'
|
|
||||||
import type { kbd } from '../themes'
|
|
||||||
import type { ExtractDeepKey } from './utils'
|
|
||||||
|
|
||||||
export type KbdSize =
|
|
||||||
| keyof typeof kbd.size
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'kbd', 'size']>
|
|
14
src/runtime/types/mark.d.ts
vendored
14
src/runtime/types/mark.d.ts
vendored
@ -1,14 +0,0 @@
|
|||||||
import type { AppConfig } from '@nuxt/schema'
|
|
||||||
import type { mark } from '../themes'
|
|
||||||
import type { ExtractDeepKey } from './utils'
|
|
||||||
import type colors from '#ray-colors'
|
|
||||||
|
|
||||||
export type MarkSize =
|
|
||||||
| keyof typeof mark.size
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'mark', 'size']>
|
|
||||||
export type MarkColor =
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'mark', 'color']>
|
|
||||||
| (typeof colors)[number]
|
|
||||||
export type MarkPosition =
|
|
||||||
| keyof typeof mark.position
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'mark', 'position']>
|
|
2
src/runtime/types/message.d.ts
vendored
2
src/runtime/types/message.d.ts
vendored
@ -1,5 +1,5 @@
|
|||||||
import type { AppConfig } from 'nuxt/schema'
|
import type { AppConfig } from 'nuxt/schema'
|
||||||
import type { message } from '../themes'
|
import type { message } from '../ui.config'
|
||||||
import type colors from '#ray-colors'
|
import type colors from '#ray-colors'
|
||||||
|
|
||||||
export type MessageType = keyof typeof message.type
|
export type MessageType = keyof typeof message.type
|
||||||
|
19
src/runtime/types/textarea.d.ts
vendored
19
src/runtime/types/textarea.d.ts
vendored
@ -1,19 +0,0 @@
|
|||||||
import type { AppConfig } from '@nuxt/schema'
|
|
||||||
import type { textarea } from '../themes'
|
|
||||||
import type { ExtractDeepKey } from './utils'
|
|
||||||
import type colors from '#ray-colors'
|
|
||||||
|
|
||||||
export type TextareaSize =
|
|
||||||
| keyof typeof textarea.size
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'textarea', 'size']>
|
|
||||||
export type TextareaColor =
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'textarea', 'color']>
|
|
||||||
| (typeof colors)[number]
|
|
||||||
export type TextareaVariant =
|
|
||||||
| keyof typeof textarea.variant
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'textarea', 'variant']>
|
|
||||||
export type TextareaModelModifiers = {
|
|
||||||
number?: boolean
|
|
||||||
trim?: boolean
|
|
||||||
lazy?: boolean
|
|
||||||
}
|
|
9
src/runtime/types/toggle.d.ts
vendored
9
src/runtime/types/toggle.d.ts
vendored
@ -1,9 +0,0 @@
|
|||||||
import type { AppConfig } from '@nuxt/schema'
|
|
||||||
import type { toggle } from '../themes'
|
|
||||||
import type { ExtractDeepKey } from './utils'
|
|
||||||
import type colors from '#ray-colors'
|
|
||||||
|
|
||||||
export type ToggleSize =
|
|
||||||
| keyof typeof toggle.size
|
|
||||||
| ExtractDeepKey<AppConfig, ['rayui', 'toggle', 'size']>
|
|
||||||
export type ToggleColor = (typeof colors)[number]
|
|
@ -1,29 +1,40 @@
|
|||||||
import { standard } from '..'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
base: 'focus:outline-none focus-visible:outline-0 disabled:cursor-not-allowed disabled:opacity-70 aria-disabled:cursor-not-allowed aria-disabled:opacity-70 flex-shrink-0 transition text-left break-all line-clamp-1',
|
base: 'focus:outline-none focus-visible:outline-0 disabled:cursor-not-allowed disabled:opacity-70 aria-disabled:cursor-not-allowed aria-disabled:opacity-70 flex-shrink-0 transition',
|
||||||
rounded: 'rounded-lg',
|
rounded: 'rounded-lg',
|
||||||
font: 'font-medium',
|
font: 'font-medium',
|
||||||
block: 'w-full flex justify-center items-center',
|
block: 'w-full flex justify-center items-center',
|
||||||
inline: 'inline-flex items-center',
|
inline: 'inline-flex items-center',
|
||||||
size: {
|
size: {
|
||||||
...standard.size,
|
'2xs': 'text-xs',
|
||||||
|
'xs': 'text-xs',
|
||||||
|
'sm': 'text-sm',
|
||||||
|
'md': 'text-sm',
|
||||||
|
'lg': 'text-sm',
|
||||||
|
'xl': 'text-base',
|
||||||
},
|
},
|
||||||
padding: {
|
padding: {
|
||||||
...standard.padding,
|
'2xs': 'px-2 py-1',
|
||||||
|
'xs': 'px-2.5 py-1.5',
|
||||||
|
'sm': 'px-2.5 py-1.5',
|
||||||
|
'md': 'px-3 py-2',
|
||||||
|
'lg': 'px-3.5 py-2.5',
|
||||||
|
'xl': 'px-3.5 py-2.5',
|
||||||
},
|
},
|
||||||
square: {
|
square: {
|
||||||
...standard.square,
|
'2xs': 'p-1',
|
||||||
},
|
'xs': 'p-1.5',
|
||||||
gap: {
|
'sm': 'p-1.5',
|
||||||
...standard.gap,
|
'md': 'p-2',
|
||||||
|
'lg': 'p-2.5',
|
||||||
|
'xl': 'p-2.5',
|
||||||
},
|
},
|
||||||
icon: {
|
icon: {
|
||||||
base: 'flex-shrink-0',
|
base: 'flex-shrink-0',
|
||||||
|
loading: 'animate-spin',
|
||||||
size: {
|
size: {
|
||||||
'2xs': 'h-4 w-4',
|
'2xs': 'h-4 w-4',
|
||||||
'xs': 'h-4 w-4',
|
'xs': 'h-4 w-4',
|
||||||
'sm': 'h-4 w-4',
|
'sm': 'h-5 w-5',
|
||||||
'md': 'h-5 w-5',
|
'md': 'h-5 w-5',
|
||||||
'lg': 'h-5 w-5',
|
'lg': 'h-5 w-5',
|
||||||
'xl': 'h-6 w-6',
|
'xl': 'h-6 w-6',
|
||||||
@ -53,6 +64,6 @@ export default {
|
|||||||
size: 'sm',
|
size: 'sm',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
variant: 'solid',
|
variant: 'solid',
|
||||||
loadingIcon: 'svg-spinners:90-ring-with-bg',
|
loadingIcon: 'loading',
|
||||||
},
|
},
|
||||||
}
|
}
|
6
src/runtime/ui.config/index.ts
Normal file
6
src/runtime/ui.config/index.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// elements
|
||||||
|
export { default as button } from './elements/button'
|
||||||
|
|
||||||
|
// overlays
|
||||||
|
export { default as message } from './overlays/message'
|
||||||
|
export { default as messages } from './overlays/messages'
|
@ -9,19 +9,15 @@ export default {
|
|||||||
type: {
|
type: {
|
||||||
success: {
|
success: {
|
||||||
color: 'emerald',
|
color: 'emerald',
|
||||||
icon: 'tabler:circle-check',
|
|
||||||
},
|
},
|
||||||
warning: {
|
warning: {
|
||||||
color: 'amber',
|
color: 'amber',
|
||||||
icon: 'tabler:alert-circle',
|
|
||||||
},
|
},
|
||||||
error: {
|
error: {
|
||||||
color: 'red',
|
color: 'red',
|
||||||
icon: 'tabler:circle-x',
|
|
||||||
},
|
},
|
||||||
info: {
|
info: {
|
||||||
color: 'blue',
|
color: 'blue',
|
||||||
icon: 'tabler:info-circle',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: {
|
default: {
|
@ -161,34 +161,6 @@ const safelistForComponent: Record<
|
|||||||
variants: ['dark'],
|
variants: ['dark'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
input: colorsToRegex => [
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^text-(${colorsToRegex})-400$`),
|
|
||||||
variants: ['placeholder'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^text-(${colorsToRegex})-500$`),
|
|
||||||
variants: ['dark:placeholder'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^ring-(${colorsToRegex})-400$`),
|
|
||||||
variants: ['dark:focus'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^ring-(${colorsToRegex})-500$`),
|
|
||||||
variants: ['focus'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
toggle: colorsToRegex => [
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^ring-(${colorsToRegex})-400$`),
|
|
||||||
variants: ['focus-visible', 'dark'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: RegExp(`^ring-(${colorsToRegex})-500$`),
|
|
||||||
variants: ['focus-visible'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateSafelist = (colors: string[], globalColors: string[]) => {
|
export const generateSafelist = (colors: string[], globalColors: string[]) => {
|
||||||
|
@ -49,7 +49,7 @@ export const installTailwind = (
|
|||||||
resolve(runtimePath, 'components/**/*.{vue,mjs,ts}'),
|
resolve(runtimePath, 'components/**/*.{vue,mjs,ts}'),
|
||||||
)},
|
)},
|
||||||
${JSON.stringify(
|
${JSON.stringify(
|
||||||
resolve(runtimePath, 'themes/**/*.{mjs,js,ts}'),
|
resolve(runtimePath, 'ui.config/**/*.{mjs,js,ts}'),
|
||||||
)}
|
)}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user