Merge pull request #2 from Chank1e/chank1e/main

WIP: vite, vitepress, tailwind based on flowbite-react and flowbite-svelte
This commit is contained in:
Zoltán Szőgyényi
2022-07-01 00:23:59 +03:00
committed by GitHub
30 changed files with 3215 additions and 2 deletions

23
.eslintrc.js Normal file
View File

@@ -0,0 +1,23 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
parser: 'vue-eslint-parser',
extends: ['eslint:recommended', 'plugin:vue/essential', 'plugin:@typescript-eslint/recommended'],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '@typescript-eslint'],
rules: {
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'never'],
'vue/multi-word-component-names': 'off',
'comma-dangle': ['error', 'always-multiline'],
'no-multiple-empty-lines': 'error',
},
}

83
.gitignore vendored Normal file
View File

@@ -0,0 +1,83 @@
# Vite
node_modules
.DS_Store
dist
dist-ssr
*.local
# Rollup Bundle Visualizer
stats.html
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# vuepress build output
.vuepress/dist
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.idea

6
.prettierrc.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
trailingComma: 'es5',
semi: false,
singleQuote: true,
printWidth: 200,
}

73
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,73 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at {{ email }}. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org

42
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,42 @@
# Contributing guide
## What do I need to know to help?
If you are looking to help to with a code contribution our project uses Typescript, Vue 3 and TailwindCSS. If you don't feel ready to make a code contribution yet, no problem!
If you are interested in making a code contribution and would like to learn more about the technologies that we use, check out the list below.
- [React Course - Beginner's Tutorial for React JavaScript Library](https://www.youtube.com/watch?v=bMknfKXIFA8)
- [TypeScript Course](https://www.youtube.com/watch?v=BwuLxPH8IDs)
- [React + TypeScript](https://www.youtube.com/watch?v=jrKcJxF0lAU)
- [TailwindCSS](https://tailwindcss.com/)
## How do I make a contribution?
Never made an open source contribution before? Wondering how contributions work in the in our project? Here's a quick rundown!
1. [Find an issue](https://github.com/themesberg/flowbite-vue/issues) that you are interested in addressing or a feature that you would like to add.
2. Fork the repository associated with the issue to your local GitHub organization. This means that you will have a copy of the repository under `your-GitHub-username/repository-name`.
3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`.
4. Create a new branch for your fix using `git checkout -b branch-name-here`.
5. Make the appropriate changes for the issue you are trying to address or the feature that you want to add.
6. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index.
7. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message. Use [conventional commits](https://www.conventionalcommits.org/) to create a nice message.
8. Push the changes to the remote repository using `git push origin branch-name-here`.
9. Submit a pull request to the upstream repository.
10. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so `"Added more log outputting to resolve #4352"`.
11. In the description of the pull request, explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it!
12. Wait for the pull request to be reviewed by a maintainer.
13. Make changes to the pull request if the reviewing maintainer recommends them.
14. Celebrate your success after your pull request is merged! 🎉 🎉
## Where can I go for help?
If you need help, you can ask questions please, [join us at our Discord Community](https://discord.gg/S6J9pUmj2t).
## What does the Code of Conduct mean for me?
Our Code of Conduct means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code.
## Code of conduct
For more information [check this file](CODE_OF_CONDUCT.md).

View File

@@ -35,8 +35,8 @@
- [Documentation](#documentation) - [Documentation](#documentation)
- [Getting started](#getting-started) - [Getting started](#getting-started)
- [Require via `npm`](#require-via--npm-) - [Require via `npm`](#require-via--npm-)
- [Include via CDN](#include-via-cdn) - [Include via CDN](#include-via-cdn)
- [Components](#components) - [Components](#components)
- [Community](#community) - [Community](#community)
- [Contributing](#contributing) - [Contributing](#contributing)

33
docs/.vitepress/config.ts Normal file
View File

@@ -0,0 +1,33 @@
function buildSidebar() {
return [
{
items: [
{ text: 'Home', link: '/' }
],
},
{
text: 'Components',
collapsible: true,
items: [
...getComponents(),
],
}]
}
function getComponents() {
return [
{ text: 'Button', link: '/guide/button/button.md' },
]
}
/**
* This can be used as an example
* https://github.com/vuejs/vitepress/blob/master/docs/.vitepress/config.js
*/
export default {
title: 'flowbite-vue vitepress',
themeConfig: {
docsDir: 'docs',
sidebar: buildSidebar(),
},
}

View File

@@ -0,0 +1,7 @@
button,
input,
optgroup,
select,
textarea {
border: inherit; /* border: 0 by default in vitepress removes all border for border class */
}

View File

@@ -0,0 +1,7 @@
import './tailwind.css'
import DefaultTheme from 'vitepress/theme'
import './clear.css'
export default DefaultTheme

View File

@@ -0,0 +1,4 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

268
docs/guide/button/button.md Normal file
View File

@@ -0,0 +1,268 @@
<script setup>
import ButtonColorExample from './examples/ButtonColorExample.vue';
import ButtonSizeExample from './examples/ButtonSizeExample.vue';
import ButtonPillExample from './examples/ButtonPillExample.vue';
import ButtonGradientMonochromeExample from './examples/ButtonGradientMonochromeExample.vue';
import ButtonGradientDuotoneExample from './examples/ButtonGradientDuotoneExample.vue';
import ButtonOutlineColorExample from './examples/ButtonOutlineColorExample.vue';
import ButtonPrefixExample from './examples/ButtonPrefixExample.vue';
import ButtonSuffixExample from './examples/ButtonSuffixExample.vue';
import ButtonOutlineGradientExample from './examples/ButtonOutlineGradientExample.vue';
import ButtonGradientShadowExample from './examples/ButtonGradientShadowExample.vue';
</script>
# Button
reference: [https://flowbite.com/docs/components/buttons/](https://flowbite.com/docs/components/buttons/)
## Prop - color
```typescript
type ButtonVariant = 'default' | 'alternative' | 'dark' | 'light' | 'green' | 'red' | 'yellow' | 'purple'
defineProps({
color: {
type: String as PropType<ButtonVariant>,
default: 'default',
},
})
```
<ButtonColorExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button color="default">Default</Button>
<Button color="alternative">Alternative</Button>
<Button color="dark">Dark</Button>
<Button color="light">Light</Button>
<Button color="green">Green</Button>
<Button color="red">Red</Button>
<Button color="yellow">Yellow</Button>
<Button color="purple">Purple</Button>
</template>
```
## Prop - size
```typescript
type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
defineProps({
size: {
type: String as PropType<ButtonSize>,
default: 'md',
},
})
```
<ButtonSizeExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button size="xs">XS</Button>
<Button size="sm">SM</Button>
<Button size="md">MD</Button>
<Button size="lg">LG</Button>
<Button size="xl">XL</Button>
</template>
```
## Prop - pill
```typescript
defineProps({
pill: {
type: Boolean,
default: false,
},
})
```
<ButtonPillExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button color="default" pill>Default</Button>
<Button color="alternative" pill>Alternative</Button>
<Button color="dark" pill>Dark</Button>
<Button color="light" pill>Light</Button>
<Button color="green" pill>Green</Button>
<Button color="red" pill>Red</Button>
<Button color="yellow" pill>Yellow</Button>
<Button color="purple" pill>Purple</Button>
</template>
```
## Prop - gradient (monochrome)
```typescript
type ButtonMonochromeGradient = 'blue' | 'green' | 'cyan' | 'teal' | 'lime' | 'red' | 'pink' | 'purple'
type ButtonDuotoneGradient = 'purple-blue' | 'cyan-blue' | 'green-blue' | 'purple-pink' | 'pink-orange' | 'teal-lime' | 'red-yellow'
type ButtonGradient = ButtonDuotoneGradient | ButtonMonochromeGradient
defineProps({
gradient: {
type: [String, null] as PropType<ButtonGradient | null>,
default: null,
},
})
```
<ButtonGradientMonochromeExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="blue">Blue</Button>
<Button gradient="cyan">Cyan</Button>
<Button gradient="green">Green</Button>
<Button gradient="lime">Lime</Button>
<Button gradient="pink">Pink</Button>
<Button gradient="purple">Purple</Button>
<Button gradient="red">Red</Button>
<Button gradient="teal">Teal</Button>
</template>
```
## Prop - gradient (duotone)
<ButtonGradientDuotoneExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="purple-blue">Purple to blue</Button>
<Button gradient="cyan-blue">Cyan to blue</Button>
<Button gradient="green-blue">Green to blue</Button>
<Button gradient="purple-pink">Purple to pink</Button>
<Button gradient="pink-orange">Pink to orange</Button>
<Button gradient="teal-lime">Teal to lime</Button>
<Button gradient="red-yellow">Red to yellow</Button>
</template>
```
## Prop - outline (color)
```typescript
defineProps({
outline: {
type: Boolean,
default: false,
},
})
```
<ButtonOutlineColorExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="purple-blue">Purple to blue</Button>
<Button gradient="cyan-blue">Cyan to blue</Button>
<Button gradient="green-blue">Green to blue</Button>
<Button gradient="purple-pink">Purple to pink</Button>
<Button gradient="pink-orange">Pink to orange</Button>
<Button gradient="teal-lime">Teal to lime</Button>
<Button gradient="red-yellow">Red to yellow</Button>
</template>
```
## Prop - outline (gradient)
<ButtonOutlineGradientExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="purple-blue" outline>Purple to blue</Button>
<Button gradient="cyan-blue" outline>Cyan to blue</Button>
<Button gradient="green-blue" outline>Green to blue</Button>
<Button gradient="purple-pink" outline>Purple to pink</Button>
<Button gradient="pink-orange" outline>Pink to orange</Button>
<Button gradient="teal-lime" outline>Teal to lime</Button>
<Button gradient="red-yellow" outline>Red to yellow</Button>
</template>
```
## Prop - shadow
<ButtonGradientShadowExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="blue" shadow>Blue</Button>
<Button gradient="cyan" shadow>Cyan</Button>
<Button gradient="green" shadow>Green</Button>
<Button gradient="lime" shadow>Lime</Button>
<Button gradient="pink" shadow>Pink</Button>
<Button gradient="purple" shadow>Purple</Button>
<Button gradient="red" shadow>Red</Button>
<Button gradient="teal" shadow>Teal</Button>
</template>
```
## Slot - prefix
<ButtonPrefixExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button color="default">
<template #prefix>
<svg class="w-5 h-5 mr-2 -ml-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a1 1 0 000 2h1.22l.305 1.222a.997.997 0 00.01.042l1.358 5.43-.893.892C3.74 11.846 4.632 14 6.414 14H15a1 1 0 000-2H6.414l1-1H14a1 1 0 00.894-.553l3-6A1 1 0 0017 3H6.28l-.31-1.243A1 1 0 005 1H3zM16 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM6.5 18a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path></svg>
</template>
Buy
</Button>
</template>
```
## Slot - suffix
<ButtonSuffixExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button color="default">
Choose plan
<template #suffix>
<svg class="w-5 h-5 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</template>
</Button>
</template>
```

View File

@@ -0,0 +1,15 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button color="default">Default</Button>
<Button color="alternative">Alternative</Button>
<Button color="dark">Dark</Button>
<Button color="light">Light</Button>
<Button color="green">Green</Button>
<Button color="red">Red</Button>
<Button color="yellow">Yellow</Button>
<Button color="purple">Purple</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,14 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="purple-blue">Purple to blue</Button>
<Button gradient="cyan-blue">Cyan to blue</Button>
<Button gradient="green-blue">Green to blue</Button>
<Button gradient="purple-pink">Purple to pink</Button>
<Button gradient="pink-orange">Pink to orange</Button>
<Button gradient="teal-lime">Teal to lime</Button>
<Button gradient="red-yellow">Red to yellow</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,15 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="blue">Blue</Button>
<Button gradient="cyan">Cyan</Button>
<Button gradient="green">Green</Button>
<Button gradient="lime">Lime</Button>
<Button gradient="pink">Pink</Button>
<Button gradient="purple">Purple</Button>
<Button gradient="red">Red</Button>
<Button gradient="teal">Teal</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,18 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="blue" shadow>Blue with blue</Button>
<Button gradient="cyan" shadow>Cyan with cyan</Button>
<Button gradient="green" shadow>Green with green</Button>
<Button gradient="lime" shadow>Lime with lime</Button>
<Button gradient="pink" shadow>Pink with pink</Button>
<Button gradient="purple" shadow>Purple with purple</Button>
<Button gradient="red" shadow>Red with red</Button>
<Button gradient="teal" shadow>Teal with teal</Button>
<Button gradient="blue" shadow="red">Blue with red</Button>
<Button gradient="cyan" shadow="teal">Cyan with teal</Button>
<Button gradient="teal" shadow="purple">Teal with purple</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,13 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button color="default" outline>Default</Button>
<Button color="dark" outline>Dark</Button>
<Button color="green" outline>Green</Button>
<Button color="red" outline>Red</Button>
<Button color="yellow" outline>Yellow</Button>
<Button color="purple" outline>Purple</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,14 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="purple-blue" outline>Purple to blue</Button>
<Button gradient="cyan-blue" outline>Cyan to blue</Button>
<Button gradient="green-blue" outline>Green to blue</Button>
<Button gradient="purple-pink" outline>Purple to pink</Button>
<Button gradient="pink-orange" outline>Pink to orange</Button>
<Button gradient="teal-lime" outline>Teal to lime</Button>
<Button gradient="red-yellow" outline>Red to yellow</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,15 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button color="default" pill>Default</Button>
<Button color="alternative" pill>Alternative</Button>
<Button color="dark" pill>Dark</Button>
<Button color="light" pill>Light</Button>
<Button color="green" pill>Green</Button>
<Button color="red" pill>Red</Button>
<Button color="yellow" pill>Yellow</Button>
<Button color="purple" pill>Purple</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,13 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button color="default">
<template #prefix>
<svg class="w-5 h-5 mr-2 -ml-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a1 1 0 000 2h1.22l.305 1.222a.997.997 0 00.01.042l1.358 5.43-.893.892C3.74 11.846 4.632 14 6.414 14H15a1 1 0 000-2H6.414l1-1H14a1 1 0 00.894-.553l3-6A1 1 0 0017 3H6.28l-.31-1.243A1 1 0 005 1H3zM16 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM6.5 18a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path></svg>
</template>
Buy
</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,12 @@
<template>
<div class="inline-flex items-center gap-2 flex-wrap">
<Button size="xs">Extra small - xs</Button>
<Button size="sm">Small - sm</Button>
<Button size="md">Medium - md</Button>
<Button size="lg">Large - lg</Button>
<Button size="xl">Extra Large - xl</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,13 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button color="default">
Choose plan
<template #suffix>
<svg class="w-5 h-5 ml-2 -mr-1" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10.293 3.293a1 1 0 011.414 0l6 6a1 1 0 010 1.414l-6 6a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-4.293-4.293a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
</template>
</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

1
docs/index.md Normal file
View File

@@ -0,0 +1 @@
# Flowbite vue

2238
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

56
package.json Normal file
View File

@@ -0,0 +1,56 @@
{
"name": "flowbite-vue",
"version": "1.0.0",
"repository": "https://github.com/themesberg/flowbite-vue.git",
"author": "Ralph Schuler <ralph@inhaus.ai>",
"license": "MIT",
"files": [
"dist"
],
"main": "./dist/flowbite-vue.umd.js",
"module": "./dist/flowbite-vue.es.js",
"exports": {
".": {
"import": "./dist/flowbite-vue.es.js",
"require": "./dist/flowbite-vue.umd.js"
}
},
"scripts": {
"dev": "vitepress dev docs",
"serve": "vitepress serve docs",
"build:docs": "vitepress build docs",
"build": "vite build",
"build-types": "vue-tsc --declaration --emitDeclarationOnly",
"lint": "eslint --ext .ts,.vue --ignore-path .gitignore --fix src",
"format": "prettier . --write"
},
"peerDependencies": {
"vue": "^3.2.37"
},
"devDependencies": {
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"@vitejs/plugin-vue": "^2.3.3",
"@vue/compiler-sfc": "^3.2.37",
"@vue/tsconfig": "^0.1.3",
"class-names": "^1.0.0",
"eslint": "^8.18.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-vue": "^9.1.1",
"flowbite": "^1.4.2",
"postcss": "^8.4.6",
"prettier": "^2.3.2",
"tailwindcss": "^3.1.4",
"typescript": "^4.7.3",
"vite": "^2.4.3",
"vitepress": "^1.0.0-alpha.4",
"vue-eslint-parser": "^9.0.3",
"vue-tsc": "^0.38.2"
},
"postcss": {
"plugins": {
"tailwindcss": {}
}
}
}

View File

@@ -0,0 +1,172 @@
<template>
<button type="button" :class="bindClasses">
<slot name="prefix" />
<span :class="spanClasses">
<slot/>
</span>
<slot name="suffix" />
</button>
</template>
<script lang="ts" setup>
import {computed, useSlots} from 'vue'
import type { PropType } from 'vue'
import classNames from 'classnames'
export type ButtonMonochromeGradient = 'blue' | 'green' | 'cyan' | 'teal' | 'lime' | 'red' | 'pink' | 'purple'
export type ButtonDuotoneGradient = 'purple-blue' | 'cyan-blue' | 'green-blue' | 'purple-pink' | 'pink-orange' | 'teal-lime' | 'red-yellow'
export type ButtonGradient = ButtonDuotoneGradient | ButtonMonochromeGradient
export type ButtonVariant = 'default' | 'alternative' | 'dark' | 'light' | 'green' | 'red' | 'yellow' | 'purple'
export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
const props = defineProps({
color: {
type: String as PropType<ButtonVariant>,
default: 'default',
},
gradient: {
type: [String, null] as PropType<ButtonGradient | null>,
default: null,
},
size: {
type: String as PropType<ButtonSize>,
default: 'md',
},
pill: {
type: Boolean,
default: false,
},
outline: {
type: Boolean,
default: false,
},
shadow: {
type: [String, null] as PropType<ButtonMonochromeGradient | '' | null>,
default: null,
},
})
const slots = useSlots()
const bindClasses = computed(() => {
const isGradient = !!props.gradient
const isColor = !!props.color
const isOutline = props.outline
let backgroundClass = ''
if(isGradient && isOutline) {
if(['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.gradient)) { // invalid gradients for outline
backgroundClass = buttonGradientClasses[props.gradient]
} else {
backgroundClass = buttonOutlineGradientClasses[props.gradient as unknown as keyof typeof buttonOutlineGradientClasses]
}
} else if(isGradient) {
backgroundClass = buttonGradientClasses[props.gradient]
} else if(isColor && isOutline) {
if(['alternative', 'light'].includes(props.color)) { // invalid colors for outline
backgroundClass = buttonColorClasses[props.color]
} else {
backgroundClass = buttonOutlineColorClasses[props.color as unknown as keyof typeof buttonOutlineColorClasses]
}
} else {
backgroundClass = buttonColorClasses[props.color]
}
let shadowClass = ''
if(props.shadow === '') {
if(props.gradient && ['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.gradient)) {
shadowClass = buttonShadowClasses[props.gradient as unknown as keyof typeof buttonShadowClasses]
}
} else if(typeof props.shadow === 'string') {
if(['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.shadow)) {
shadowClass = buttonShadowClasses[props.shadow as unknown as keyof typeof buttonShadowClasses]
}
}
return classNames(
backgroundClass,
shadowClass,
(isGradient && isOutline) ? 'p-0.5' : buttonSizeClasses[props.size],
props.pill ? '!rounded-full' : '',
(slots.prefix || slots.suffix) ? 'inline-flex items-center' : '',
)
})
const spanClasses = computed(() => {
if(!!props.gradient && props.outline)
return classNames(
'relative transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0',
buttonSizeClasses[props.size],
)
return ''
})
const buttonColorClasses: Record<ButtonVariant, string> = {
default: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800',
alternative: 'font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700',
dark: 'text-white bg-gray-800 hover:bg-gray-900 focus:outline-none focus:ring-4 focus:ring-gray-300 font-medium rounded-lg dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700',
light: 'text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 font-medium rounded-lg dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700',
green: 'focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800',
red: 'focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900',
yellow: 'focus:outline-none text-white bg-yellow-400 hover:bg-yellow-500 focus:ring-4 focus:ring-yellow-300 font-medium rounded-lg dark:focus:ring-yellow-900',
purple: 'focus:outline-none text-white bg-purple-700 hover:bg-purple-800 focus:ring-4 focus:ring-purple-300 font-medium rounded-lg dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-900',
}
const buttonOutlineColorClasses: Record<Exclude<ButtonVariant, 'light' | 'alternative'>, string> = {
dark: 'text-gray-900 hover:text-white border border-gray-800 hover:bg-gray-900 focus:ring-4 focus:outline-none focus:ring-gray-300 font-medium rounded-lg text-sm text-center dark:border-gray-600 dark:text-gray-400 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-800',
default: 'text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm text-center dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-600 dark:focus:ring-blue-800',
green: 'text-green-700 hover:text-white border border-green-700 hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-green-300 font-medium rounded-lg text-sm text-center dark:border-green-500 dark:text-green-500 dark:hover:text-white dark:hover:bg-green-600 dark:focus:ring-green-800',
purple: 'text-purple-700 hover:text-white border border-purple-700 hover:bg-purple-800 focus:ring-4 focus:outline-none focus:ring-purple-300 font-medium rounded-lg text-sm text-center dark:border-purple-400 dark:text-purple-400 dark:hover:text-white dark:hover:bg-purple-500 dark:focus:ring-purple-900',
red: 'text-red-700 hover:text-white border border-red-700 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm text-center dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900',
yellow: 'text-yellow-400 hover:text-white border border-yellow-400 hover:bg-yellow-500 focus:ring-4 focus:outline-none focus:ring-yellow-300 font-medium rounded-lg text-sm text-center dark:border-yellow-300 dark:text-yellow-300 dark:hover:text-white dark:hover:bg-yellow-400 dark:focus:ring-yellow-900',
}
const buttonGradientClasses: Record<ButtonGradient, string> = {
'cyan-blue': 'text-white bg-gradient-to-r from-cyan-500 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg',
'green-blue': 'text-white bg-gradient-to-br from-green-400 to-blue-600 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-green-200 dark:focus:ring-green-800 font-medium rounded-lg',
'pink-orange': 'text-white bg-gradient-to-br from-pink-500 to-orange-400 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-pink-200 dark:focus:ring-pink-800 font-medium rounded-lg',
'purple-blue': 'text-white bg-gradient-to-br from-purple-600 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 font-medium rounded-lg',
'purple-pink': 'text-white bg-gradient-to-r from-purple-500 to-pink-500 hover:bg-gradient-to-l focus:ring-4 focus:outline-none focus:ring-purple-200 dark:focus:ring-purple-800 font-medium rounded-lg',
'red-yellow': 'text-gray-900 bg-gradient-to-r from-red-200 via-red-300 to-yellow-200 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-red-100 dark:focus:ring-red-400 font-medium rounded-lg',
'teal-lime': 'text-gray-900 bg-gradient-to-r from-teal-200 to-lime-200 hover:bg-gradient-to-l hover:from-teal-200 hover:to-lime-200 focus:ring-4 focus:outline-none focus:ring-lime-200 dark:focus:ring-teal-700 font-medium rounded-lg',
'blue': 'text-white bg-gradient-to-r from-blue-500 via-blue-600 to-blue-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800 rounded-lg',
'cyan': 'text-white bg-gradient-to-r from-cyan-500 via-cyan-600 to-cyan-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-cyan-300 dark:focus:ring-cyan-800 rounded-lg',
'green': 'text-white bg-gradient-to-r from-green-500 via-green-600 to-green-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-green-300 dark:focus:ring-green-800 rounded-lg',
'lime': 'text-gray-900 bg-gradient-to-r from-lime-500 via-lime-600 to-lime-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-lime-300 dark:focus:ring-lime-800 rounded-lg',
'pink': 'text-white bg-gradient-to-r from-pink-500 via-pink-600 to-pink-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-pink-300 dark:focus:ring-pink-800 rounded-lg',
'purple': 'text-white bg-gradient-to-r from-purple-500 via-purple-600 to-purple-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-purple-300 dark:focus:ring-purple-800 rounded-lg',
'red': 'text-white bg-gradient-to-r from-red-500 via-red-600 to-red-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 rounded-lg',
'teal': 'text-white bg-gradient-to-r from-teal-500 via-teal-600 to-teal-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-teal-300 dark:focus:ring-teal-800 rounded-lg',
}
const buttonOutlineGradientClasses: Record<ButtonDuotoneGradient, string> = {
'cyan-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-cyan-500 to-blue-500 group-hover:from-cyan-500 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-cyan-200 dark:focus:ring-cyan-800',
'green-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-green-400 to-blue-600 group-hover:from-green-400 group-hover:to-blue-600 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-green-200 dark:focus:ring-green-800',
'pink-orange': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-pink-500 to-orange-400 group-hover:from-pink-500 group-hover:to-orange-400 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-pink-200 dark:focus:ring-pink-800',
'purple-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800',
'purple-pink': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-500 to-pink-500 group-hover:from-purple-500 group-hover:to-pink-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-purple-200 dark:focus:ring-purple-800',
'red-yellow': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-red-200 via-red-300 to-yellow-200 group-hover:from-red-200 group-hover:via-red-300 group-hover:to-yellow-200 dark:text-white dark:hover:text-gray-900 focus:ring-4 focus:outline-none focus:ring-red-100 dark:focus:ring-red-400',
'teal-lime': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-teal-300 to-lime-300 group-hover:from-teal-300 group-hover:to-lime-300 dark:text-white dark:hover:text-gray-900 focus:ring-4 focus:outline-none focus:ring-lime-200 dark:focus:ring-lime-800',
}
const buttonSizeClasses: Record<ButtonSize, string> = {
xs: 'text-xs px-2 py-1',
sm: 'text-sm px-3 py-1.5',
md: 'text-sm px-4 py-2',
lg: 'text-base px-5 py-2.5',
xl: 'text-base px-6 py-3',
}
const buttonShadowClasses: Record<ButtonMonochromeGradient, string> = {
'blue': 'shadow-lg shadow-blue-500/50 dark:shadow-lg dark:shadow-blue-800/80',
'cyan': 'shadow-lg shadow-cyan-500/50 dark:shadow-lg dark:shadow-cyan-800/80',
'green': 'shadow-lg shadow-green-500/50 dark:shadow-lg dark:shadow-green-800/80',
'lime': 'shadow-lg shadow-lime-500/50 dark:shadow-lg dark:shadow-lime-800/80',
'pink': 'shadow-lg shadow-pink-500/50 dark:shadow-lg dark:shadow-pink-800/80',
'purple': 'shadow-lg shadow-purple-500/50 dark:shadow-lg dark:shadow-purple-800/80',
'red': 'shadow-lg shadow-red-500/50 dark:shadow-lg dark:shadow-red-800/80',
'teal': 'shadow-lg shadow-teal-500/50 dark:shadow-lg dark:shadow-teal-800/80',
}
</script>

8
src/env.d.ts vendored Normal file
View File

@@ -0,0 +1,8 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

1
src/index.ts Normal file
View File

@@ -0,0 +1 @@
export { default as Button } from './components/Button/Button.vue'

5
tailwind.config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
content: ['./docs/.vitepress/**/*.{js,ts,vue}', './docs/**/*.{js,ts,vue,md}', './src/**/*.{js,ts,vue}'],
plugins: [require('flowbite/plugin')],
theme: {},
}

13
tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"exclude": [
"node_modules",
"**/node_modules"
]
}

31
vite.config.ts Normal file
View File

@@ -0,0 +1,31 @@
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, 'src'),
},
},
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'flowbite-vue',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
},
},
},
},
})