├── .github └── workflows │ └── docs.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── components.d.ts ├── index.html ├── package.json ├── postcss.config.cjs ├── src │ ├── @types │ │ ├── global.d.ts │ │ └── vue.d.ts │ ├── README.md │ ├── app.vue │ ├── assets │ │ └── photo.jpg │ ├── components │ │ ├── app │ │ │ └── app-menu.vue │ │ ├── markdown-table.vue │ │ └── playground.vue │ ├── main.ts │ ├── pages │ │ ├── components │ │ │ ├── alert.md │ │ │ ├── artboard.md │ │ │ ├── avatar.md │ │ │ ├── badge.md │ │ │ ├── breadcrumb.md │ │ │ ├── button.md │ │ │ ├── card.md │ │ │ ├── checkbox.md │ │ │ ├── counter.md │ │ │ ├── divider.md │ │ │ ├── drawer.md │ │ │ ├── dropdown.md │ │ │ ├── icons.md │ │ │ ├── indicator.md │ │ │ ├── input.md │ │ │ ├── join.md │ │ │ ├── kbd.md │ │ │ ├── link.md │ │ │ ├── loading.md │ │ │ ├── mask.md │ │ │ ├── menu.md │ │ │ ├── modal.md │ │ │ ├── navbar.md │ │ │ ├── pagination.md │ │ │ ├── popper.md │ │ │ ├── progress.md │ │ │ ├── radio.md │ │ │ ├── raw.md │ │ │ ├── space.md │ │ │ ├── swap.md │ │ │ ├── tab.md │ │ │ ├── table.md │ │ │ ├── textarea.md │ │ │ ├── toggle.md │ │ │ └── tooltip.md │ │ ├── demo.md │ │ └── index.vue │ ├── styles │ │ ├── global.less │ │ ├── index.ts │ │ ├── markdown.less │ │ └── tailwind.css │ └── utils │ │ └── index.ts ├── tailwind.config.cjs ├── tsconfig.json └── vite.config.ts ├── jest.config.js ├── package.json ├── packages ├── daisyui-style-ext │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json └── develop │ ├── __tests__ │ ├── classname-plugin.test.ts │ └── fixtures │ │ └── classname-plugin.js │ ├── cli.js │ ├── index.js │ ├── package.json │ ├── src │ ├── build │ │ ├── classname-plugin.ts │ │ ├── rollup-styles-plugin.ts │ │ ├── rollup.ts │ │ └── ts-declaration-transformer.ts │ ├── cli.ts │ ├── index.ts │ └── init │ │ ├── index.ts │ │ └── parse-css-theme.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── postcss.config.js ├── rollup.config.js ├── scripts └── buildIcons.js ├── src ├── @types │ ├── dom.ts │ ├── ext.d.ts │ └── global.d.ts ├── components │ ├── _styles │ │ ├── animate.less │ │ ├── common │ │ │ └── checkbox-radio.less │ │ ├── daisyui-utilities-global │ │ │ ├── glass.css │ │ │ └── variables.css │ │ └── global.ts │ ├── _widgets │ │ ├── raw.tsx │ │ ├── style │ │ │ └── raw.less │ │ └── theme.tsx │ ├── alert │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ └── style.less │ ├── artboard │ │ ├── artboard.tsx │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── avatar │ │ ├── avatar-group.tsx │ │ ├── avatar.tsx │ │ ├── index.tsx │ │ ├── state.ts │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-s.css │ ├── badge │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-us.css │ ├── breadcrumb │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ └── style.less │ ├── button │ │ ├── button-group.tsx │ │ ├── button.tsx │ │ ├── index.tsx │ │ ├── state.ts │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── card │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── checkbox │ │ ├── checkbox.tsx │ │ ├── group.tsx │ │ ├── index.ts │ │ ├── state.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-us.css │ ├── counter │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── divider │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── drawer │ │ ├── drawer.tsx │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── dropdown │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── icon │ │ ├── icon.tsx │ │ ├── icons.tsx │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── index.tsx │ ├── indicator │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-us.css │ ├── input │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ └── u-us.css │ ├── join │ │ ├── index.tsx │ │ └── styles │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── kbd │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ └── u-us.css │ ├── link │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ └── index.ts │ ├── loading │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ └── index.ts │ ├── mask │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ └── index.tsx │ ├── menu │ │ ├── index.tsx │ │ ├── menu-item.tsx │ │ ├── menu.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ ├── u-s.css │ │ │ └── u-us.css │ ├── modal │ │ ├── base.tsx │ │ ├── index.tsx │ │ ├── style │ │ │ ├── base.less │ │ │ └── widgets.less │ │ └── widgets.tsx │ ├── navbar │ │ ├── index.ts │ │ ├── navbar.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ └── index.ts │ ├── pagination │ │ └── index.tsx │ ├── popper │ │ ├── index.tsx │ │ └── style │ │ │ └── index.less │ ├── progress │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── radial-progress-c-s.css │ │ │ └── radial-progress-c-us.css │ ├── radio │ │ ├── group.tsx │ │ ├── index.tsx │ │ ├── radio.tsx │ │ ├── state.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-us.css │ ├── space │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── swap │ │ ├── index.tsx │ │ └── style │ │ │ ├── index.ts │ │ │ └── style.less │ ├── tab │ │ ├── index.tsx │ │ ├── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-us.css │ │ └── tabs.tsx │ ├── table │ │ ├── index.tsx │ │ ├── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ ├── style.less │ │ │ └── u-s.css │ │ └── table.tsx │ ├── textarea │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ └── index.ts │ ├── toggle │ │ ├── index.tsx │ │ └── style │ │ │ ├── c-s.css │ │ │ ├── c-us.css │ │ │ ├── index.ts │ │ │ └── u-us.css │ └── tooltip │ │ ├── index.tsx │ │ ├── style │ │ ├── index.ts │ │ └── style.less │ │ └── tooltip.tsx ├── index.tsx ├── install.ts └── shared │ ├── animation-timer.ts │ ├── constants │ ├── base-props.ts │ └── index.ts │ ├── ctx.ts │ ├── hooks │ ├── index.ts │ ├── use-active-change.ts │ ├── use-async.ts │ ├── use-break-point.ts │ ├── use-checkbox.ts │ └── use-event-listener.ts │ ├── style-manager.ts │ ├── styled.ts │ ├── theme │ ├── define.ts │ ├── internal.ts │ └── themes.ts │ ├── types │ ├── common.ts │ ├── components.tsx │ ├── theme.ts │ └── utils.ts │ └── utils.ts ├── tailwind.config.js └── tsconfig.json /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [master] 9 | pull_request: 10 | branches: [master] 11 | workflow_dispatch: 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | # node-version: [12.x, 14.x, 16.x] 20 | node-version: [18.x] 21 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 22 | 23 | steps: 24 | - uses: actions/checkout@v2 25 | 26 | - name: Install pnpm 27 | uses: pnpm/action-setup@v2 28 | with: 29 | version: 6.19.1 30 | 31 | - name: Use Node.js ${{ matrix.node-version }} 32 | uses: actions/setup-node@v2 33 | with: 34 | node-version: ${{ matrix.node-version }} 35 | cache: 'pnpm' 36 | 37 | - run: pnpm i 38 | - run: pnpm build --filter @dv/develop 39 | - run: pnpm run dvinit 40 | - run: pnpm run build 41 | - run: pnpm run build --filter docs 42 | 43 | - name: GitHub Pages action 44 | uses: peaceiris/actions-gh-pages@v3.7.3 45 | with: 46 | github_token: ${{ secrets.ACCESS_TOKEN }} 47 | publish_dir: docs/dist 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | ### Node ### 3 | # Logs 4 | logs 5 | *-debug.log* 6 | *-debug.log* 7 | *-error.log* 8 | 9 | # Custom 10 | node_modules/ 11 | \.DS_Store 12 | src/_daisyui 13 | src/icons/vue 14 | 15 | dist 16 | es 17 | lib 18 | **/.yarn/install-state.gz 19 | **/.yarn/cache 20 | 21 | docs/src/.demo 22 | .vite-ssg-temp 23 | out/ 24 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmmirror.com 2 | # 将所有模块放在最顶层,解决组件库打包时报错 vue 中导出的 App、computed 不存在的问题 3 | # shamefully-hoist=true 4 | 5 | # 全部提升过于暴力,只提升 vue 相关的到顶层 6 | public-hoist-pattern[]=*vue* 7 | public-hoist-pattern[]=*popperjs* 8 | public-hoist-pattern[]=rollup 9 | public-hoist-pattern[]=daisyui 10 | public-hoist-pattern[]=tslib 11 | public-hoist-pattern[]=typescript 12 | 13 | auto-install-peers=true 14 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *-lock.yaml 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "htmlWhitespaceSensitivity": "strict" 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true, 3 | "html.format.enable": true, 4 | // https://github.com/ben-rogerson/twin.macro/discussions/227 5 | "tailwindCSS.experimental.classRegex": [ 6 | "tw`([^`]*)", // tw`...` 7 | "tw=\"([^\"]*)", //
8 | "tw={\"([^\"}]*)", //
9 | "tw\\.\\w+`([^`]*)", // tw.xxx`...` 10 | "tw\\(.*?\\)`([^`]*)" // tw(Component)`...` 11 | ], 12 | "less.lint.unknownAtRules": "ignore" 13 | } 14 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Daisyui Vue 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite-ssg build", 8 | "serve": "vite preview" 9 | }, 10 | "dependencies": { 11 | "@unhead/vue": "^1.1.27", 12 | "@vueuse/head": "^1.1.26", 13 | "@vicons/fluent": "^0.12.0", 14 | "vue": "3.2.26" 15 | }, 16 | "devDependencies": { 17 | "@types/fs-extra": "^9.0.13", 18 | "@types/markdown-it": "^12.2.3", 19 | "@vitejs/plugin-vue": "^4.2.3", 20 | "@vitejs/plugin-vue-jsx": "^3.0.1", 21 | "@vue/compiler-sfc": "3.2.26", 22 | "@vue/server-renderer": "3.2.26", 23 | "autoprefixer": "^10.3.6", 24 | "cross-env": "^7.0.3", 25 | "fs-extra": "^10.0.1", 26 | "highlight.js": "^11.2.0", 27 | "html-escaper": "^3.0.3", 28 | "postcss": "^8.4.0", 29 | "tailwindcss": "^3.3.2", 30 | "unplugin-vue-components": "^0.25.1", 31 | "vite": "^4.3.9", 32 | "vite-plugin-md": "^0.21.5", 33 | "vite-plugin-pages": "^0.31.0", 34 | "vite-plugin-pwa": "^0.16.4", 35 | "vite-plugin-vue-markdown": "^0.23.5", 36 | "vite-ssg": "^0.22.2", 37 | "vue-router": "^4.0.14" 38 | }, 39 | "engines": { 40 | "node": ">=18.0.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | // postcss.config.js 2 | module.exports = { 3 | plugins: { 4 | tailwindcss: {}, 5 | autoprefixer: {}, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /docs/src/@types/global.d.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daief/daisyui-vue/8150491449dc47467bf1dad98c9789e29dd5f127/docs/src/@types/global.d.ts -------------------------------------------------------------------------------- /docs/src/@types/vue.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import { defineComponent } from 'vue'; 5 | const Component: ReturnType; 6 | export default Component; 7 | } 8 | 9 | declare module '*.md' { 10 | import { defineComponent } from 'vue'; 11 | const Component: ReturnType; 12 | export default Component; 13 | } 14 | -------------------------------------------------------------------------------- /docs/src/README.md: -------------------------------------------------------------------------------- 1 | # document for daisyui-vue 2 | 3 | Markdown 书写规则: 4 | 5 | - `:::demo` 将代码块标记为可执行的 demo,作用域为当前 Markdown,仅支持 `html` 语言 6 | - `:::run` 将代码块标记为独立文件,代码块内容会被抽取成单个文件后执行,支持 `html`、`tsx` 语言 7 | -------------------------------------------------------------------------------- /docs/src/assets/photo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daief/daisyui-vue/8150491449dc47467bf1dad98c9789e29dd5f127/docs/src/assets/photo.jpg -------------------------------------------------------------------------------- /docs/src/components/app/app-menu.vue: -------------------------------------------------------------------------------- 1 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/src/components/markdown-table.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 31 | -------------------------------------------------------------------------------- /docs/src/main.ts: -------------------------------------------------------------------------------- 1 | import { ViteSSG } from 'vite-ssg'; 2 | import routes from 'virtual:generated-pages'; 3 | import daisyui, { 4 | STYLE_MANAGER_CONTEXT_SYMBOL, 5 | StyleManager, 6 | IconHeart, 7 | IconEllipsisHorizontal, 8 | IconClose, 9 | IconFolderOpenOutline, 10 | IconDocumentOutline, 11 | IconMenu, 12 | IconCode, 13 | IconLogoGithub, 14 | IconVolumeMute, 15 | IconVolumeHigh, 16 | IconSunny, 17 | IconMoon, 18 | IconColorPalette, 19 | } from 'daisyui-vue'; 20 | import './styles'; 21 | import App from './app.vue'; 22 | import Playground from './components/playground.vue'; 23 | import MarkdownTable from './components/markdown-table.vue'; 24 | 25 | const icons = [ 26 | IconHeart, 27 | IconEllipsisHorizontal, 28 | IconClose, 29 | IconFolderOpenOutline, 30 | IconDocumentOutline, 31 | IconMenu, 32 | IconCode, 33 | IconLogoGithub, 34 | IconVolumeMute, 35 | IconVolumeHigh, 36 | IconSunny, 37 | IconMoon, 38 | IconColorPalette, 39 | ]; 40 | 41 | export const createApp = ViteSSG( 42 | App, 43 | { 44 | routes, 45 | base: '/daisyui-vue/', 46 | }, 47 | (ctx) => { 48 | const { app, router, isClient } = ctx; 49 | if (!isClient) { 50 | const styleManager = new StyleManager(); 51 | app.provide(STYLE_MANAGER_CONTEXT_SYMBOL, styleManager); 52 | app.config.globalProperties.$styleManager = styleManager; 53 | } 54 | 55 | // install plugins etc. 56 | app.component('Playground', Playground); 57 | app.component('MarkdownTable', MarkdownTable); 58 | app.use(daisyui); 59 | 60 | icons.forEach((i) => app.component(i.name, i)); 61 | 62 | router.isReady().then(() => { 63 | router.afterEach((to, from, fa) => { 64 | if (!isClient) return; 65 | if (to.path !== from.path) { 66 | try { 67 | (window as any).gtag.trackPath(''); 68 | } catch (error) {} 69 | } 70 | }); 71 | }); 72 | }, 73 | ); 74 | -------------------------------------------------------------------------------- /docs/src/pages/components/alert.md: -------------------------------------------------------------------------------- 1 | # Alert 2 | 3 | ## Examples 4 | 5 | alert 6 | 7 | ```html :::demo 8 | 9 | Lorem ipsum dolor sit amet, consectetur adip! 10 | 11 | ``` 12 | 13 | alert state: info 14 | 15 | ```html :::demo 16 | Lorem ipsum dolor sit amet, consectetur adip! 17 | ``` 18 | 19 | alert state: success 20 | 21 | ```html :::demo 22 | 23 | Lorem ipsum dolor sit amet, consectetur adip! 24 | 25 | ``` 26 | 27 | alert state: warning 28 | 29 | ```html :::demo 30 | 31 | Lorem ipsum dolor sit amet, consectetur adip! 32 | 33 | ``` 34 | 35 | alert state: error 36 | 37 | ```html :::demo 38 | 39 | Lorem ipsum dolor sit amet, consectetur adip! 40 | 41 | ``` 42 | 43 | alert with actions 44 | 45 | ```html :::demo 46 | 47 | 50 | 54 | 55 | ``` 56 | 57 | alert 58 | 59 | ```html :::demo 60 | 61 | 64 | 67 | 73 | 78 | 79 | ``` 80 | 81 | ## Alert 82 | 83 | ### Attributes 84 | 85 | | name | description | type | default | 86 | | ---- | ---------------- | ----------------------------- | ------- | 87 | | type | alert color type | info, success, warning, error | - | 88 | 89 | ### Slots 90 | 91 | | name | description | 92 | | ------- | ------------- | 93 | | default | alert title | 94 | | content | alert content | 95 | | actions | alert actions | 96 | -------------------------------------------------------------------------------- /docs/src/pages/components/artboard.md: -------------------------------------------------------------------------------- 1 | # Artboard 2 | 3 | Used to display some content. 4 | 5 | ## Examples 6 | 7 | artboard - phone 8 | 9 | ```html :::demo 10 |
11 | 12 | phone(custom height) 13 | 14 | phone-1 15 | phone-2 16 | phone-3 17 | phone-4 18 | phone-5 19 | phone-6 20 |
21 | ``` 22 | 23 | artboard - phone horizontal 24 | 25 | ```html :::demo 26 |
27 | phone-1 28 | phone-2 29 | phone-3 30 | phone-4 31 | phone-5 32 | phone-6 33 |
34 | ``` 35 | 36 | ## Artboard 37 | 38 | ### Attributes 39 | 40 | | name | description | type | default | 41 | | ---------- | --------------------- | ------------------------- | ------- | 42 | | phone | demo size | boolean, 1, 2, 3, 4, 5, 6 | false | 43 | | horizontal | shows horizontal view | boolean | false | 44 | -------------------------------------------------------------------------------- /docs/src/pages/components/breadcrumb.md: -------------------------------------------------------------------------------- 1 | # Breadcrumb 2 | 3 | ## Examples 4 | 5 | breadcrumbs 6 | 7 | ```html :::demo 8 | 9 | Home 10 | Documents 11 | Add Document 12 | 13 | ``` 14 | 15 | breadcrumbs with icon 16 | 17 | ```html :::demo 18 | 19 | 20 | 21 | Home 22 | 23 | 24 | 25 | Documents 26 | 27 | 28 | 29 | Add Document 30 | 31 | 32 | ``` 33 | 34 | breadcrumbs overflow scroll 35 | 36 | ```html :::demo 37 | 38 | If you set max-width 39 | or the list 40 | gets larger than 41 | the container 42 | it will scroll 43 | 44 | ``` 45 | 46 | ## Breadcrumb 47 | 48 | `-` 49 | 50 | ## BreadcrumbItem 51 | 52 | `-` 53 | -------------------------------------------------------------------------------- /docs/src/pages/components/counter.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | ## Examples 4 | 5 | Counter 6 | 7 | ```html :::demo 8 |
9 | 10 |
11 | ``` 12 | 13 | Large text 14 | 15 | ```html :::demo 16 |
17 | 24 |
25 | ``` 26 | 27 | Increase 28 | 29 | ```html :::demo 30 |
31 | 32 |
33 | ``` 34 | 35 | ## Counter 36 | 37 | ### Attributes 38 | 39 | | name | description | type | default | 40 | | ------------------ | ----------------------- | ----------------- | ------- | 41 | | from | start value | number | - | 42 | | to | end value | number | - | 43 | | duration | duration | number | - | 44 | | format | control how to display | (value) => string | - | 45 | | transitionDuration | css transition duration | number | 0 | 46 | -------------------------------------------------------------------------------- /docs/src/pages/components/divider.md: -------------------------------------------------------------------------------- 1 | # Divider 2 | 3 | ## Examples 4 | 5 | divider 6 | 7 | ```html :::demo 8 |
9 |
10 | content 11 |
12 | OR 13 |
14 | content 15 |
16 |
17 | ``` 18 | 19 | divider horizontal 20 | 21 | ```html :::demo 22 |
23 |
26 | content 27 |
28 | OR 29 |
32 | content 33 |
34 |
35 | ``` 36 | 37 | divider with no text 38 | 39 | ```html :::demo 40 |
41 |
42 | content 43 |
44 | 45 |
46 | content 47 |
48 |
49 | ``` 50 | 51 | divider with no text 52 | 53 | ```html :::demo 54 |
55 |
58 | content 59 |
60 | 61 |
64 | content 65 |
66 |
67 | ``` 68 | 69 | ## Divider 70 | 71 | ### Attributes 72 | 73 | | name | description | type | default | 74 | | ---------- | ---------------------------------- | ------- | ------- | 75 | | horizontal | Divide elements next to each other | boolean | false | 76 | -------------------------------------------------------------------------------- /docs/src/pages/components/icons.md: -------------------------------------------------------------------------------- 1 | # Icons 2 | 3 | Icons of this library are based on [xicons](https://github.com/07akioni/xicons) [ionicons5](https://www.xicons.org). 4 | 5 | ```html :::run 6 | 15 | 16 | 25 | ``` 26 | 27 | `xicons` is also recommended for more icons. 28 | 29 | ```html :::run 30 | 40 | 41 | 50 | ``` 51 | 52 | ## Icon 53 | 54 | ### Attributes 55 | 56 | | name | description | type | default | 57 | | ----- | ------------ | -------------- | ------- | 58 | | color | icon color | string | - | 59 | | size | icon size | number, string | - | 60 | | tag | wrap element | string | span | 61 | 62 | ### Slots 63 | 64 | | name | description | 65 | | ------- | ------------ | 66 | | default | svg children | 67 | -------------------------------------------------------------------------------- /docs/src/pages/components/join.md: -------------------------------------------------------------------------------- 1 | 2 | meta: 3 | category: layout 4 | 5 | 6 | # Join 7 | 8 | Join is a container for grouping multiple items, it can be used to group buttons, inputs, or any other element. Join applies border radius to the first and last item. Join can be used to create a horizontal or vertical list of items. 9 | 10 | ## Examples 11 | 12 | Join 13 | 14 | ```html :::demo 15 | 16 | button 17 | button 18 | button 19 | 20 | ``` 21 | 22 | Group items vertically 23 | 24 | ```html :::demo 25 | 26 | button 27 | button 28 | button 29 | 30 | ``` 31 | 32 | With extra elements in the group 33 | 34 | ```html :::demo 35 | 36 | 37 | search 38 | 39 | ``` 40 | 41 | ## Join 42 | 43 | ### Attributes 44 | 45 | | name | description | type | default | 46 | | -------- | --------------------- | ------- | ------- | 47 | | vertical | show items vertically | boolean | - | 48 | -------------------------------------------------------------------------------- /docs/src/pages/components/kbd.md: -------------------------------------------------------------------------------- 1 | # Kbd 2 | 3 | Kbd is used to display keyboard shortcuts. 4 | 5 | ## Examples 6 | 7 | Kbd 8 | 9 | ```html :::demo 10 | A 11 | ``` 12 | 13 | Kbd sizes 14 | 15 | ```html :::demo 16 |
17 | Shift 18 | Shift 19 | Shift 20 | Shift 21 |
22 | ``` 23 | 24 | In text 25 | 26 | ```html :::demo 27 |

Press F to pay respects.

28 | ``` 29 | 30 | Key combination 31 | 32 | ```html :::demo 33 |

34 | ctrl 35 | + 36 | shift 37 | + 38 | del 39 |

40 | ``` 41 | 42 | Function Keys 43 | 44 | ```html :::demo 45 |
46 | 47 | 48 | 49 | 50 |
51 | ``` 52 | 53 | A full keyboard 54 | 55 | ```html :::demo 56 |
57 | q 58 | w 59 | e 60 | r 61 | t 62 | y 63 | u 64 | i 65 | o 66 | p 67 |
68 |
69 | a 70 | s 71 | d 72 | f 73 | g 74 | h 75 | j 76 | k 77 | l 78 |
79 |
80 | z 81 | x 82 | c 83 | v 84 | b 85 | n 86 | m 87 | / 88 |
89 | ``` 90 | 91 | ## Kbd 92 | 93 | ### Attributes 94 | 95 | | name | description | type | default | 96 | | ---- | ----------- | ----- | ------- | 97 | | size | size | ISize | md | 98 | -------------------------------------------------------------------------------- /docs/src/pages/components/link.md: -------------------------------------------------------------------------------- 1 | # Link 2 | 3 | ## Examples 4 | 5 | Link 6 | 7 | ```html :::demo 8 |
9 | I'm a simple link 10 |
11 | ``` 12 | 13 | Link 14 | 15 | ```html :::demo 16 |
17 |

18 | Tailwind CSS resets the style of links by default. 19 |
20 | Add "link" class to make it look like a 21 | normal link again. 22 |

23 |
24 | ``` 25 | 26 | Link type color 27 | 28 | ```html :::demo 29 |
30 | neutral color 31 | primary color 32 | secondary color 33 | accent color 34 |
35 | ``` 36 | 37 | Show underline only on hover 38 | 39 | ```html :::demo 40 |
41 | I'm a simple link 42 |
43 | ``` 44 | 45 | ## Link 46 | 47 | ### Attributes 48 | 49 | | name | description | type | default | 50 | | ---------------- | ---------------------------- | ----------------------------------- | ------- | 51 | | variant | link color type | neutral, primary, secondary, accent | neutral | 52 | | enableHoverClass | show underline only on hover | boolean | false | 53 | -------------------------------------------------------------------------------- /docs/src/pages/components/mask.md: -------------------------------------------------------------------------------- 1 | # Mask 2 | 3 | ## Examples 4 | 5 | mask 6 | 7 | ```tsx :::run 8 | export default { 9 | setup: () => { 10 | const types = [ 11 | 'squircle', 12 | 'heart', 13 | 'hexagon', 14 | 'hexagon-2', 15 | 'decagon', 16 | 'pentagon', 17 | 'diamond', 18 | 'square', 19 | 'circle', 20 | 'parallelogram', 21 | 'parallelogram-2', 22 | 'parallelogram-3', 23 | 'parallelogram-4', 24 | 'star', 25 | 'star-2', 26 | 'triangle', 27 | 'triangle-2', 28 | 'triangle-3', 29 | 'triangle-4', 30 | ]; 31 | return () => ( 32 |
33 | {types.map((type) => ( 34 |
35 |

mask-{type}

36 | 37 | 38 | 39 |
40 | ))} 41 |
42 | ); 43 | }, 44 | }; 45 | ``` 46 | 47 | ## Mask 48 | 49 | ### Attributes 50 | 51 | | name | description | type | default | 52 | | ---- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | 53 | | type | the shape type of content | squircle, heart, hexagon, hexagon-2, decagon, pentagon, diamond, square, circle, parallelogram, parallelogram-2, parallelogram-3, parallelogram-4, star, star-2, triangle, triangle-2, triangle-3, triangle-4 | squircle | 54 | -------------------------------------------------------------------------------- /docs/src/pages/components/navbar.md: -------------------------------------------------------------------------------- 1 | # Navbar 2 | 3 | ## Examples 4 | 5 | Navbar 6 | 7 | ```html :::demo 8 |
9 | 10 | daisyui vue 11 | 12 |
13 | ``` 14 | 15 | Navbar with icons 16 | 17 | ```html :::demo 18 |
19 | 20 | 21 | daisyui vue 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | ``` 31 | 32 | Navbar with icon at start and end 33 | 34 | ```html :::demo 35 |
36 | 37 | 38 | 39 | daisyui vue 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 |
48 | ``` 49 | 50 | ## Navbar 51 | 52 | ### Attributes 53 | 54 | | name | description | type | default | 55 | | ---- | ----------- | ---- | ------- | 56 | 57 | ## NavbarStart 58 | 59 | ### Attributes 60 | 61 | | name | description | type | default | 62 | | ---- | ----------- | ---- | ------- | 63 | 64 | ## NavbarCenter 65 | 66 | ### Attributes 67 | 68 | | name | description | type | default | 69 | | ---- | ----------- | ---- | ------- | 70 | 71 | ## NavbarEnd 72 | 73 | ### Attributes 74 | 75 | | name | description | type | default | 76 | | ---- | ----------- | ---- | ------- | 77 | -------------------------------------------------------------------------------- /docs/src/pages/components/pagination.md: -------------------------------------------------------------------------------- 1 | # Pagination 2 | 3 | ## Examples 4 | 5 | Pagination 6 | 7 | ```html :::demo 8 |
9 | 10 | 11 | 12 | 13 |
14 | ``` 15 | 16 | Sizes 17 | 18 | ```html :::demo 19 |
20 | 21 | 22 | 23 | 24 |
25 | ``` 26 | 27 | Outline 28 | 29 | ```html :::demo 30 | 31 | ``` 32 | 33 | ## Pagination 34 | 35 | ### Attributes 36 | 37 | | name | description | type | default | 38 | | ---------- | -------------------- | ------ | ------- | 39 | | modelValue | current page v-model | number | - | 40 | | total | total page | number | 0 | 41 | -------------------------------------------------------------------------------- /docs/src/pages/components/raw.md: -------------------------------------------------------------------------------- 1 | # Raw 2 | 3 | ## Examples 4 | 5 | background type 6 | 7 | ```html :::demo 8 |
9 | div 10 | neutral 11 | parimary 12 | secondary 13 | accent 14 | info 15 | success 16 | warning 17 | error 18 | base-100 19 | base-200 20 | base-300 21 |
22 | ``` 23 | 24 | text color 25 | 26 | ```html :::demo 27 |
28 | primary 29 | info 30 | base-content 31 | 32 | color name 33 | #6cf 34 | rgb(218 137 33) 35 |
36 | ``` 37 | 38 | html tag 39 | 40 | ```html :::demo 41 |
42 | span 43 | button 44 |
45 | ``` 46 | 47 | ## Raw 48 | 49 | ### Attributes 50 | 51 | | name | description | type | default | 52 | | ------- | ----------- | ------------- | ------- | 53 | | tag | html tag | string | div | 54 | | variant | theme type | IRawType | - | 55 | | color | text color | IColor,string | - | 56 | -------------------------------------------------------------------------------- /docs/src/pages/components/swap.md: -------------------------------------------------------------------------------- 1 | # Swap 2 | 3 | ## Examples 4 | 5 | Swap text 6 | 7 | ```html :::demo 8 | 9 | ``` 10 | 11 | Swap volume icons 12 | 13 | ```tsx :::run 14 | export default { 15 | setup: () => { 16 | return () => ( 17 | } 19 | off={() => } 20 | /> 21 | ); 22 | }, 23 | }; 24 | ``` 25 | 26 | Swap icons with rotate effect 27 | 28 | ```html :::demo 29 | 30 | 33 | 36 | 37 | ``` 38 | 39 | Swap with flip effect 40 | 41 | ```tsx :::run 42 | export default { 43 | setup: () => { 44 | return () => ( 45 |
46 | 47 |
48 | ); 49 | }, 50 | }; 51 | ``` 52 | 53 | Controlled swap 54 | 55 | ```tsx :::run 56 | import { ref } from 'vue'; 57 | 58 | export default { 59 | setup: () => { 60 | const active = ref(false); 61 | return () => ( 62 |
63 |
64 | (active.value = true)}>on 65 |  /  66 | (active.value = false)}>off 67 |
68 |
69 | 70 |
71 |
72 | ); 73 | }, 74 | }; 75 | ``` 76 | 77 | ## Swap 78 | 79 | ### Attributes 80 | 81 | | name | description | type | default | 82 | | --------- | ------------------------------- | ------------ | ------- | 83 | | on | render on | - | - | 84 | | off | render off | - | - | 85 | | tag | wrap elemnt tag | string | label | 86 | | animation | animation effect | rotate, flip | - | 87 | | active | swap active status | boolean | - | 88 | | onChange | swap active status change event | Function | - | 89 | 90 | ### Solts 91 | 92 | | name | description | 93 | | ---- | ----------- | 94 | | on | render on | 95 | | off | render off | 96 | -------------------------------------------------------------------------------- /docs/src/pages/components/textarea.md: -------------------------------------------------------------------------------- 1 | # Textarea 2 | 3 | ## Examples 4 | 5 | Textarea 6 | 7 | ```html :::demo 8 |
9 | 10 |
11 | ``` 12 | 13 | Textarea with border 14 | 15 | ```html :::demo 16 |
17 | 18 |
19 | ``` 20 | 21 | Ghost (no background) 22 | 23 | ```html :::demo 24 |
25 | 26 |
27 | ``` 28 | 29 | Textarea with colors 30 | 31 | ```html :::demo 32 |
33 | 34 |
35 | 36 |
37 | 38 |
39 | 40 |
41 | 42 |
43 | 44 |
45 | 46 |
47 | ``` 48 | 49 | ## Textarea 50 | 51 | ### Attributes 52 | 53 | | name | description | type | default | 54 | | ------- | ------------------- | ------------------------------------------------------------------------- | ------- | 55 | | variant | textarea color type | neutral, primary, secondary, accent, info, success, warning, error, ghost | neutral | 56 | | border | textarea border | boolean | true | 57 | -------------------------------------------------------------------------------- /docs/src/pages/components/toggle.md: -------------------------------------------------------------------------------- 1 | # Toggle 2 | 3 | ## Examples 4 | 5 | Toggle 6 | 7 | ```html :::demo 8 |
9 | 10 |
11 | ``` 12 | 13 | Toggle color 14 | 15 | ```html :::demo 16 |
17 | 22 |
23 | ``` 24 | 25 | Toggle size 26 | 27 | ```html :::demo 28 |
29 | 30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 | ``` 38 | 39 | ## Toggle 40 | 41 | ### Attributes 42 | 43 | | name | description | type | default | 44 | | ------------ | ---------------------- | ----------------------------------- | ------- | 45 | | v-model | v-model checked status | boolean | - | 46 | | defaultValue | initial checked status | Function | - | 47 | | variant | toogle color type | neutral, primary, secondary, accent | neutral | 48 | | size | toogle size | xs, sm, md, lg | - | 49 | -------------------------------------------------------------------------------- /docs/src/pages/demo.md: -------------------------------------------------------------------------------- 1 | 2 | meta: 3 | menuHidden: true 4 | 5 | 6 | # Demo for development 7 | 8 | ```tsx :::run 9 | import { Tabs, TabPanel } from 'daisyui-vue'; 10 | import { ref } from 'vue'; 11 | 12 | export default { 13 | setup: () => { 14 | const currentTab = ref('1'); 15 | const slots = { 16 | default: () => 'Content 3', 17 | title: () => Title Slot, 18 | }; 19 | 20 | const arr = [1, 2, 3]; 21 | 22 | return () => ( 23 | 24 | I'm a text 25 | {null} 26 | {false} 27 | {0} 28 | {'a'} 29 | button 30 | <> 31 | {arr.map((it) => ( 32 |
{it}
33 | ))} 34 | asd 35 | {arr.map((it) => ( 36 |
{it}2
37 | ))} 38 | 39 |
40 | ); 41 | }, 42 | }; 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/src/pages/index.vue: -------------------------------------------------------------------------------- 1 | 2 | meta: 3 | name: Home 4 | sort: 0 5 | 6 | 7 | 33 | -------------------------------------------------------------------------------- /docs/src/styles/global.less: -------------------------------------------------------------------------------- 1 | body { 2 | -webkit-tap-highlight-color: transparent; 3 | --tw-bg-opacity: 1; 4 | } 5 | 6 | code.hljs { 7 | font-size: 14px; 8 | border-radius: 6px; 9 | } 10 | 11 | .docs-img-bg { 12 | background-image: url(@/assets/photo.jpg); 13 | } 14 | 15 | .dv { 16 | &-bgbase100 { 17 | --tw-bg-opacity: 1; 18 | background-color: hsl(var(--b1) / var(--tw-bg-opacity)); 19 | } 20 | &-bgbase200 { 21 | --tw-bg-opacity: 1; 22 | background-color: hsl(var(--b2) / var(--tw-bg-opacity)); 23 | } 24 | &-bgbase300 { 25 | --tw-bg-opacity: 1; 26 | background-color: hsl(var(--b3) / var(--tw-bg-opacity)); 27 | } 28 | 29 | &-borderbase100 { 30 | --tw-border-opacity: 1; 31 | border-color: hsl(var(--b1) / var(--tw-border-opacity)); 32 | } 33 | 34 | &-borderbase200 { 35 | --tw-border-opacity: 1; 36 | border-color: hsl(var(--b2) / var(--tw-border-opacity)); 37 | } 38 | 39 | &-textbasecontent { 40 | --tw-text-opacity: 1; 41 | color: hsl(var(--bc) / var(--tw-text-opacity)); 42 | } 43 | 44 | &-roundedbox { 45 | border-radius: var(--dv-roundedbox, 1rem); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /docs/src/styles/index.ts: -------------------------------------------------------------------------------- 1 | import './tailwind.css'; 2 | import './markdown.less'; 3 | import 'highlight.js/styles/atom-one-dark.css'; 4 | import './global.less'; 5 | -------------------------------------------------------------------------------- /docs/src/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /docs/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export const isBrowser = typeof window !== 'undefined'; 2 | -------------------------------------------------------------------------------- /docs/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | // tailwind.config.js 2 | module.exports = { 3 | // purge: { 4 | // // enabled: true, 5 | // content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx,html,md}'], 6 | // options: { 7 | // safelist: [/data-theme$/], 8 | // }, 9 | // }, 10 | // darkMode: false, // or 'media' or 'class' 11 | content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx,html,md}'], 12 | theme: { 13 | extend: {}, 14 | }, 15 | variants: { 16 | extend: {}, 17 | }, 18 | // plugins: [require('daisyui')], // 引用一些基本样式 19 | daisyui: { 20 | logs: false, 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "include": ["src"], 4 | "compilerOptions": { 5 | "allowSyntheticDefaultImports": true, 6 | "moduleResolution": "Node", 7 | "esModuleInterop": true, 8 | // "types": ["vite/client", "vite-plugin-pages/client"], 9 | "baseUrl": ".", 10 | "paths": { 11 | "daisyui-vue": ["../dist"], 12 | "@/*": ["src/*"] 13 | }, 14 | "resolveJsonModule": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | testPathIgnorePatterns: ['src/_daisyui'], 6 | testTimeout: 10000, 7 | testMatch: ['**/__tests__/**/*.test.[jt]s?(x)'], 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "daisyui-vue", 3 | "private": true, 4 | "version": "0.0.1-alpha.20", 5 | "author": "daief (https://github.com/daief)", 6 | "homepage": "https://daief.tech/daisyui-vue", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/daief/daisyui-vue.git" 10 | }, 11 | "license": "Apache-2.0", 12 | "sideEffects": false, 13 | "scripts": { 14 | "build": "rm -rf dist && NODE_ENV=production rollup -c", 15 | "watch": "NODE_ENV=development rollup -c -w", 16 | "dvinit": "dv init", 17 | "icons": "dv icons", 18 | "release": "standard-version", 19 | "pre:release": "pnpm run release --prerelease=alpha", 20 | "pub": "pnpm build && pnpm dv pre-publish && pnpm dv publish" 21 | }, 22 | "resolutions": { 23 | "vue": "3.2.26" 24 | }, 25 | "peerDependencies": { 26 | "@vicons/ionicons5": "^0.12.0", 27 | "vue": "^3.0.0" 28 | }, 29 | "dependencies": { 30 | "@popperjs/core": "^2.11.6", 31 | "deepmerge": "^4.0.0" 32 | }, 33 | "devDependencies": { 34 | "@dv/develop": "*", 35 | "@types/jest": "^29.4.0", 36 | "@types/node": "^14.18.12", 37 | "@vicons/ionicons5": "^0.12.0", 38 | "jest": "^29.4.3", 39 | "prettier": "^2.4.0", 40 | "standard-version": "^9.5.0", 41 | "ts-jest": "^29.0.5", 42 | "vue": "*" 43 | }, 44 | "publishConfig": { 45 | "registry": "https://registry.npmjs.org/", 46 | "access": "public" 47 | }, 48 | "description": "Vue3 UI components based on [daisyui](https://github.com/saadeghi/daisyui).", 49 | "keywords": [ 50 | "Vue", 51 | "Vue3", 52 | "UI Library", 53 | "UI Components", 54 | "Daisyui" 55 | ], 56 | "bugs": { 57 | "url": "https://github.com/daief/daisyui-vue/issues" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/daisyui-style-ext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "daisyui-style-ext", 3 | "private": true, 4 | "version": "1.0.0", 5 | "main": "out/index.js", 6 | "license": "MIT", 7 | "devDependencies": { 8 | "@types/node": "^14.0.13", 9 | "@types/vscode": "^1.46.0", 10 | "esbuild": "^0.14.27", 11 | "typescript": "^4.0.0" 12 | }, 13 | "engines": { 14 | "vscode": "^1.46.0", 15 | "node": ">=14.0.0" 16 | }, 17 | "scripts": { 18 | "esbuild-base": "esbuild ./src/index.ts --bundle --outfile=out/index.js --external:vscode --format=cjs --platform=node", 19 | "build": "pnpm esbuild-base --minify", 20 | "pkg": "vsce package --no-dependencies --out out/ext.vsix" 21 | }, 22 | "activationEvents": [ 23 | "onCommand:extension.ds-insert-style" 24 | ], 25 | "contributes": { 26 | "commands": [ 27 | { 28 | "command": "extension.ds-insert-style", 29 | "title": "Daisyui Style: Insert style" 30 | } 31 | ], 32 | "menus": { 33 | "editor/context": [ 34 | { 35 | "command": "extension.ds-insert-style", 36 | "group": "1_ds" 37 | } 38 | ] 39 | }, 40 | "keybindings": [ 41 | { 42 | "command": "extension.ds-insert-style", 43 | "key": "alt+cmd+d" 44 | } 45 | ] 46 | }, 47 | "configuration": { 48 | "properties": {} 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/daisyui-style-ext/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ES6", 5 | "lib": ["DOM", "ESNext"], 6 | "module": "CommonJS", 7 | "moduleResolution": "Node", 8 | "skipLibCheck": true, 9 | "experimentalDecorators": true, 10 | "emitDecoratorMetadata": true, 11 | "allowSyntheticDefaultImports": true, 12 | "baseUrl": ".", 13 | "paths": { 14 | "@/*": ["src/*"] 15 | }, 16 | "outDir": "out" 17 | }, 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/develop/__tests__/fixtures/classname-plugin.js: -------------------------------------------------------------------------------- 1 | __c('btn'); 2 | 3 | ['$clsUniquePrefix$btn dv-btn']; 4 | /* - */ 5 | __c(a, 'btn'); 6 | 7 | [a, '$clsUniquePrefix$btn dv-btn']; 8 | /* - */ 9 | __c(`btn`); 10 | 11 | [`$clsUniquePrefix$btn dv-btn`]; 12 | /* - */ 13 | __c(`btn-${a}`); 14 | 15 | [`$clsUniquePrefix$btn-${a} dv-btn-${a}`]; 16 | /* - */ 17 | __c('a', `b`); 18 | 19 | ['$clsUniquePrefix$a dv-a', `$clsUniquePrefix$b dv-b`]; 20 | /* - */ 21 | __c({ 22 | a1: true, 23 | }); 24 | 25 | [ 26 | { 27 | '$clsUniquePrefix$a1 dv-a1': true, 28 | }, 29 | ]; 30 | /* - */ 31 | __c({ 32 | a1: true, 33 | [a]: false, 34 | }); 35 | 36 | [ 37 | { 38 | '$clsUniquePrefix$a1 dv-a1': true, 39 | [a]: false, 40 | }, 41 | ]; 42 | /* - */ 43 | __c({ 44 | a2: true, 45 | }); 46 | 47 | [ 48 | { 49 | '$clsUniquePrefix$a2 dv-a2': true, 50 | }, 51 | ]; 52 | /* - */ 53 | __c({ 54 | [`bb`]: true, 55 | }); 56 | 57 | [ 58 | { 59 | [`$clsUniquePrefix$bb dv-bb`]: true, 60 | }, 61 | ]; 62 | /* - */ 63 | __c({ 64 | [`bb-${a}`]: true, 65 | }); 66 | 67 | [ 68 | { 69 | [`$clsUniquePrefix$bb-${a} dv-bb-${a}`]: true, 70 | }, 71 | ]; 72 | /* - */ 73 | __c({ 74 | [`bb-${a}-${b}-ss`]: true, 75 | }); 76 | 77 | [ 78 | { 79 | [`$clsUniquePrefix$bb-${a}-${b}-ss dv-bb-${a}-${b}-ss`]: true, 80 | }, 81 | ]; 82 | /* - */ 83 | __c`a`; 84 | 85 | `$clsUniquePrefix$a dv-a`; 86 | /* - */ 87 | __c`a-${1}`; 88 | 89 | `$clsUniquePrefix$a-${1} dv-a-${1}`; 90 | -------------------------------------------------------------------------------- /packages/develop/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('.'); 4 | 5 | require('./src/cli.ts'); 6 | -------------------------------------------------------------------------------- /packages/develop/index.js: -------------------------------------------------------------------------------- 1 | const register = () => { 2 | const tsNode = require('ts-node'); 3 | const path = require('path'); 4 | 5 | tsNode.register({ 6 | project: path.resolve(__dirname, 'tsconfig.json'), 7 | }); 8 | }; 9 | 10 | register(); 11 | 12 | module.exports = require('./src/index.ts'); 13 | module.exports.register = register; 14 | -------------------------------------------------------------------------------- /packages/develop/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dv/develop", 3 | "private": true, 4 | "version": "1.0.0", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "bin": { 8 | "dv": "cli.js" 9 | }, 10 | "dependencies": { 11 | "@babel/core": "^7.15.5", 12 | "@babel/preset-env": "^7.20.2", 13 | "@babel/preset-typescript": "^7.18.6", 14 | "@rollup/plugin-alias": "^3.1.5", 15 | "@rollup/plugin-babel": "^5.3.0", 16 | "@rollup/plugin-commonjs": "^24.1.0", 17 | "@rollup/plugin-node-resolve": "^15.0.0", 18 | "@rollup/plugin-replace": "^3.0.0", 19 | "@types/babel__core": "^7.20.1", 20 | "@types/fs-extra": "^9.0.13", 21 | "@types/glob": "^7.1.4", 22 | "@vue/babel-plugin-jsx": "^1.1.1", 23 | "autoprefixer": "^10.3.4", 24 | "cac": "^6.7.14", 25 | "cssnano": "^5.0.10", 26 | "daisyui": "3.1.5", 27 | "download-git-repo": "^3.0.2", 28 | "fs-extra": "^10.0.1", 29 | "glob": "^7.1.7", 30 | "less": "^4.1.1", 31 | "node-fetch": "^2.0.0", 32 | "node-html-parser": "^4.1.5", 33 | "postcss": "^8.0.0", 34 | "postcss-modules": "^6.0.0", 35 | "postcss-nested": "^5.0.6", 36 | "prettier": "^2.4.0", 37 | "rollup": "^2.79.0", 38 | "rollup-plugin-cleanup": "^3.2.1", 39 | "rollup-plugin-postcss": "^4.0.1", 40 | "rollup-plugin-typescript2": "^0.34.0", 41 | "standard-version": "^9.3.2", 42 | "tailwindcss": "^3.3.2", 43 | "ts-node": "^10.9.1", 44 | "tslib": "^2.4.0", 45 | "typescript": "^4.8.2", 46 | "vue": "3.2.26" 47 | }, 48 | "devDependencies": { 49 | "https-proxy-agent": "^7.0.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /packages/develop/src/build/rollup-styles-plugin.ts: -------------------------------------------------------------------------------- 1 | import { Plugin } from 'rollup'; 2 | import postcss, { Plugin as PostcssPlugin } from 'postcss'; 3 | import { createPostcssModulesOptions } from './classname-plugin'; 4 | import postcssModules from 'postcss-modules'; 5 | 6 | // const postcssJs = require('postcss-js'); 7 | const less = require('less'); 8 | 9 | const postcssRemToPx = (): PostcssPlugin => { 10 | const base = 16; 11 | return { 12 | postcssPlugin: 'postcssRemToPx', 13 | Rule(rule) { 14 | rule.walkDecls((decl) => { 15 | const reg = /(\d*\.?\d+)rem/gis; 16 | const res = decl.value.matchAll(reg); 17 | for (const it of res) { 18 | const px = +it[1] * base + 'px'; 19 | decl.value = decl.value.replace(it[0], px); 20 | } 21 | }); 22 | }, 23 | }; 24 | }; 25 | 26 | export const createStylesPlugin = (tailwindConfig: any) => { 27 | tailwindConfig = { ...tailwindConfig }; 28 | tailwindConfig.content = []; 29 | const process = postcss([ 30 | require('tailwindcss')({ 31 | ...tailwindConfig, 32 | }), 33 | require('postcss-nested')({ 34 | bubble: ['screen'], 35 | }), 36 | require('cssnano')({ 37 | preset: [ 38 | 'default', 39 | { 40 | mergeRules: false, 41 | }, 42 | ], 43 | }), 44 | require('autoprefixer'), 45 | postcssRemToPx(), 46 | postcssModules(createPostcssModulesOptions()), 47 | ]); 48 | 49 | const uid = (() => { 50 | let i = 0; 51 | return () => ++i; 52 | })(); 53 | 54 | const plugin: Plugin = { 55 | name: 'rollup-styles-plugin', 56 | async transform(code, id) { 57 | if (!/\.(le|c)ss$/.test(id)) return null; 58 | 59 | let cssCode = code; 60 | 61 | if (/\.less/i.test(id)) { 62 | // https://lesscss.org/usage/#programmatic-usage 63 | const lessResult = await less.render(code, { 64 | sourceMap: { sourceMapFileInline: false }, 65 | }); 66 | cssCode = lessResult.css; 67 | } 68 | 69 | const postcssResult = await process.process(cssCode, { 70 | map: false, 71 | }); 72 | 73 | // css 2 js 74 | // const jsObject = postcssJs.objectify(postcssResult.root); 75 | // jsObject[':root'] = void 0; 76 | // return `export default ${JSON.stringify(jsObject)}`; 77 | 78 | return ` 79 | const css = ${JSON.stringify(postcssResult.css)}; 80 | export default { 81 | css, 82 | id: ${uid()}, 83 | }; 84 | `; 85 | }, 86 | }; 87 | 88 | return plugin; 89 | }; 90 | -------------------------------------------------------------------------------- /packages/develop/src/build/ts-declaration-transformer.ts: -------------------------------------------------------------------------------- 1 | import * as ts from 'typescript'; 2 | import * as path from 'path'; 3 | 4 | /** 5 | * 替换产物声明文件中的别名路径 6 | * @param context 7 | * @returns 8 | */ 9 | export const createDeclarationTransformer: ts.TransformerFactory< 10 | ts.SourceFile 11 | > = (context) => { 12 | const config = context.getCompilerOptions(); 13 | const aliasKeys = Object.keys(config.paths!) 14 | .filter((it) => it.endsWith('*')) 15 | .map((it) => it.replace('*', '')); // [ '@/', '@styles/' ] 16 | 17 | return (source) => { 18 | const currentFileName = source.fileName; 19 | 20 | const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult => { 21 | const isOk = 22 | node.parent && 23 | (ts.isImportDeclaration(node.parent) || 24 | ts.isExportDeclaration(node.parent)) && 25 | ts.isStringLiteral(node); 26 | 27 | let importAliaKey = isOk 28 | ? aliasKeys.find((key) => node.text.startsWith(key)) 29 | : undefined; 30 | 31 | if (isOk && importAliaKey) { 32 | const importAliaKeyWithStar = importAliaKey + '*'; 33 | // 替换别名 34 | const prefix = config.paths![importAliaKeyWithStar][0].replace('*', ''); 35 | const importFileName = path.resolve( 36 | config.baseUrl!, 37 | prefix, 38 | node.text.replace(importAliaKey, ''), 39 | ); 40 | 41 | const relativeImport = path.relative( 42 | path.dirname(currentFileName), 43 | importFileName, 44 | ); 45 | 46 | return ts.factory.createStringLiteral(relativeImport, true); 47 | } 48 | return ts.visitEachChild(node, visitor, context); 49 | }; 50 | 51 | return ts.visitNode(source, visitor); 52 | }; 53 | }; 54 | 55 | export const createDeclarationTransformerFactory = (program: ts.Program) => { 56 | return createDeclarationTransformer; 57 | }; 58 | -------------------------------------------------------------------------------- /packages/develop/src/cli.ts: -------------------------------------------------------------------------------- 1 | import { cac } from 'cac'; 2 | import path from 'path'; 3 | import { createIcons, init, parseCssTheme } from './init'; 4 | import fs from 'fs-extra'; 5 | 6 | const cli = cac('dv'); 7 | 8 | const context = process.cwd(); 9 | const workspace = (...ps: string[]) => path.resolve(context, ...ps); 10 | 11 | cli.command('init', 'init daisyui & theme').action(async () => { 12 | return init(context); 13 | }); 14 | 15 | cli.command('icons', 'create icons').action(async () => { 16 | return createIcons(context); 17 | }); 18 | 19 | cli.command('gen-themes', 'init theme').action(async () => { 20 | return parseCssTheme(context); 21 | }); 22 | 23 | cli.command('pre-publish', '').action(async () => { 24 | const pkg = fs.readJsonSync(workspace('package.json')); 25 | pkg.private = false; 26 | pkg.main = 'index.js'; 27 | pkg.module = 'index.js'; 28 | pkg.type = 'module'; 29 | delete pkg.devDependencies; 30 | fs.writeJSONSync(workspace('dist/package.json'), pkg, { 31 | spaces: 2, 32 | }); 33 | ['.npmrc'].forEach((file) => { 34 | fs.copyFileSync(workspace(file), workspace('dist', file)); 35 | }); 36 | console.log('package.json:\n', JSON.stringify(pkg, null, 4)); 37 | }); 38 | 39 | cli.command('publish', '').action(async () => { 40 | const { execSync } = await import('child_process'); 41 | execSync('npm publish', { 42 | cwd: workspace('dist'), 43 | stdio: 'inherit', 44 | }); 45 | }); 46 | 47 | cli.help().parse(); 48 | -------------------------------------------------------------------------------- /packages/develop/src/index.ts: -------------------------------------------------------------------------------- 1 | export { getRoolupConfig } from './build/rollup'; 2 | -------------------------------------------------------------------------------- /packages/develop/src/init/index.ts: -------------------------------------------------------------------------------- 1 | import pkg from '../../package.json'; 2 | const version = pkg.dependencies.daisyui; 3 | 4 | // @ts-ignore 5 | import downloadRepo from 'download-git-repo'; 6 | import path from 'path'; 7 | import fs from 'fs-extra'; 8 | import { parseCssTheme } from './parse-css-theme'; 9 | 10 | export const init = async (context: string) => { 11 | const workspace = (...ps: string[]) => path.resolve(context, ...ps); 12 | 13 | const clone = () => 14 | new Promise((accept, reject) => { 15 | downloadRepo( 16 | 'saadeghi/daisyui#v' + version, 17 | workspace('src/_daisyui'), 18 | { 19 | shallow: 1, 20 | }, 21 | (err: any) => { 22 | if (err) { 23 | return reject(err); 24 | } 25 | accept(); 26 | fs.emptyDirSync(workspace('src/_daisyui/examples')); 27 | console.log('[Init]: clone daisyui repo done'); 28 | }, 29 | ); 30 | }); 31 | 32 | return Promise.all([clone(), parseCssTheme(context)]); 33 | }; 34 | 35 | export async function createIcons(context: string) { 36 | const workspace = (...ps: string[]) => path.resolve(context, ...ps); 37 | const iconFile = require.resolve('@vicons/ionicons5'); 38 | 39 | const filterFiles = ['index', 'async-index']; 40 | 41 | const icons = await fs.readdir(path.dirname(iconFile)).then((ls) => 42 | ls 43 | .filter((it) => it.endsWith('.js')) 44 | .map((it) => it.replace('.js', '')) 45 | .filter((it) => !filterFiles.includes(it)), 46 | ); 47 | 48 | const topImports = `import { defineComponent, HTMLAttributes } from 'vue'; 49 | import { Icon, iconProps, IIconProps, IconComponent } from './icon'; 50 | `; 51 | 52 | const iconTpl = ` 53 | export const Icon$name = /* @__PURE__ */ defineComponent({ 54 | name: 'Icon$name', 55 | props: iconProps as any, 56 | setup: (props) => { 57 | return () => ( 58 | $slot 59 | ); 60 | }, 61 | }) as any as IconComponent; 62 | `; 63 | 64 | let file = topImports; 65 | 66 | file += 'import {\n'; 67 | file += ' ' + icons.join(',\n '); 68 | file += `} from '@vicons/ionicons5'\n`; 69 | 70 | file += icons 71 | .map((icon) => 72 | iconTpl.replace(/\$name/g, icon).replace('$slot', `<${icon} />`), 73 | ) 74 | .join('\n'); 75 | 76 | await fs.writeFile(workspace('src/components/icon/icons.tsx'), file); 77 | 78 | console.log(`[Generate icons]: create ${icons.length} icons success.`); 79 | } 80 | 81 | export { parseCssTheme }; 82 | -------------------------------------------------------------------------------- /packages/develop/tsconfig.json: -------------------------------------------------------------------------------- 1 | // for ts-node 2 | { 3 | // https://github.com/tsconfig/bases 4 | // "extends": "ts-node/node14/tsconfig.json", 5 | 6 | // Most ts-node options can be specified here using their programmatic names. 7 | "ts-node": { 8 | // It is faster to skip typechecking. 9 | // Remove if you want ts-node to do typechecking. 10 | "transpileOnly": false, 11 | 12 | "files": true, 13 | 14 | "compilerOptions": { 15 | // compilerOptions specified here will override those declared below, 16 | // but *only* in ts-node. Useful if you want ts-node and tsc to use 17 | // different options with a single tsconfig.json. 18 | } 19 | }, 20 | "compilerOptions": { 21 | // typescript options here 22 | "forceConsistentCasingInFileNames": true, 23 | "resolveJsonModule": true, 24 | "strict": true, 25 | "target": "ES6", 26 | "lib": ["DOM", "ESNext"], 27 | "module": "CommonJS", 28 | "moduleResolution": "Node", 29 | "skipLibCheck": true, 30 | "experimentalDecorators": true, 31 | "emitDecoratorMetadata": true, 32 | "allowSyntheticDefaultImports": true, 33 | "esModuleInterop": true 34 | }, 35 | "include": ["src/**/*"] 36 | } 37 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - docs 3 | - packages/* 4 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | // postcss.config.js 2 | module.exports = { 3 | plugins: { 4 | tailwindcss: {}, 5 | autoprefixer: {}, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import { getRoolupConfig } from '@dv/develop'; 2 | 3 | export default getRoolupConfig({ 4 | context: process.cwd(), 5 | }); 6 | -------------------------------------------------------------------------------- /scripts/buildIcons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 从 svg 文件生成 tsx 组件 3 | * - 默认为 stroke 模式,如果是 fill 模式,需要在 svg 上标记 stroke="none" 4 | * - svg 上的 viewBox 会被继承 5 | */ 6 | 7 | const path = require('path'); 8 | const fs = require('fs-extra'); 9 | const parser = require('node-html-parser'); 10 | 11 | const baseDir = path.resolve(__dirname, '../src/icons'); 12 | const svgDir = path.resolve(baseDir, 'svg'); 13 | const vueDir = path.resolve(baseDir, 'vue'); 14 | 15 | const svgs = fs.readdirSync(svgDir); 16 | 17 | const iconFileTpl = ` 18 | import { component } from '@/shared/styled'; 19 | import { IconBase, IIconBaseProps } from '../icon-base'; 20 | 21 | const $name = component({ 22 | name: '$name', 23 | setup: () => { 24 | return () => ( 25 | 26 | $child 27 | 28 | ); 29 | }, 30 | }); 31 | 32 | export default $name; 33 | `; 34 | 35 | const icons = []; 36 | 37 | fs.emptyDirSync(vueDir); 38 | 39 | for (let index = 0; index < svgs.length; index++) { 40 | const basename = svgs[index]; 41 | const svgName = basename 42 | .replace(/\.svg$/i, '') 43 | // ax-bc-df => AxBcDf 44 | .split('-') 45 | .map((it) => it[0].toUpperCase() + it.slice(1)) 46 | .join(''); 47 | const iconName = `Icon${svgName}`; 48 | icons.push(iconName); 49 | 50 | const svgContent = fs.readFileSync(path.resolve(svgDir, basename), 'utf-8'); 51 | const svgNode = parser.parse(svgContent).firstChild; 52 | const svgChildContent = svgNode.innerHTML; 53 | 54 | const iconFile = iconFileTpl 55 | .replace(/\$name/g, iconName) 56 | .replace(/\$child/g, svgChildContent) 57 | // viewBox 58 | .replace( 59 | /\$props/g, 60 | svgNode.attributes.viewBox 61 | ? `viewBox="${svgNode.attributes.viewBox}" $props` 62 | : '$props', 63 | ) 64 | .replace( 65 | /\$props/g, 66 | svgContent.includes('stroke="none"') ? 'useStroke={false}' : '', 67 | ); 68 | 69 | fs.writeFileSync(path.resolve(vueDir, iconName + '.tsx'), iconFile); 70 | 71 | console.log(`✅ ${iconName}`); 72 | } 73 | 74 | const indexContent = icons 75 | .map((name) => `export { default as ${name} } from './${name}'`) 76 | .join('\n'); 77 | fs.writeFileSync(path.resolve(vueDir, 'index.tsx'), indexContent); 78 | -------------------------------------------------------------------------------- /src/@types/dom.ts: -------------------------------------------------------------------------------- 1 | import { InputHTMLAttributes } from 'vue'; 2 | 3 | export type InputChangeEvent = Omit & { 4 | target: HTMLInputElement; 5 | }; 6 | -------------------------------------------------------------------------------- /src/@types/ext.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.less' { 2 | const content: { 3 | css: string; 4 | id: number; 5 | }; 6 | export default content; 7 | } 8 | 9 | declare module '*.css' { 10 | const content: { 11 | css: string; 12 | id: number; 13 | }; 14 | export default content; 15 | } 16 | -------------------------------------------------------------------------------- /src/@types/global.d.ts: -------------------------------------------------------------------------------- 1 | declare const VERSION: string; 2 | declare const CLASSNAME_UNIQUE: string; 3 | 4 | interface __C { 5 | (template: TemplateStringsArray, ...values: any[]): string; 6 | (...args: Array>): Array< 7 | string | Record 8 | >; 9 | } 10 | 11 | // compiled by babel plugin 12 | declare const __c: __C; 13 | -------------------------------------------------------------------------------- /src/components/_styles/animate.less: -------------------------------------------------------------------------------- 1 | .dv-t-translate-x-enter-active, 2 | .dv-t-translate-x-leave-active, 3 | .-dv-t-translate-x-enter-active, 4 | .-dv-t-translate-x-leave-active { 5 | transition-property: transform; 6 | @apply duration-300 ease-in-out; 7 | } 8 | 9 | .dv-t-translate-x-enter-from, 10 | .dv-t-translate-x-leave-to { 11 | @apply -translate-x-full; 12 | } 13 | 14 | .-dv-t-translate-x-enter-from, 15 | .-dv-t-translate-x-leave-to { 16 | @apply translate-x-full; 17 | } 18 | -------------------------------------------------------------------------------- /src/components/_styles/common/checkbox-radio.less: -------------------------------------------------------------------------------- 1 | .dv-checkbox, 2 | .dv-radio { 3 | &-wrapper { 4 | display: inline-flex; 5 | align-items: center; 6 | cursor: pointer; 7 | vertical-align: top; 8 | 9 | &-disabled { 10 | cursor: not-allowed; 11 | } 12 | } 13 | 14 | &-xs + span { 15 | @apply text-xs leading-5; 16 | } 17 | &-sm + span { 18 | @apply text-sm leading-6; 19 | } 20 | &-md + span { 21 | @apply text-base leading-7; 22 | } 23 | &-lg + span { 24 | @apply text-lg leading-8; 25 | } 26 | 27 | & + span { 28 | padding-left: 8px; 29 | padding-right: 8px; 30 | } 31 | } 32 | 33 | @names: checkbox, radio; 34 | each(@names, { 35 | @css-gap: ~"--dv-@{value}-gap"; 36 | 37 | .dv-@{value}-wrapper { 38 | & + & { 39 | margin-left: var(@css-gap, 8px); 40 | } 41 | } 42 | 43 | .dv-@{value}-group-item { 44 | margin-right: var(@css-gap, 8px); 45 | &:last-child { 46 | margin-right: 0; 47 | } 48 | } 49 | }) 50 | .dv-checkbox-group, 51 | .dv-radio-group { 52 | display: inline-block; 53 | line-height: 1.5715; 54 | 55 | &-item + &-item { 56 | margin-left: 0; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/_styles/daisyui-utilities-global/glass.css: -------------------------------------------------------------------------------- 1 | .glass { 2 | &.btn, 3 | &.btn-active { 4 | border: none; 5 | backdrop-filter: blur(var(--glass-blur, 40px)); 6 | background-color: transparent; 7 | background-image: linear-gradient( 8 | 135deg, 9 | rgb(255 255 255 / var(--glass-opacity, 30%)) 0%, 10 | rgb(0 0 0 / 0%) 100% 11 | ), 12 | linear-gradient( 13 | var(--glass-reflex-degree, 100deg), 14 | rgb(255 255 255 / var(--glass-reflex-opacity, 10%)) 25%, 15 | rgb(0 0 0 / 0%) 25% 16 | ); 17 | box-shadow: 0 0 0 1px rgb(255 255 255 / var(--glass-border-opacity, 10%)) 18 | inset, 19 | 0 0 0 2px rgb(0 0 0 / 5%); 20 | text-shadow: 0 1px rgb(0 0 0 / var(--glass-text-shadow-opacity, 5%)); 21 | } 22 | @media (hover: hover) { 23 | &.btn-active { 24 | border: none; 25 | backdrop-filter: blur(var(--glass-blur, 40px)); 26 | background-color: transparent; 27 | background-image: linear-gradient( 28 | 135deg, 29 | rgb(255 255 255 / var(--glass-opacity, 30%)) 0%, 30 | rgb(0 0 0 / 0%) 100% 31 | ), 32 | linear-gradient( 33 | var(--glass-reflex-degree, 100deg), 34 | rgb(255 255 255 / var(--glass-reflex-opacity, 10%)) 25%, 35 | rgb(0 0 0 / 0%) 25% 36 | ); 37 | box-shadow: 0 0 0 1px rgb(255 255 255 / var(--glass-border-opacity, 10%)) 38 | inset, 39 | 0 0 0 2px rgb(0 0 0 / 5%); 40 | text-shadow: 0 1px rgb(0 0 0 / var(--glass-text-shadow-opacity, 5%)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/components/_styles/daisyui-utilities-global/variables.css: -------------------------------------------------------------------------------- 1 | .no-animation { 2 | --btn-focus-scale: 1; 3 | --animation-btn: 0; 4 | --animation-input: 0; 5 | } 6 | .tab-border-none { 7 | --tab-border: 0px; 8 | } 9 | .tab-border { 10 | --tab-border: 1px; 11 | } 12 | .tab-border-2 { 13 | --tab-border: 2px; 14 | } 15 | .tab-border-3 { 16 | --tab-border: 3px; 17 | } 18 | .tab-rounded-none { 19 | --tab-radius: 0; 20 | } 21 | .tab-rounded-lg { 22 | --tab-radius: 0.5rem; 23 | } 24 | -------------------------------------------------------------------------------- /src/components/_styles/global.ts: -------------------------------------------------------------------------------- 1 | import d_glass from './daisyui-utilities-global/glass.css'; 2 | import d_variables from './daisyui-utilities-global/variables.css'; 3 | import animate from './animate.less'; 4 | 5 | const globalStyles = [d_glass, d_variables, animate]; 6 | export default globalStyles; 7 | 8 | export const globalStyleIds = globalStyles.map((it) => it.id); 9 | -------------------------------------------------------------------------------- /src/components/_widgets/raw.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps, IColorType } from 'daisyui-vue/shared/types/common'; 3 | import { computed, createVNode, HTMLAttributes, PropType } from 'vue'; 4 | import style from './style/raw.less'; 5 | import { IThemeVariableColor } from 'daisyui-vue/shared/theme/define'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export type IRawType = IColorType | 'base-100' | 'base-200' | 'base-300'; 9 | 10 | export const rawProps = { 11 | tag: { 12 | type: String, 13 | default: 'div', 14 | }, 15 | variant: { 16 | type: String as PropType, 17 | default: '', 18 | }, 19 | color: { 20 | type: String as PropType | PropType, 21 | default: '', 22 | }, 23 | }; 24 | 25 | export type IRawProps = ExtractFromProps; 26 | 27 | export const Raw = componentV2( 28 | { 29 | name: 'Raw', 30 | props: rawProps, 31 | setup: (props, { slots }) => { 32 | const theme = useTheme(); 33 | 34 | const bg = computed(() => { 35 | const cssVar = theme.variables.css[props.variant || '']; 36 | if (cssVar) return `hsl(${cssVar} / var(--tw-bg-opacity, 1))`; 37 | return 'none'; 38 | }); 39 | 40 | const color = computed(() => { 41 | if (!props.color && props.variant) { 42 | const bgContent = props.variant.startsWith('base-') 43 | ? theme.variables.css['base-content'] 44 | : theme.variables.css[`${props.variant}-content`]; 45 | return `hsl(${bgContent} / var(--tw-text-opacity, 1))`; 46 | } 47 | 48 | const colorFromTheme = theme.variables.css[props.color || '']; 49 | if (props.color && colorFromTheme) { 50 | return `hsl(${colorFromTheme} / var(--tw-text-opacity, 1))`; 51 | } 52 | 53 | return props.color || 'currentColor'; 54 | }); 55 | 56 | const styleRef = computed(() => { 57 | return { 58 | '--dv-raw-bg': bg.value, 59 | '--dv-raw-color': color.value, 60 | }; 61 | }); 62 | 63 | return () => 64 | createVNode( 65 | props.tag || 'div', 66 | { 67 | class: `${theme.className} dv-raw`, 68 | style: styleRef.value, 69 | }, 70 | slots.default?.(), 71 | ); 72 | }, 73 | }, 74 | [style], 75 | ); 76 | -------------------------------------------------------------------------------- /src/components/_widgets/style/raw.less: -------------------------------------------------------------------------------- 1 | .dv-raw { 2 | background-color: var(--dv-raw-bg); 3 | color: var(--dv-raw-color); 4 | } 5 | -------------------------------------------------------------------------------- /src/components/_widgets/theme.tsx: -------------------------------------------------------------------------------- 1 | import { THEME_CONTEXT_SYMBOL, useStyleManager } from 'daisyui-vue/shared/ctx'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 4 | import { ITheme, IThemeContext } from 'daisyui-vue/shared/types/theme'; 5 | import { 6 | HTMLAttributes, 7 | PropType, 8 | computed, 9 | h, 10 | provide, 11 | reactive, 12 | watch, 13 | } from 'vue'; 14 | 15 | export const themeProviderProps = { 16 | theme: { 17 | type: Object as PropType, 18 | require: true, 19 | }, 20 | wrapper: { 21 | type: [String, Boolean] as PropType, 22 | default: 'div', 23 | }, 24 | }; 25 | 26 | export type IThemeProviderProps = ExtractFromProps; 27 | 28 | export const ThemeProvider = componentV2({ 29 | name: 'ThemeProvider', 30 | props: themeProviderProps, 31 | setup: (props, { slots }) => { 32 | const styleMgr = useStyleManager(); 33 | const themeCtx: IThemeContext = reactive({} as any); 34 | const wrapperEl = computed(() => { 35 | if (typeof props.wrapper === 'string') return props.wrapper; 36 | if (props.wrapper) return 'div'; 37 | return ''; 38 | }); 39 | 40 | watch( 41 | () => props.theme, 42 | (val, _, clear) => { 43 | if (val) { 44 | Object.assign(themeCtx, props.theme, { 45 | className: styleMgr?.registerTheme(val)?.className || '', 46 | }); 47 | } 48 | clear(() => val && styleMgr?.unregisterTheme(val)); 49 | }, 50 | { 51 | immediate: true, 52 | flush: 'sync', 53 | }, 54 | ); 55 | 56 | provide(THEME_CONTEXT_SYMBOL, themeCtx); 57 | 58 | return () => 59 | wrapperEl.value 60 | ? h(wrapperEl.value, { class: themeCtx.className }, slots.default?.()) 61 | : slots.default?.(); 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /src/components/alert/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps, IStateColor } from 'daisyui-vue/shared/types/common'; 3 | import { 4 | IconBanOutline, 5 | IconCheckmarkCircleOutline, 6 | IconInformationCircleOutline, 7 | IconWarningOutline, 8 | } from '../icon'; 9 | import { HTMLAttributes, PropType } from 'vue'; 10 | import style from './style'; 11 | import { useTheme } from 'daisyui-vue/shared/ctx'; 12 | 13 | export const alertProps = { 14 | type: { 15 | type: String as PropType, 16 | default: '', 17 | }, 18 | }; 19 | 20 | export type IAlertProps = ExtractFromProps; 21 | 22 | export const Alert = componentV2( 23 | { 24 | name: 'Alert', 25 | props: alertProps, 26 | setup: (props, { slots }) => { 27 | return () => { 28 | const icon = 29 | slots.icon?.() || 30 | { 31 | info: () => , 32 | success: () => , 33 | warning: () => , 34 | error: () => , 35 | }[props.type!]?.(); 36 | 37 | const actions = slots.actions?.(); 38 | const content = slots.content?.(); 39 | const defaultSlot = slots.default?.(); 40 | const theme = useTheme(); 41 | 42 | return ( 43 |
50 |
51 | {icon ?
{icon}
: null} 52 | 62 |
63 | {actions ?
{actions}
: null} 64 |
65 | ); 66 | }; 67 | }, 68 | }, 69 | style, 70 | ); 71 | -------------------------------------------------------------------------------- /src/components/alert/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-alert { 2 | @apply bg-base-200 p-4 rounded-box text-base-content; 3 | &-info { 4 | @apply bg-info text-info-content; 5 | } 6 | &-success { 7 | @apply bg-success text-success-content; 8 | } 9 | &-warning { 10 | @apply bg-warning text-warning-content; 11 | } 12 | &-error { 13 | @apply bg-error text-error-content; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/components/alert/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-alert { 2 | @apply flex w-full flex-col items-center justify-between gap-4 space-y-2 md:flex-row md:space-y-0; 3 | > :where(*) { 4 | @apply flex items-center gap-2; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/components/alert/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s from './style.less'; 4 | 5 | export default [s1, s2, s]; 6 | -------------------------------------------------------------------------------- /src/components/alert/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-alert { 2 | &-content { 3 | @apply flex-1; 4 | 5 | > label { 6 | @apply leading-6; 7 | 8 | > h4 { 9 | margin: 0; 10 | } 11 | > p { 12 | @apply text-sm text-base-content text-opacity-60 leading-5; 13 | } 14 | } 15 | } 16 | 17 | &-iconwrap { 18 | font-size: 1.5em; 19 | @apply mr-2 flex; 20 | } 21 | 22 | &-actions { 23 | @apply flex-none; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/artboard/artboard.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { HTMLAttributes, PropType } from 'vue'; 4 | import style from './style'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | export const artboardProps = { 8 | phone: { 9 | type: [String, Boolean] as PropType< 10 | boolean | '1' | '2' | '3' | '4' | '5' | '6' 11 | >, 12 | }, 13 | horizontal: { 14 | type: Boolean, 15 | }, 16 | }; 17 | 18 | export type IArtboardProps = ExtractFromProps; 19 | 20 | export const Artboard = componentV2( 21 | { 22 | name: 'Artboard', 23 | props: artboardProps, 24 | setup: (props, { slots }) => { 25 | const theme = useTheme(); 26 | return () => ( 27 |
39 | {slots.default?.()} 40 |
41 | ); 42 | }, 43 | }, 44 | style, 45 | ); 46 | -------------------------------------------------------------------------------- /src/components/artboard/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './artboard'; 2 | -------------------------------------------------------------------------------- /src/components/artboard/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-artboard { 2 | @apply w-full; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/artboard/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | 3 | import s2 from './u-us.css'; 4 | import s3 from './u-s.css'; 5 | 6 | export default [s1, s2, s3]; 7 | -------------------------------------------------------------------------------- /src/components/artboard/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-artboard { 2 | &-demo { 3 | @apply bg-base-100 text-base-content rounded-box; 4 | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/components/artboard/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-artboard { 2 | &-demo { 3 | @apply flex flex-none flex-col items-center justify-center; 4 | } 5 | &.dv-phone { 6 | width: 320px; 7 | &-1 { 8 | width: 320px; 9 | height: 568px; 10 | &.dv-horizontal, 11 | &.dv-artboard-horizontal { 12 | width: 568px; 13 | height: 320px; 14 | } 15 | } 16 | &-2 { 17 | width: 375px; 18 | height: 667px; 19 | &.dv-horizontal, 20 | &.dv-artboard-horizontal { 21 | width: 667px; 22 | height: 375px; 23 | } 24 | } 25 | &-3 { 26 | width: 414px; 27 | height: 736px; 28 | &.dv-horizontal, 29 | &.dv-artboard-horizontal { 30 | width: 736px; 31 | height: 414px; 32 | } 33 | } 34 | &-4 { 35 | width: 375px; 36 | height: 812px; 37 | &.dv-horizontal, 38 | &.dv-artboard-horizontal { 39 | width: 812px; 40 | height: 375px; 41 | } 42 | } 43 | &-5 { 44 | width: 414px; 45 | height: 896px; 46 | &.dv-horizontal, 47 | &.dv-artboard-horizontal { 48 | width: 896px; 49 | height: 414px; 50 | } 51 | } 52 | &-6 { 53 | width: 320px; 54 | height: 1024px; 55 | &.dv-horizontal, 56 | &.dv-artboard-horizontal { 57 | width: 1024px; 58 | height: 320px; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/components/avatar/avatar-group.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps, ISize } from 'daisyui-vue/shared/types/common'; 3 | import { 4 | cloneVNode, 5 | computed, 6 | HTMLAttributes, 7 | PropType, 8 | provide, 9 | reactive, 10 | toRef, 11 | } from 'vue'; 12 | import { ctxAvatarGroupKey, IAvatarGroupCtx, sizeMap } from './state'; 13 | import style from './style'; 14 | import { useTheme } from 'daisyui-vue/shared/ctx'; 15 | 16 | export const avatarGroupProps = { 17 | size: { 18 | type: [Number, String] as PropType, 19 | default: 'md', 20 | }, 21 | gap: { 22 | type: [Number, String] as PropType, 23 | default: void 0, 24 | }, 25 | }; 26 | 27 | export type IAvatarGroupProps = ExtractFromProps; 28 | 29 | export const AvatrGroup = componentV2( 30 | { 31 | name: 'AvatarGroup', 32 | props: avatarGroupProps, 33 | setup: (props, { slots }) => { 34 | const theme = useTheme(); 35 | 36 | provide( 37 | ctxAvatarGroupKey, 38 | reactive({ 39 | size: toRef(props, 'size'), 40 | }), 41 | ); 42 | 43 | const gapValue = computed(() => { 44 | const res = props.gap || sizeMap[props.size!] / 2 || 24; 45 | return typeof res === 'number' ? `-${res}px` : '-' + res; 46 | }); 47 | 48 | return () => ( 49 |
50 | {(slots.default?.() || []).map((v, i) => 51 | cloneVNode(v, { 52 | style: 53 | i === 0 54 | ? {} 55 | : { 56 | marginLeft: gapValue.value, 57 | }, 58 | }), 59 | )} 60 |
61 | ); 62 | }, 63 | }, 64 | style, 65 | ); 66 | -------------------------------------------------------------------------------- /src/components/avatar/avatar.tsx: -------------------------------------------------------------------------------- 1 | import { IMaskType, Mask } from '../mask'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps, ISize } from 'daisyui-vue/shared/types/common'; 4 | import { computed, HTMLAttributes, inject, PropType } from 'vue'; 5 | import style from './style'; 6 | import { ctxAvatarGroupKey, getSizeValue, IAvatarGroupCtx } from './state'; 7 | import { isUndefined } from 'daisyui-vue/shared/utils'; 8 | import { useTheme } from 'daisyui-vue/shared/ctx'; 9 | 10 | export const avatarProps = { 11 | src: String, 12 | placeholder: { 13 | type: String, 14 | default: void 0, 15 | }, 16 | size: { 17 | type: [Number, String] as PropType, 18 | default: 'md', 19 | }, 20 | type: { type: String as PropType, default: 'circle' }, 21 | status: { 22 | type: String as PropType<'online' | 'offline'>, 23 | default: '', 24 | }, 25 | }; 26 | 27 | export type IAvatarProps = ExtractFromProps; 28 | 29 | export const Avatar = componentV2( 30 | { 31 | name: 'Avatar', 32 | props: avatarProps, 33 | setup: (props, { slots }) => { 34 | const theme = useTheme(); 35 | const ctx = inject(ctxAvatarGroupKey, { size: '' }); 36 | const merged = computed(() => ({ 37 | size: ctx.size || props.size, 38 | })); 39 | 40 | const sizeStyle = computed(() => { 41 | const sizeValue = getSizeValue(merged.value.size); 42 | return { 43 | width: sizeValue, 44 | height: sizeValue, 45 | }; 46 | }); 47 | return () => { 48 | const children = slots.default?.(); 49 | const renderPls = () => 50 | props.placeholder ? {props.placeholder} : null; 51 | const renderImg = () => (props.src ? : null); 52 | 53 | return ( 54 |
63 | 64 |
65 | {children || renderImg() || renderPls()} 66 |
67 |
68 |
69 | ); 70 | }; 71 | }, 72 | }, 73 | style, 74 | ); 75 | -------------------------------------------------------------------------------- /src/components/avatar/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './avatar'; 2 | export * from './avatar-group'; 3 | -------------------------------------------------------------------------------- /src/components/avatar/state.ts: -------------------------------------------------------------------------------- 1 | import { ISize } from 'daisyui-vue/shared/types/common'; 2 | import { cssUnit } from 'daisyui-vue/shared/utils'; 3 | 4 | export const ctxAvatarGroupKey = Symbol('AvatarGroup'); 5 | 6 | export const sizeMap: Record = { 7 | xs: 24, 8 | sm: 32, 9 | md: 40, 10 | lg: 64, 11 | }; 12 | 13 | export interface IAvatarGroupCtx { 14 | size?: string | number; 15 | } 16 | 17 | export function getSizeValue(size: string | number = '') { 18 | return cssUnit(sizeMap[size] || size); 19 | } 20 | -------------------------------------------------------------------------------- /src/components/avatar/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-avatar-group { 2 | @apply flex overflow-hidden; 3 | .dv-avatar { 4 | @apply overflow-hidden rounded-full border-4 border-base-100; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/components/avatar/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-avatar { 2 | @apply relative inline-flex; 3 | & > div { 4 | @apply block aspect-square overflow-hidden; 5 | } 6 | img { 7 | @apply h-full w-full object-cover; 8 | } 9 | &.dv-placeholder { 10 | & > div { 11 | @apply flex items-center justify-center; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/avatar/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-s.css'; 4 | 5 | import s from './style.less'; 6 | 7 | export default [s1, s2, s3, s]; 8 | -------------------------------------------------------------------------------- /src/components/avatar/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-avatar { 2 | &-circle { 3 | @apply rounded-full; 4 | } 5 | &.dv-placeholder { 6 | & > .dv-mask { 7 | --tw-text-opacity: 1; 8 | color: hsla(var(--nc) / var(--tw-text-opacity, 1)); 9 | --tw-bg-opacity: 1; 10 | background-color: hsla(var(--nf) / var(--tw-bg-opacity, 1)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/avatar/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-avatar { 2 | &.dv-online { 3 | &:before { 4 | content: ''; 5 | @apply absolute z-10 block rounded-full bg-success; 6 | width: 15%; 7 | height: 15%; 8 | top: 7%; 9 | right: 7%; 10 | box-shadow: 0 0 0 2px hsl(var(--b1)); 11 | } 12 | } 13 | &.dv-offline { 14 | &:before { 15 | content: ''; 16 | @apply absolute z-10 block rounded-full bg-base-300; 17 | width: 15%; 18 | height: 15%; 19 | top: 7%; 20 | right: 7%; 21 | box-shadow: 0 0 0 2px hsl(var(--b1)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/components/badge/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { 3 | ExtractFromProps, 4 | IColorType, 5 | ISize, 6 | } from 'daisyui-vue/shared/types/common'; 7 | import { computed, PropType, HTMLAttributes } from 'vue'; 8 | import style from './style'; 9 | import { useTheme } from 'daisyui-vue/shared/ctx'; 10 | 11 | export const badgeProps = { 12 | outline: { type: Boolean, default: void 0 }, 13 | variant: { 14 | type: String as PropType, 15 | default: 'neutral', 16 | }, 17 | size: { 18 | type: String as PropType, 19 | default: 'md', 20 | }, 21 | }; 22 | 23 | export type IBadgeProps = ExtractFromProps; 24 | 25 | export const Badge = componentV2( 26 | { 27 | name: 'Badge', 28 | props: badgeProps, 29 | setup: (props, { slots }) => { 30 | const size = computed(() => props.size || 'md'); 31 | const outline = computed(() => props.outline || false); 32 | const theme = useTheme(); 33 | 34 | return () => ( 35 |
44 | {slots.default?.()} 45 |
46 | ); 47 | }, 48 | }, 49 | style, 50 | ); 51 | -------------------------------------------------------------------------------- /src/components/badge/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-badge { 2 | @apply inline-flex items-center justify-center transition duration-200 ease-in-out; 3 | @apply h-5 text-sm leading-5; 4 | width: fit-content; 5 | padding-left: 0.563rem; 6 | padding-right: 0.563rem; 7 | } 8 | -------------------------------------------------------------------------------- /src/components/badge/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s from './style.less'; 5 | 6 | export default [s1, s2, s3, s]; 7 | -------------------------------------------------------------------------------- /src/components/badge/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-badge { 2 | white-space: nowrap; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/badge/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-badge { 2 | &-xs { 3 | @apply h-3 text-xs leading-3; 4 | padding-left: 0.313rem; 5 | padding-right: 0.313rem; 6 | } 7 | &-sm { 8 | @apply h-4 text-xs leading-4; 9 | padding-left: 0.438rem; 10 | padding-right: 0.438rem; 11 | } 12 | &-md { 13 | @apply h-5 text-sm leading-5; 14 | padding-left: 0.563rem; 15 | padding-right: 0.563rem; 16 | } 17 | &-lg { 18 | @apply h-6 text-base leading-6; 19 | padding-left: 0.688rem; 20 | padding-right: 0.688rem; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/components/breadcrumb/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { AnchorHTMLAttributes, HTMLAttributes } from 'vue'; 3 | import style from './style'; 4 | import { useTheme } from 'daisyui-vue/shared/ctx'; 5 | 6 | export const Breadcrumb = componentV2<{}, HTMLAttributes>( 7 | { 8 | name: 'Breadcrumb', 9 | setup: (_, { slots }) => { 10 | const theme = useTheme(); 11 | return () => ( 12 |
13 |
    {slots.default?.()}
14 |
15 | ); 16 | }, 17 | }, 18 | style, 19 | ); 20 | 21 | export const BreadcrumbItem = componentV2<{}, AnchorHTMLAttributes>({ 22 | name: 'BreadcrumbItem', 23 | inheritAttrs: false, 24 | setup: (_, { attrs, slots }) => { 25 | return () => ( 26 |
  • 27 | {slots.default?.()} 28 |
  • 29 | ); 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /src/components/breadcrumb/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-breadcrumbs { 2 | @apply py-2; 3 | & > ul { 4 | & > li { 5 | & > a { 6 | &:focus { 7 | @apply outline-none; 8 | } 9 | &:focus-visible { 10 | outline: 2px solid currentColor; 11 | outline-offset: 2px; 12 | } 13 | } 14 | & + *:before { 15 | content: ''; 16 | @apply ml-2 mr-3 block h-1.5 w-1.5 rotate-45 transform opacity-40; 17 | border-top: 1px solid; 18 | border-right: 1px solid; 19 | background-color: transparent; 20 | } 21 | } 22 | } 23 | } 24 | 25 | [dir='rtl'] .dv-breadcrumbs > ul > li + *:before { 26 | --tw-rotate: -45deg; 27 | } 28 | -------------------------------------------------------------------------------- /src/components/breadcrumb/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-breadcrumbs { 2 | @apply max-w-full overflow-x-auto; 3 | & > ul { 4 | @apply flex items-center whitespace-nowrap; 5 | min-height: min-content; 6 | & > li { 7 | @apply flex items-center; 8 | & > a { 9 | @apply flex cursor-pointer items-center hover:underline; 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/breadcrumb/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s from './style.less'; 4 | 5 | export default [s1, s2, s]; 6 | -------------------------------------------------------------------------------- /src/components/breadcrumb/style/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daief/daisyui-vue/8150491449dc47467bf1dad98c9789e29dd5f127/src/components/breadcrumb/style/style.less -------------------------------------------------------------------------------- /src/components/button/button-group.tsx: -------------------------------------------------------------------------------- 1 | import { ExtractFromProps, ISize } from 'daisyui-vue/shared/types/common'; 2 | import { computed, HTMLAttributes, PropType, provide } from 'vue'; 3 | import { ctxKey, ICtx } from './state'; 4 | import { IButtonShape } from './button'; 5 | import { componentV2 } from 'daisyui-vue/shared/styled'; 6 | import style from './style'; 7 | import { Join } from '../join'; 8 | 9 | export const buttonGroupProps = { 10 | outline: Boolean, 11 | size: { 12 | type: String as PropType, 13 | default: 'md', 14 | }, 15 | shape: { 16 | type: String as PropType, 17 | }, 18 | }; 19 | 20 | export type IButtonGroupProps = ExtractFromProps; 21 | 22 | export const ButtonGroup = componentV2( 23 | { 24 | name: 'ButtonGroup', 25 | props: buttonGroupProps, 26 | setup: (props, { slots }) => { 27 | const ctxVal = computed(() => ({ 28 | size: props.size || 'md', 29 | shape: props.shape || 'defalut', 30 | outline: props.outline!, 31 | })); 32 | 33 | provide(ctxKey, ctxVal); 34 | 35 | return () => {slots.default?.()}; 36 | }, 37 | }, 38 | style, 39 | ); 40 | -------------------------------------------------------------------------------- /src/components/button/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './button'; 2 | export * from './button-group'; 3 | -------------------------------------------------------------------------------- /src/components/button/state.ts: -------------------------------------------------------------------------------- 1 | import { ISize } from '../../shared/types/common'; 2 | import { IButtonShape } from './button'; 3 | 4 | export const ctxKey = Symbol('ButtonGroup'); 5 | 6 | export interface ICtx { 7 | size: ISize; 8 | shape: IButtonShape; 9 | outline: boolean; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/button/style/c-us.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | @apply inline-flex flex-shrink-0 cursor-pointer select-none flex-wrap items-center justify-center border-transparent text-center transition duration-200 ease-in-out rounded-btn; 3 | @apply h-12 px-4 text-sm min-h-12; 4 | line-height: 1em; 5 | 6 | /* disabled */ 7 | &-disabled, 8 | &[disabled], 9 | &:disabled { 10 | @apply pointer-events-none; 11 | } 12 | 13 | /* shapes */ 14 | &-square { 15 | @apply h-12 w-12 p-0; 16 | } 17 | &-circle { 18 | @apply h-12 w-12 rounded-full p-0; 19 | } 20 | } 21 | 22 | /* group */ 23 | .btn-group { 24 | @apply inline-flex; 25 | & > input[type="radio"].btn { 26 | @apply appearance-none; 27 | } 28 | & > input[type="radio"].btn:before { 29 | content: attr(data-title); 30 | } 31 | } 32 | 33 | /* radio input and checkbox as button */ 34 | .btn:is(input[type="checkbox"]), 35 | .btn:is(input[type="radio"]) { 36 | @apply appearance-none; 37 | } 38 | .btn:is(input[type="checkbox"]):after, 39 | .btn:is(input[type="radio"]):after { 40 | @apply content-[attr(aria-label)]; 41 | } 42 | -------------------------------------------------------------------------------- /src/components/button/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | 4 | import s3 from './u-us.css'; 5 | import s4 from './u-s.css'; 6 | 7 | export default [s1, s2, s3, s4]; 8 | -------------------------------------------------------------------------------- /src/components/button/style/u-s.css: -------------------------------------------------------------------------------- 1 | /* group */ 2 | .btn-group { 3 | .btn:not(:first-child):not(:last-child) { 4 | border-top-left-radius: 0; 5 | border-top-right-radius: 0; 6 | border-bottom-left-radius: 0; 7 | border-bottom-right-radius: 0; 8 | } 9 | .btn:first-child:not(:last-child) { 10 | @apply -mt-0 -ml-px; 11 | border-top-left-radius: var(--rounded-btn, 0.5rem); 12 | border-top-right-radius: 0; 13 | border-bottom-left-radius: var(--rounded-btn, 0.5rem); 14 | border-bottom-right-radius: 0; 15 | } 16 | .btn:last-child:not(:first-child) { 17 | border-top-left-radius: 0; 18 | border-top-right-radius: var(--rounded-btn, 0.5rem); 19 | border-bottom-left-radius: 0; 20 | border-bottom-right-radius: var(--rounded-btn, 0.5rem); 21 | } 22 | &-horizontal { 23 | .btn:not(:first-child):not(:last-child) { 24 | border-top-left-radius: 0; 25 | border-top-right-radius: 0; 26 | border-bottom-left-radius: 0; 27 | border-bottom-right-radius: 0; 28 | } 29 | .btn:first-child:not(:last-child) { 30 | @apply -mt-0 -ml-px; 31 | border-top-left-radius: var(--rounded-btn, 0.5rem); 32 | border-top-right-radius: 0; 33 | border-bottom-left-radius: var(--rounded-btn, 0.5rem); 34 | border-bottom-right-radius: 0; 35 | } 36 | .btn:last-child:not(:first-child) { 37 | border-top-left-radius: 0; 38 | border-top-right-radius: var(--rounded-btn, 0.5rem); 39 | border-bottom-left-radius: 0; 40 | border-bottom-right-radius: var(--rounded-btn, 0.5rem); 41 | } 42 | } 43 | &-vertical { 44 | .btn:first-child:not(:last-child) { 45 | @apply -mt-px -ml-0; 46 | border-top-left-radius: var(--rounded-btn, 0.5rem); 47 | border-top-right-radius: var(--rounded-btn, 0.5rem); 48 | border-bottom-left-radius: 0; 49 | border-bottom-right-radius: 0; 50 | } 51 | .btn:last-child:not(:first-child) { 52 | border-top-left-radius: 0; 53 | border-top-right-radius: 0; 54 | border-bottom-left-radius: var(--rounded-btn, 0.5rem); 55 | border-bottom-right-radius: var(--rounded-btn, 0.5rem); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/button/style/u-us.css: -------------------------------------------------------------------------------- 1 | .btn { 2 | &-xs { 3 | @apply h-6 px-2 min-h-6; 4 | font-size: 0.75rem; 5 | } 6 | &-sm { 7 | @apply h-8 px-3 min-h-8; 8 | font-size: 0.875rem; 9 | } 10 | &-md { 11 | @apply h-12 px-4 min-h-12; 12 | font-size: 0.875rem; 13 | } 14 | &-lg { 15 | @apply h-16 px-6 min-h-16; 16 | font-size: 1.125rem; 17 | } 18 | &-wide { 19 | @apply w-64; 20 | } 21 | &-block { 22 | @apply w-full; 23 | } 24 | &-square { 25 | &:where(.btn-xs) { 26 | @apply h-6 w-6 p-0; 27 | } 28 | &:where(.btn-sm) { 29 | @apply h-8 w-8 p-0; 30 | } 31 | &:where(.btn-md) { 32 | @apply h-12 w-12 p-0; 33 | } 34 | &:where(.btn-lg) { 35 | @apply h-16 w-16 p-0; 36 | } 37 | } 38 | &-circle { 39 | &:where(.btn-xs) { 40 | @apply h-6 w-6 rounded-full p-0; 41 | } 42 | &:where(.btn-sm) { 43 | @apply h-8 w-8 rounded-full p-0; 44 | } 45 | &:where(.btn-md) { 46 | @apply h-12 w-12 rounded-full p-0; 47 | } 48 | &:where(.btn-lg) { 49 | @apply h-16 w-16 rounded-full p-0; 50 | } 51 | } 52 | } 53 | 54 | /* group */ 55 | .btn-group-horizontal { 56 | @apply flex-row; 57 | } 58 | .btn-group-vertical { 59 | @apply flex-col; 60 | } 61 | -------------------------------------------------------------------------------- /src/components/card/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-card { 2 | @apply rounded-box; 3 | &:focus-visible { 4 | outline: 2px solid currentColor; 5 | outline-offset: 2px; 6 | } 7 | &.dv-bordered { 8 | @apply border border-base-200; 9 | } 10 | &-bordered { 11 | @apply border border-base-200; 12 | } 13 | &.dv-compact { 14 | .card-body { 15 | @apply p-4 text-sm; 16 | } 17 | } 18 | &-body { 19 | padding: var(--padding-card, 2rem); 20 | @apply flex flex-col gap-2; 21 | } 22 | &-title { 23 | @apply flex items-center gap-2 text-xl font-semibold; 24 | } 25 | &.dv-image-full { 26 | &:before { 27 | @apply z-10 bg-neutral opacity-75 rounded-box; 28 | } 29 | } 30 | &.dv-image-full > &-body { 31 | @apply z-20 text-neutral-content; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/components/card/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-card { 2 | @apply relative flex flex-col overflow-hidden; 3 | &:focus { 4 | @apply outline-none; 5 | } 6 | &-body { 7 | @apply flex flex-auto flex-col; 8 | :where(p) { 9 | @apply flex-grow; 10 | } 11 | } 12 | &-actions { 13 | @apply flex flex-wrap items-start gap-2; 14 | } 15 | & figure { 16 | @apply flex items-center justify-center; 17 | } 18 | &.dv-image-full { 19 | @apply grid; 20 | &:before { 21 | @apply relative; 22 | content: ''; 23 | } 24 | &:before, 25 | & > * { 26 | @apply col-start-1 row-start-1; 27 | } 28 | & > figure img { 29 | @apply h-full object-cover; 30 | } 31 | } 32 | &.dv-image-full > &-body { 33 | @apply relative; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/card/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from './u-s.css'; 5 | export default [s1, s2, s3, s4]; 6 | -------------------------------------------------------------------------------- /src/components/card/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-card-compact { 2 | .dv-card-body { 3 | @apply p-4 text-sm; 4 | } 5 | .dv-card-title { 6 | @apply mb-1; 7 | } 8 | } 9 | .dv-card-normal { 10 | .dv-card-body { 11 | padding: var(--padding-card, 2rem); 12 | @apply text-base; 13 | } 14 | .dv-card-title { 15 | @apply mb-3; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/components/card/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-card-side { 2 | align-items: stretch; 3 | flex-direction: row; 4 | & figure > * { 5 | max-width: unset; 6 | } 7 | } 8 | :where(.dv-card-side figure > *) { 9 | width: 100%; 10 | height: 100%; 11 | object-fit: cover; 12 | } 13 | -------------------------------------------------------------------------------- /src/components/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkbox'; 2 | export * from './group'; 3 | -------------------------------------------------------------------------------- /src/components/checkbox/state.tsx: -------------------------------------------------------------------------------- 1 | import { ISize, IText } from 'daisyui-vue/shared/types/common'; 2 | 3 | export interface ICheckboxContext { 4 | value: IText[]; 5 | size: ISize; 6 | disabled: boolean; 7 | onChange: (value: IText) => void; 8 | register: (value: IText) => void; 9 | cancel: (value: IText) => void; 10 | } 11 | 12 | export const checkboxCtxKey = Symbol('CheckboxGroup'); 13 | -------------------------------------------------------------------------------- /src/components/checkbox/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-checkbox { 2 | --chkbg: var(--bc); 3 | --chkfg: var(--b1); 4 | @apply h-6 w-6 cursor-pointer appearance-none border border-solid border-base-content border-opacity-20 rounded-btn; 5 | &:focus-visible { 6 | outline: 2px solid hsl(var(--bc)); 7 | outline-offset: 2px; 8 | } 9 | 10 | &-primary { 11 | --chkbg: var(--p); 12 | --chkfg: var(--pc); 13 | @apply border-primary hover:border-primary; 14 | &:focus-visible { 15 | outline: 2px solid hsl(var(--p)); 16 | } 17 | &:checked, 18 | &[checked='true'], 19 | &[aria-checked='true'] { 20 | @apply border-primary bg-primary text-primary-content; 21 | } 22 | } 23 | &-secondary { 24 | --chkbg: var(--s); 25 | --chkfg: var(--sc); 26 | @apply border-secondary hover:border-secondary; 27 | &:focus-visible { 28 | outline: 2px solid hsl(var(--s)); 29 | } 30 | &:checked, 31 | &[checked='true'], 32 | &[aria-checked='true'] { 33 | @apply border-secondary bg-secondary text-secondary-content; 34 | } 35 | } 36 | &-accent { 37 | --chkbg: var(--a); 38 | --chkfg: var(--ac); 39 | @apply border-accent hover:border-accent; 40 | &:focus-visible { 41 | outline: 2px solid hsl(var(--a)); 42 | } 43 | &:checked, 44 | &[checked='true'], 45 | &[aria-checked='true'] { 46 | @apply border-accent bg-accent text-accent-content; 47 | } 48 | } 49 | &:disabled { 50 | @apply cursor-not-allowed border-transparent bg-base-content opacity-20; 51 | } 52 | } 53 | 54 | @keyframes checkmark { 55 | 0% { 56 | background-position-y: 5px; 57 | } 58 | 50% { 59 | background-position-y: -2px; 60 | } 61 | 100% { 62 | background-position-y: 0; 63 | } 64 | } 65 | 66 | body[dir='rtl'] { 67 | .dv-checkbox { 68 | --chkbg: var(--bc); 69 | --chkfg: var(--b1); 70 | &:checked, 71 | &[checked='true'], 72 | &[aria-checked='true'] { 73 | background-image: linear-gradient( 74 | 45deg, 75 | transparent 65%, 76 | hsl(var(--chkbg)) 65.99% 77 | ), 78 | linear-gradient(-45deg, transparent 75%, hsl(var(--chkbg)) 75.99%), 79 | linear-gradient(45deg, hsl(var(--chkbg)) 40%, transparent 40.99%), 80 | linear-gradient( 81 | -45deg, 82 | hsl(var(--chkbg)) 30%, 83 | hsl(var(--chkfg)) 30.99%, 84 | hsl(var(--chkfg)) 40%, 85 | transparent 40.99% 86 | ), 87 | linear-gradient(45deg, hsl(var(--chkfg)) 50%, hsl(var(--chkbg)) 50.99%); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/components/checkbox/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-checkbox { 2 | @apply shrink-0; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/checkbox/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from 'daisyui-vue/components/_styles/common/checkbox-radio.less'; 5 | import s from './style.less'; 6 | 7 | export default [s1, s2, s3, s4, s]; 8 | -------------------------------------------------------------------------------- /src/components/checkbox/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-checkbox { 2 | &-indeterminate { 3 | @apply bg-base-content bg-no-repeat; 4 | animation: checkmark var(--animation-input, 0.2s) ease-in-out; 5 | background-image: linear-gradient( 6 | 90deg, 7 | transparent 80%, 8 | hsl(var(--chkbg)) 80% 9 | ), 10 | linear-gradient(-90deg, transparent 80%, hsl(var(--chkbg)) 80%), 11 | linear-gradient( 12 | 0deg, 13 | hsl(var(--chkbg)) 43%, 14 | hsl(var(--chkfg)) 43%, 15 | hsl(var(--chkfg)) 57%, 16 | hsl(var(--chkbg)) 57% 17 | ); 18 | } 19 | &:not(&-indeterminate) { 20 | &:checked, 21 | &[checked='true'], 22 | &[aria-checked='true'] { 23 | @apply bg-base-content bg-no-repeat; 24 | animation: checkmark var(--animation-input, 0.2s) ease-in-out; 25 | background-image: linear-gradient( 26 | -45deg, 27 | transparent 65%, 28 | hsl(var(--chkbg)) 65.99% 29 | ), 30 | linear-gradient(45deg, transparent 75%, hsl(var(--chkbg)) 75.99%), 31 | linear-gradient(-45deg, hsl(var(--chkbg)) 40%, transparent 40.99%), 32 | linear-gradient( 33 | 45deg, 34 | hsl(var(--chkbg)) 30%, 35 | hsl(var(--chkfg)) 30.99%, 36 | hsl(var(--chkfg)) 40%, 37 | transparent 40.99% 38 | ), 39 | linear-gradient(-45deg, hsl(var(--chkfg)) 50%, hsl(var(--chkbg)) 50.99%); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/components/checkbox/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-checkbox { 2 | &-xs { 3 | @apply h-4 w-4; 4 | } 5 | &-sm { 6 | @apply h-5 w-5; 7 | } 8 | &-md { 9 | @apply h-6 w-6; 10 | } 11 | &-lg { 12 | @apply h-8 w-8; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/counter/style/index.ts: -------------------------------------------------------------------------------- 1 | import s from './style.less'; 2 | 3 | export default [s]; 4 | -------------------------------------------------------------------------------- /src/components/counter/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-counter { 2 | line-height: 1em; 3 | & > * { 4 | height: 1em; 5 | @apply inline-block overflow-y-hidden; 6 | } 7 | & > .dv-counter-number { 8 | &:before { 9 | transition: all 0s cubic-bezier(1, 0, 0, 1); 10 | transition-duration: var(--t-d); 11 | position: relative; 12 | content: '0\A 1\A 2\A 3\A 4\A 5\A 6\A 7\A 8\A 9\A'; 13 | white-space: pre; 14 | top: calc(var(--value) * -1em); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/components/divider/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { computed, HtmlHTMLAttributes } from 'vue'; 4 | import style from './style'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | const props = { 8 | horizontal: { 9 | type: Boolean, 10 | default: false, 11 | }, 12 | }; 13 | 14 | export type IDividerProps = ExtractFromProps; 15 | 16 | export const Divider = componentV2( 17 | { 18 | name: 'Divider', 19 | props, 20 | setup: (props, { slots }) => { 21 | const theme = useTheme(); 22 | const cls = computed(() => ({ 23 | [theme.className]: true, 24 | 'dv-divider': true, 25 | 'dv-divider-horizontal': props.horizontal, 26 | })); 27 | return () =>
    {slots.default?.()}
    ; 28 | }, 29 | }, 30 | style, 31 | ); 32 | -------------------------------------------------------------------------------- /src/components/divider/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-divider { 2 | @apply my-4 h-4 whitespace-nowrap; 3 | &:before { 4 | @apply bg-base-content bg-opacity-10; 5 | } 6 | &:after { 7 | @apply bg-base-content bg-opacity-10; 8 | } 9 | &:not(:empty) { 10 | @apply gap-4; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/components/divider/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-divider { 2 | @apply flex flex-row items-center self-stretch; 3 | &:before, 4 | &:after { 5 | content: ''; 6 | @apply flex-grow; 7 | @apply h-0.5 w-full; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/components/divider/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from './u-s.css'; 5 | export default [s1, s2, s3, s4]; 6 | -------------------------------------------------------------------------------- /src/components/divider/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-divider-horizontal { 2 | @apply my-0 mx-4 h-auto w-4; 3 | } 4 | .dv-divider-vertical { 5 | @apply mx-0 my-4 h-4 w-auto; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/divider/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-divider-horizontal { 2 | @apply flex-col; 3 | &:before { 4 | @apply h-full w-0.5; 5 | } 6 | &:after { 7 | @apply h-full w-0.5; 8 | } 9 | } 10 | .dv-divider-vertical { 11 | @apply flex-row; 12 | &:before { 13 | @apply h-0.5 w-full; 14 | } 15 | &:after { 16 | @apply h-0.5 w-full; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/drawer/drawer.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { getRenderResult } from 'daisyui-vue/shared/utils'; 4 | import { PropType, computed, Transition } from 'vue'; 5 | import { ModalBase } from '../modal'; 6 | import style from './style'; 7 | import { useTheme } from 'daisyui-vue/shared/ctx'; 8 | 9 | export const drawerProps = { 10 | open: Boolean, 11 | disableTeleport: Boolean, 12 | flattern: Boolean, 13 | placement: { 14 | type: String as PropType<'left' | 'right'>, 15 | default: 'left', 16 | }, 17 | onClose: { 18 | type: Function as PropType, 19 | }, 20 | }; 21 | 22 | export type IDrawerProps = ExtractFromProps; 23 | 24 | export const Drawer = componentV2( 25 | { 26 | name: 'Drawer', 27 | props: drawerProps, 28 | setup: (props, { slots }) => { 29 | const theme = useTheme(); 30 | 31 | const clsStatus = computed(() => ({ 32 | 'dv-drawer-side-parent': true, 33 | 'dv-drawer-end': props.placement === 'right', 34 | 'dv-drawer--open': props.open, 35 | [`dv-drawer--flattern-${props.flattern ? 'on' : 'off'}`]: true, 36 | })); 37 | 38 | const rootCls = computed(() => [ 39 | theme.className, 40 | 'dv-drawer', 41 | clsStatus.value, 42 | ]); 43 | 44 | const overlayCls = computed(() => ['dv-drawer-overlay', clsStatus.value]); 45 | 46 | return () => { 47 | const transitionName = 48 | (props.placement === 'right' ? '-' : '') + 'dv-t-translate-x'; 49 | 50 | const contentNode = () => getRenderResult('content', props, slots); 51 | const defaultNode = () => slots.default?.(); 52 | const sideNode = () => ( 53 |
    {defaultNode()}
    54 | ); 55 | 56 | const showSideDirectly = props.flattern; 57 | 58 | return ( 59 |
    60 |
    {contentNode()}
    61 | 62 | {showSideDirectly ? sideNode() : null} 63 | 64 | {!showSideDirectly && ( 65 | 72 | )} 73 |
    74 | ); 75 | }; 76 | }, 77 | }, 78 | style, 79 | ); 80 | -------------------------------------------------------------------------------- /src/components/drawer/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './drawer'; 2 | -------------------------------------------------------------------------------- /src/components/drawer/style/index.ts: -------------------------------------------------------------------------------- 1 | // self hosted style 2 | import s from './style.less'; 3 | 4 | export default [s]; 5 | -------------------------------------------------------------------------------- /src/components/dropdown/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { Popper, popperProps } from '../popper'; 4 | import styles from './style'; 5 | 6 | export const dropdownProps = { 7 | ...popperProps, 8 | placement: { 9 | ...popperProps.placement, 10 | default: 'bottom', 11 | }, 12 | }; 13 | 14 | export type IDropdownProps = ExtractFromProps; 15 | 16 | export const Dropdown = componentV2( 17 | { 18 | name: 'Dropdown', 19 | props: dropdownProps, 20 | setup: (props, { slots }) => { 21 | return () => ( 22 | 23 | ); 24 | }, 25 | }, 26 | styles, 27 | ); 28 | -------------------------------------------------------------------------------- /src/components/dropdown/style/index.ts: -------------------------------------------------------------------------------- 1 | import s from './style.less'; 2 | 3 | export default [s]; 4 | -------------------------------------------------------------------------------- /src/components/dropdown/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-popper-node.dv-dropdown { 2 | --popper-tail-offset: 4px; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/icon/icon.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { cssUnit } from 'daisyui-vue/shared/utils'; 4 | import { HTMLAttributes, cloneVNode, PropType, h, DefineComponent } from 'vue'; 5 | import style from './style'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const iconProps = { 9 | color: { 10 | type: String, 11 | default: 'currentColor', 12 | }, 13 | size: { 14 | type: [Number, String] as PropType, 15 | }, 16 | tag: { 17 | type: String, 18 | default: 'span', 19 | }, 20 | }; 21 | 22 | export type IIconProps = ExtractFromProps; 23 | 24 | export type IconComponent = DefineComponent; 25 | 26 | export const Icon: IconComponent = componentV2( 27 | { 28 | name: 'Icon', 29 | props: iconProps, 30 | setup: (props, { slots }) => { 31 | const theme = useTheme(); 32 | return () => { 33 | const child = slots.default?.()[0]; 34 | return h( 35 | props.tag!, 36 | { 37 | class: theme.className + ' dv-icon', 38 | style: { 39 | fontSize: cssUnit(props.size!), 40 | color: props.color, 41 | }, 42 | }, 43 | [ 44 | child 45 | ? cloneVNode(child, { 46 | focusable: false, 47 | ariaHidden: false, 48 | }) 49 | : null, 50 | ], 51 | ); 52 | }; 53 | }, 54 | }, 55 | style, 56 | ); 57 | -------------------------------------------------------------------------------- /src/components/icon/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './icon'; 2 | export * from './icons'; 3 | -------------------------------------------------------------------------------- /src/components/icon/style/index.ts: -------------------------------------------------------------------------------- 1 | import s from './style.less'; 2 | 3 | export default [s]; 4 | -------------------------------------------------------------------------------- /src/components/icon/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-icon { 2 | display: inline-block; 3 | flex-shrink: 0; 4 | font-style: normal; 5 | line-height: 0; 6 | text-align: center; 7 | text-transform: none; 8 | vertical-align: middle; 9 | text-rendering: optimizeLegibility; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | width: 1em; 13 | height: 1em; 14 | overflow: hidden; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './alert'; 2 | export * from './artboard'; 3 | export * from './avatar'; 4 | export * from './avatar'; 5 | export * from './badge'; 6 | export * from './breadcrumb'; 7 | export * from './button'; 8 | export * from './card'; 9 | export * from './checkbox'; 10 | export * from './counter'; 11 | export * from './divider'; 12 | export * from './drawer'; 13 | export * from './dropdown'; 14 | export * from './icon'; 15 | export * from './indicator'; 16 | export * from './input'; 17 | export * from './join'; 18 | export * from './kbd'; 19 | export * from './link'; 20 | export * from './loading'; 21 | export * from './mask'; 22 | export * from './menu'; 23 | export * from './modal'; 24 | export * from './navbar'; 25 | export * from './pagination'; 26 | export * from './popper'; 27 | export * from './progress'; 28 | export * from './radio'; 29 | export * from './space'; 30 | export * from './swap'; 31 | export * from './tab'; 32 | export * from './table'; 33 | export * from './textarea'; 34 | export * from './toggle'; 35 | export * from './tooltip'; 36 | 37 | export * from './_widgets/raw'; 38 | export { ThemeProvider } from './_widgets/theme'; 39 | -------------------------------------------------------------------------------- /src/components/indicator/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import styles from './style'; 3 | import { computed, createVNode, DefineComponent, PropType } from 'vue'; 4 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | export const indicatorProps = { 8 | tag: { 9 | type: [String, Object] as PropType, 10 | default: 'div', 11 | }, 12 | }; 13 | 14 | export type IIndicatorProps = ExtractFromProps; 15 | 16 | export const Indicator = componentV2( 17 | { 18 | name: 'Indicator', 19 | props: indicatorProps, 20 | setup: (props, { slots }) => { 21 | const theme = useTheme(); 22 | return () => { 23 | // TODO warning 24 | // Non-function value encountered for default slot. Prefer function slots for better performance. 25 | const Component = props.tag || 'div'; 26 | return ( 27 | 31 | ); 32 | }; 33 | }, 34 | }, 35 | styles, 36 | ); 37 | 38 | export const indicatorItemProps = { 39 | tag: { 40 | type: [String, Object] as PropType, 41 | default: 'div', 42 | }, 43 | placement: { 44 | type: String as PropType<`${'top' | 'middle' | 'bottom'}-${ 45 | | 'start' 46 | | 'center' 47 | | 'end'}`>, 48 | default: 'start-end', 49 | }, 50 | }; 51 | 52 | export type IIndicatorItemProps = ExtractFromProps; 53 | 54 | export const IndicatorItem = componentV2( 55 | { 56 | name: 'IndicatorItem', 57 | props: indicatorItemProps, 58 | setup: (props, { slots }) => { 59 | const theme = useTheme(); 60 | const propsPassed = computed(() => { 61 | const [v, h] = props.placement!.split('-'); 62 | return { 63 | class: [ 64 | theme.className, 65 | 'dv-indicator-item', 66 | { 67 | [`dv-indicator-${h}`]: true, 68 | [`dv-indicator-${v}`]: true, 69 | }, 70 | ], 71 | }; 72 | }); 73 | return () => { 74 | const children = slots.default?.(); 75 | return createVNode(props.tag || 'div', propsPassed.value, children); 76 | }; 77 | }, 78 | }, 79 | styles, 80 | ); 81 | -------------------------------------------------------------------------------- /src/components/indicator/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-indicator { 2 | @apply relative inline-flex; 3 | width: max-content; 4 | & :where(.dv-indicator-item) { 5 | z-index: 1; 6 | @apply absolute transform; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/components/indicator/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './u-us.css'; 3 | import s from './style.less'; 4 | export default [s1, s2, s]; 5 | -------------------------------------------------------------------------------- /src/components/indicator/style/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daief/daisyui-vue/8150491449dc47467bf1dad98c9789e29dd5f127/src/components/indicator/style/style.less -------------------------------------------------------------------------------- /src/components/indicator/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-indicator { 2 | & :where(.dv-indicator-item) { 3 | @apply right-0 left-auto top-0 bottom-auto translate-x-1/2 -translate-y-1/2; 4 | } 5 | & :where(.dv-indicator-item.dv-indicator-start) { 6 | @apply right-auto left-0 -translate-x-1/2; 7 | } 8 | & :where(.dv-indicator-item.dv-indicator-center) { 9 | @apply right-1/2 left-1/2 -translate-x-1/2; 10 | } 11 | & :where(.dv-indicator-item.dv-indicator-end) { 12 | @apply right-0 left-auto translate-x-1/2; 13 | } 14 | & :where(.dv-indicator-item.dv-indicator-bottom) { 15 | @apply top-auto bottom-0 translate-y-1/2; 16 | } 17 | & :where(.dv-indicator-item.dv-indicator-middle) { 18 | @apply top-1/2 bottom-1/2 -translate-y-1/2; 19 | } 20 | & :where(.dv-indicator-item.dv-indicator-top) { 21 | @apply top-0 bottom-auto -translate-y-1/2; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/input/index.tsx: -------------------------------------------------------------------------------- 1 | import { InputChangeEvent } from 'daisyui-vue/@types/dom'; 2 | import { 3 | colorVariantWithGhostProps, 4 | V_MODEL_EVENT, 5 | } from 'daisyui-vue/shared/constants'; 6 | import { componentV2 } from 'daisyui-vue/shared/styled'; 7 | import { ExtractFromProps, ISize } from 'daisyui-vue/shared/types/common'; 8 | import { computed, InputHTMLAttributes, PropType } from 'vue'; 9 | import styles from './style'; 10 | import { useTheme } from 'daisyui-vue/shared/ctx'; 11 | 12 | export const inputProps = { 13 | border: { 14 | type: Boolean, 15 | default: true, 16 | }, 17 | ...colorVariantWithGhostProps, 18 | size: { 19 | type: String as PropType, 20 | default: 'md', 21 | }, 22 | modelValue: { 23 | type: String, 24 | default: '', 25 | }, 26 | }; 27 | 28 | export type IInputProps = ExtractFromProps; 29 | 30 | export const Input = componentV2( 31 | { 32 | name: 'Input', 33 | props: inputProps, 34 | emits: [V_MODEL_EVENT], 35 | setup: (props, { emit }) => { 36 | const theme = useTheme(); 37 | const cls = computed(() => ({ 38 | [theme.className]: true, 39 | 'dv-input': true, 40 | 'dv-input-bordered': props.border, 41 | [`dv-input-${props.variant}`]: !!props.variant, 42 | [`dv-input-${props.size}`]: !!props.size, 43 | })); 44 | 45 | const handleOnInput = (e: InputChangeEvent) => { 46 | emit(V_MODEL_EVENT, e.target.value); 47 | }; 48 | 49 | return () => ( 50 | 57 | ); 58 | }, 59 | }, 60 | styles, 61 | ); 62 | -------------------------------------------------------------------------------- /src/components/input/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-input { 2 | @apply border border-base-content border-opacity-0 bg-base-100 rounded-btn; 3 | &[list]::-webkit-calendar-picker-indicator { 4 | line-height: 1em; 5 | } 6 | &-bordered { 7 | @apply border-opacity-20; 8 | } 9 | &:focus { 10 | outline: 2px solid hsla(var(--bc) / 0.2); 11 | outline-offset: 2px; 12 | } 13 | &-ghost { 14 | @apply bg-opacity-5; 15 | &:focus { 16 | @apply bg-opacity-100 text-base-content; 17 | box-shadow: none; 18 | } 19 | } 20 | &-primary { 21 | @apply border-primary; 22 | &:focus { 23 | outline: 2px solid hsl(var(--p)); 24 | } 25 | } 26 | &-secondary { 27 | @apply border-secondary; 28 | &:focus { 29 | outline: 2px solid hsl(var(--s)); 30 | } 31 | } 32 | &-accent { 33 | @apply border-accent; 34 | &:focus { 35 | outline: 2px solid hsl(var(--a)); 36 | } 37 | } 38 | &-info { 39 | @apply border-info; 40 | &:focus { 41 | outline: 2px solid hsl(var(--in)); 42 | } 43 | } 44 | &-success { 45 | @apply border-success; 46 | &:focus { 47 | outline: 2px solid hsl(var(--su)); 48 | } 49 | } 50 | &-warning { 51 | @apply border-warning; 52 | &:focus { 53 | outline: 2px solid hsl(var(--wa)); 54 | } 55 | } 56 | &-error { 57 | @apply border-error; 58 | &:focus { 59 | outline: 2px solid hsl(var(--er)); 60 | } 61 | } 62 | &-disabled, 63 | &[disabled] { 64 | @apply cursor-not-allowed border-base-200 bg-base-200 text-opacity-20 placeholder-base-content placeholder-opacity-20; 65 | } 66 | /* &::-webkit-calendar-picker-indicator { 67 | display: none; 68 | } */ 69 | } 70 | -------------------------------------------------------------------------------- /src/components/input/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-input { 2 | @apply flex-shrink transition duration-200 ease-in-out; 3 | @apply h-12 px-4 text-sm leading-loose; 4 | } 5 | .dv-input-group { 6 | @apply flex w-full items-stretch; 7 | > .dv-input { 8 | @apply isolate; 9 | } 10 | > *, 11 | > .dv-input { 12 | @apply rounded-none; 13 | } 14 | &-md { 15 | @apply text-sm leading-loose; 16 | } 17 | &-lg { 18 | @apply text-lg leading-loose; 19 | } 20 | &-sm { 21 | @apply text-sm leading-8; 22 | } 23 | &-xs { 24 | @apply text-xs leading-relaxed; 25 | } 26 | :where(span) { 27 | @apply flex items-center bg-base-300 px-4; 28 | } 29 | :first-child { 30 | border-top-left-radius: var(--rounded-btn, 0.5rem); 31 | border-top-right-radius: 0; 32 | border-bottom-left-radius: var(--rounded-btn, 0.5rem); 33 | border-bottom-right-radius: 0; 34 | } 35 | :last-child { 36 | border-top-left-radius: 0; 37 | border-top-right-radius: var(--rounded-btn, 0.5rem); 38 | border-bottom-left-radius: 0; 39 | border-bottom-right-radius: var(--rounded-btn, 0.5rem); 40 | } 41 | &-vertical { 42 | @apply flex-col; 43 | :first-child { 44 | border-top-left-radius: var(--rounded-btn, 0.5rem); 45 | border-top-right-radius: var(--rounded-btn, 0.5rem); 46 | border-bottom-left-radius: 0; 47 | border-bottom-right-radius: 0; 48 | } 49 | :last-child { 50 | border-top-left-radius: 0; 51 | border-top-right-radius: 0; 52 | border-bottom-left-radius: var(--rounded-btn, 0.5rem); 53 | border-bottom-right-radius: var(--rounded-btn, 0.5rem); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/components/input/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | export default [s1, s2, s3]; 5 | -------------------------------------------------------------------------------- /src/components/input/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-input { 2 | &-md { 3 | @apply h-12 px-4 text-sm leading-loose; 4 | } 5 | &-lg { 6 | @apply h-16 px-6 text-lg leading-loose; 7 | } 8 | &-sm { 9 | @apply h-8 px-3 text-sm leading-8; 10 | } 11 | &-xs { 12 | @apply h-6 px-2 text-xs leading-relaxed; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/join/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import styles from './styles'; 3 | import { flatUntilNotFragment } from 'daisyui-vue/shared/utils'; 4 | import { HTMLAttributes, cloneVNode, computed, isVNode } from 'vue'; 5 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const joinProps = { 9 | vertical: Boolean, 10 | }; 11 | 12 | export type IJoinProps = ExtractFromProps; 13 | 14 | export const Join = componentV2( 15 | { 16 | name: 'Join', 17 | props: joinProps, 18 | setup: (props, { slots }) => { 19 | const theme = useTheme(); 20 | const cls = computed(() => 21 | __c( 22 | theme.className, 23 | 'join', 24 | `join-${props.vertical ? 'vertical' : 'horizontal'}`, 25 | ), 26 | ); 27 | return () => ( 28 |
    29 | {flatUntilNotFragment(slots.default?.()).map((it) => 30 | isVNode(it) 31 | ? cloneVNode(it, { 32 | class: __c`join-item`, 33 | }) 34 | : null, 35 | )} 36 |
    37 | ); 38 | }, 39 | }, 40 | styles, 41 | ); 42 | -------------------------------------------------------------------------------- /src/components/join/styles/c-s.css: -------------------------------------------------------------------------------- 1 | .join { 2 | @apply rounded-btn; 3 | & > :where(*:not(:first-child)) { 4 | @apply -ml-px my-0; 5 | } 6 | &-item:focus { 7 | @apply isolate; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/components/join/styles/c-us.css: -------------------------------------------------------------------------------- 1 | .join { 2 | @apply inline-flex items-stretch; 3 | & :where(.join-item) { 4 | border-top-right-radius: 0; 5 | border-bottom-right-radius: 0; 6 | border-bottom-left-radius: 0; 7 | border-top-left-radius: 0; 8 | } 9 | & .join-item:not(:first-child):not(:last-child), 10 | & *:not(:first-child):not(:last-child) .join-item { 11 | border-top-right-radius: 0; 12 | border-bottom-right-radius: 0; 13 | border-bottom-left-radius: 0; 14 | border-top-left-radius: 0; 15 | } 16 | 17 | & .join-item:first-child:not(:last-child), 18 | & *:first-child:not(:last-child) .join-item { 19 | border-top-right-radius: 0; 20 | border-bottom-right-radius: 0; 21 | } 22 | 23 | & :where(.join-item:first-child:not(:last-child)), 24 | & :where(*:first-child:not(:last-child) .join-item) { 25 | border-bottom-left-radius: inherit; 26 | border-top-left-radius: inherit; 27 | } 28 | 29 | & .join-item:last-child:not(:first-child), 30 | & *:last-child:not(:first-child) .join-item { 31 | border-bottom-left-radius: 0; 32 | border-top-left-radius: 0; 33 | } 34 | 35 | & :where(.join-item:last-child:not(:first-child)), 36 | & :where(*:last-child:not(:first-child) .join-item) { 37 | border-top-right-radius: inherit; 38 | border-bottom-right-radius: inherit; 39 | } 40 | } 41 | :where(.join *) { 42 | @apply rounded-[inherit]; 43 | } 44 | -------------------------------------------------------------------------------- /src/components/join/styles/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from './u-s.css'; 5 | export default [s1, s2, s3, s4]; 6 | -------------------------------------------------------------------------------- /src/components/join/styles/u-s.css: -------------------------------------------------------------------------------- 1 | .join.join-vertical > :where(*:not(:first-child)) { 2 | @apply -mt-px mx-0; 3 | } 4 | .join.join-horizontal > :where(*:not(:first-child)) { 5 | @apply -ml-px my-0; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/join/styles/u-us.css: -------------------------------------------------------------------------------- 1 | .join.join-vertical { 2 | @apply flex-col; 3 | & .join-item:first-child:not(:last-child), 4 | & *:first-child:not(:last-child) .join-item { 5 | border-bottom-left-radius: 0; 6 | border-bottom-right-radius: 0; 7 | } 8 | & .join-item:first-child:not(:last-child), 9 | & *:first-child:not(:last-child) .join-item { 10 | border-top-left-radius: inherit; 11 | border-top-right-radius: inherit; 12 | } 13 | & .join-item:last-child:not(:first-child), 14 | & *:last-child:not(:first-child) .join-item { 15 | border-top-left-radius: 0; 16 | border-top-right-radius: 0; 17 | } 18 | & .join-item:last-child:not(:first-child), 19 | & *:last-child:not(:first-child) .join-item { 20 | border-bottom-left-radius: inherit; 21 | border-bottom-right-radius: inherit; 22 | } 23 | } 24 | 25 | .join.join-horizontal { 26 | @apply flex-row; 27 | & .join-item:first-child:not(:last-child), 28 | & *:first-child:not(:last-child) .join-item { 29 | border-bottom-right-radius: 0; 30 | border-top-right-radius: 0; 31 | } 32 | & .join-item:first-child:not(:last-child), 33 | & *:first-child:not(:last-child) .join-item { 34 | border-bottom-left-radius: inherit; 35 | border-top-left-radius: inherit; 36 | } 37 | & .join-item:last-child:not(:first-child), 38 | & *:last-child:not(:first-child) .join-item { 39 | border-bottom-left-radius: 0; 40 | border-top-left-radius: 0; 41 | } 42 | & .join-item:last-child:not(:first-child), 43 | & *:last-child:not(:first-child) .join-item { 44 | border-bottom-right-radius: inherit; 45 | border-top-right-radius: inherit; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/components/kbd/index.tsx: -------------------------------------------------------------------------------- 1 | import { sizeProps } from 'daisyui-vue/shared/constants'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 4 | import { computed, HTMLAttributes } from 'vue'; 5 | import style from './style'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const kbdProps = { 9 | ...sizeProps, 10 | }; 11 | 12 | export type IKbdProps = ExtractFromProps; 13 | 14 | export const Kbd = componentV2( 15 | { 16 | name: 'Kbd', 17 | props: kbdProps, 18 | setup(props, ctx) { 19 | const theme = useTheme(); 20 | const cls = computed(() => ({ 21 | [theme.className]: true, 22 | 'dv-kbd': true, 23 | [`dv-kbd-${props.size}`]: !!props.size, 24 | })); 25 | return () => {ctx.slots.default?.()}; 26 | }, 27 | }, 28 | style, 29 | ); 30 | -------------------------------------------------------------------------------- /src/components/kbd/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-kbd { 2 | @apply border border-base-content border-opacity-20 bg-base-200 px-2 rounded-btn; 3 | border-bottom-width: 2px; 4 | min-height: 2.2em; 5 | min-width: 2.2em; 6 | } 7 | -------------------------------------------------------------------------------- /src/components/kbd/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-kbd { 2 | @apply inline-flex items-center justify-center; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/kbd/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | export default [s1, s2, s3]; 5 | -------------------------------------------------------------------------------- /src/components/kbd/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-kbd { 2 | &-xs { 3 | @apply px-1 text-xs; 4 | min-height: 1.2em; 5 | min-width: 1.2em; 6 | } 7 | &-sm { 8 | @apply px-1 text-sm; 9 | min-height: 1.6em; 10 | min-width: 1.6em; 11 | } 12 | &-md { 13 | @apply px-2 text-base; 14 | min-height: 2.2em; 15 | min-width: 2.2em; 16 | } 17 | &-lg { 18 | @apply px-4 text-lg; 19 | min-height: 2.5em; 20 | min-width: 2.5em; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/components/link/index.tsx: -------------------------------------------------------------------------------- 1 | import { brandVariantProps } from 'daisyui-vue/shared/constants'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 4 | import { computed, HTMLAttributes } from 'vue'; 5 | import styles from './style'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const linkProps = { 9 | ...brandVariantProps, 10 | enableHoverClass: { 11 | type: Boolean, 12 | default: false, 13 | }, 14 | }; 15 | 16 | export type ILinkProps = ExtractFromProps; 17 | 18 | export const Link = componentV2( 19 | { 20 | name: 'Link', 21 | props: linkProps, 22 | setup: (props, { slots }) => { 23 | const theme = useTheme(); 24 | const cls = computed(() => [ 25 | theme.className, 26 | 'dv-link', 27 | { 28 | [`dv-link-${props.variant}`]: !!props.variant, 29 | 'dv-link-hover': props.enableHoverClass, 30 | }, 31 | ]); 32 | return () => {slots.default?.()}; 33 | }, 34 | }, 35 | styles, 36 | ); 37 | -------------------------------------------------------------------------------- /src/components/link/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-link { 2 | &-primary { 3 | @apply text-primary hover:text-primary-focus; 4 | } 5 | &-secondary { 6 | @apply text-secondary hover:text-secondary-focus; 7 | } 8 | &-accent { 9 | @apply text-accent hover:text-accent-focus; 10 | } 11 | &-neutral { 12 | @apply text-neutral hover:text-neutral-focus; 13 | } 14 | &:focus { 15 | @apply outline-none; 16 | } 17 | &:focus-visible { 18 | outline: 2px solid currentColor; 19 | outline-offset: 2px; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/components/link/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-link { 2 | @apply cursor-pointer underline; 3 | &-hover { 4 | @apply no-underline hover:underline; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/components/link/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | export default [s1, s2]; 4 | -------------------------------------------------------------------------------- /src/components/loading/index.tsx: -------------------------------------------------------------------------------- 1 | import { sizeProps } from 'daisyui-vue/shared/constants'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 4 | import { HTMLAttributes, PropType, computed } from 'vue'; 5 | import style from './style'; 6 | import { Raw, rawProps } from '../_widgets/raw'; 7 | import { useTheme } from 'daisyui-vue/shared/ctx'; 8 | 9 | export const loadingProps = { 10 | variant: { 11 | type: String as PropType< 12 | 'spinner' | 'dots' | 'ring' | 'ball' | 'bars' | 'infinity' 13 | >, 14 | default: 'spinner', 15 | }, 16 | ...sizeProps, 17 | color: rawProps.color, 18 | }; 19 | 20 | export type ILoadingProps = ExtractFromProps; 21 | 22 | export const Loading = componentV2( 23 | { 24 | name: 'Loading', 25 | props: loadingProps, 26 | setup(props, ctx) { 27 | const theme = useTheme(); 28 | const cls = computed(() => 29 | __c( 30 | theme.className, 31 | 'loading', 32 | `loading-${props.variant}`, 33 | `loading-${props.size}`, 34 | ), 35 | ); 36 | return () => ; 37 | }, 38 | }, 39 | style, 40 | ); 41 | -------------------------------------------------------------------------------- /src/components/loading/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-s.css'; 2 | export default [s1]; 3 | -------------------------------------------------------------------------------- /src/components/mask/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { cloneVNode, PropType } from 'vue'; 4 | import style from './style'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | export type IMaskType = 8 | | 'squircle' 9 | | 'heart' 10 | | 'hexagon' 11 | | 'hexagon-2' 12 | | 'decagon' 13 | | 'pentagon' 14 | | 'diamond' 15 | | 'square' 16 | | 'circle' 17 | | 'parallelogram' 18 | | 'parallelogram-2' 19 | | 'parallelogram-3' 20 | | 'parallelogram-4' 21 | | 'star' 22 | | 'star-2' 23 | | 'triangle' 24 | | 'triangle-2' 25 | | 'triangle-3' 26 | | 'triangle-4'; 27 | 28 | export const maskProps = { 29 | type: { 30 | type: String as PropType, 31 | default: 'squircle', 32 | }, 33 | }; 34 | 35 | export type IMaskProps = ExtractFromProps; 36 | 37 | export const Mask = componentV2( 38 | { 39 | name: 'Mask', 40 | props: maskProps, 41 | setup: (props, { slots }) => { 42 | const theme = useTheme(); 43 | return () => { 44 | const child = slots.default?.()?.[0]; 45 | return child 46 | ? cloneVNode(child, { 47 | class: `${theme.className} dv-mask dv-mask-${props.type}`, 48 | }) 49 | : null; 50 | }; 51 | }, 52 | }, 53 | style, 54 | ); 55 | -------------------------------------------------------------------------------- /src/components/mask/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-mask { 2 | mask-size: contain; 3 | mask-repeat: no-repeat; 4 | mask-position: center; 5 | &-half-1 { 6 | mask-size: 200%; 7 | mask-position: left; 8 | } 9 | &-half-2 { 10 | mask-size: 200%; 11 | mask-position: right; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/mask/style/index.tsx: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | 4 | export default [s1, s2]; 5 | -------------------------------------------------------------------------------- /src/components/menu/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './menu'; 2 | export * from './menu-item'; 3 | -------------------------------------------------------------------------------- /src/components/menu/menu-item.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { createVNode, computed, HTMLAttributes, PropType } from 'vue'; 4 | import style from './style'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | export const menuItemProps = { 8 | asTitle: Boolean, 9 | disabled: Boolean, 10 | bordered: Boolean, 11 | hoverBordered: Boolean, 12 | /** 13 | * 仅在子元素为 a 标签时生效 14 | */ 15 | active: Boolean, 16 | childWrapper: { 17 | type: [String, Boolean] as PropType, 18 | default: void 0, 19 | }, 20 | }; 21 | 22 | export type IMuneItemProps = ExtractFromProps; 23 | 24 | export const MenuItem = componentV2( 25 | { 26 | name: 'MenuItem', 27 | props: menuItemProps, 28 | setup: (props, { slots }) => { 29 | const theme = useTheme(); 30 | const cls = computed(() => [ 31 | theme.className, 32 | { 33 | 'dv-menu-title': props.asTitle, 34 | 'dv-disabled': props.disabled, 35 | 'dv-bordered': props.bordered, 36 | 'dv-hover-bordered': props.hoverBordered, 37 | }, 38 | ]); 39 | 40 | const wrapper = computed(() => { 41 | if (props.childWrapper === void 0) { 42 | return props.asTitle ? 'span' : 'a'; 43 | } 44 | if (props.childWrapper === false) { 45 | return null; 46 | } 47 | return props.childWrapper; 48 | }); 49 | 50 | return () => { 51 | const children = slots.default?.(); 52 | return ( 53 |
  • 54 | {wrapper.value 55 | ? createVNode( 56 | wrapper.value, 57 | { 58 | class: { 59 | 'dv-active': props.active, 60 | }, 61 | }, 62 | children, 63 | ) 64 | : children} 65 |
  • 66 | ); 67 | }; 68 | }, 69 | }, 70 | style, 71 | ); 72 | -------------------------------------------------------------------------------- /src/components/menu/menu.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { computed, HTMLAttributes } from 'vue'; 4 | import style from './style'; 5 | import { useTheme } from 'daisyui-vue/shared/ctx'; 6 | 7 | export const menuProps = { 8 | compact: Boolean, 9 | horizontal: Boolean, 10 | }; 11 | 12 | export type IMenuProps = ExtractFromProps; 13 | 14 | export const Menu = componentV2( 15 | { 16 | name: 'Menu', 17 | props: menuProps, 18 | setup: (props, { slots }) => { 19 | const theme = useTheme(); 20 | const cls = computed(() => [ 21 | theme.className, 22 | 'dv-menu dv-menu-normal', 23 | props.horizontal ? 'dv-menu-horizontal' : 'dv-menu-vertical', 24 | { 25 | 'dv-menu-compact': props.compact, 26 | }, 27 | ]); 28 | return () =>
      {slots.default?.()}
    ; 29 | }, 30 | }, 31 | style, 32 | ); 33 | -------------------------------------------------------------------------------- /src/components/menu/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-menu { 2 | @apply flex flex-col; 3 | &.dv-horizontal { 4 | @apply inline-flex flex-row; 5 | :where(li) { 6 | @apply flex-row; 7 | } 8 | } 9 | 10 | :where(li) { 11 | @apply relative flex flex-col flex-wrap items-stretch; 12 | } 13 | :where(li:not(.dv-menu-title)) > :where(*:not(ul)) { 14 | @apply flex; 15 | } 16 | :where(li:not(.dv-disabled):not(.dv-menu-title)) > :where(*:not(ul)) { 17 | @apply cursor-pointer select-none items-center outline-none; 18 | } 19 | > :where(li > *:not(ul):focus) { 20 | @apply outline-none; 21 | } 22 | > :where(li.dv-disabled > *:not(ul):focus) { 23 | @apply cursor-auto; 24 | } 25 | 26 | > :where(li) :where(ul) { 27 | @apply flex flex-col items-stretch; 28 | } 29 | > :where(li) > :where(ul) { 30 | @apply absolute hidden; 31 | top: initial; 32 | left: 100%; 33 | } 34 | > :where(li:hover) > :where(ul) { 35 | @apply flex; 36 | } 37 | > :where(li:focus) > :where(ul) { 38 | @apply flex; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/components/menu/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from './u-s.css'; 5 | import s from './style.less'; 6 | 7 | export default [s1, s2, s3, s4, s]; 8 | -------------------------------------------------------------------------------- /src/components/menu/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-menu { 2 | @apply m-0 p-0; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/menu/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-menu-vertical :where(li.dv-bordered > *) { 2 | @apply border-l-4 border-b-0; 3 | } 4 | .dv-menu-horizontal :where(li.dv-bordered > *) { 5 | @apply border-l-0 border-b-4; 6 | } 7 | .dv-menu-normal :where(li > *) { 8 | @apply py-3 text-base; 9 | } 10 | .dv-menu-compact :where(li > *) { 11 | @apply py-2 text-sm; 12 | } 13 | .dv-menu-vertical > :where(li:first-child) { 14 | border-top-left-radius: inherit; 15 | border-top-right-radius: inherit; 16 | border-bottom-right-radius: unset; 17 | border-bottom-left-radius: unset; 18 | } 19 | .dv-menu-vertical > :where(li:first-child) > :where(*:not(ul)) { 20 | border-top-left-radius: inherit; 21 | border-top-right-radius: inherit; 22 | border-bottom-right-radius: unset; 23 | border-bottom-left-radius: unset; 24 | } 25 | .dv-menu-vertical > :where(li:last-child) { 26 | border-top-left-radius: unset; 27 | border-top-right-radius: unset; 28 | border-bottom-right-radius: inherit; 29 | border-bottom-left-radius: inherit; 30 | } 31 | .dv-menu-vertical > :where(li:last-child) > :where(*:not(ul)) { 32 | border-top-left-radius: unset; 33 | border-top-right-radius: unset; 34 | border-bottom-right-radius: inherit; 35 | border-bottom-left-radius: inherit; 36 | } 37 | 38 | .dv-menu-horizontal > :where(li:first-child) { 39 | border-top-left-radius: inherit; 40 | border-top-right-radius: unset; 41 | border-bottom-right-radius: unset; 42 | border-bottom-left-radius: inherit; 43 | } 44 | .dv-menu-horizontal > :where(li:first-child) > :where(*:not(ul)) { 45 | border-top-left-radius: inherit; 46 | border-top-right-radius: unset; 47 | border-bottom-right-radius: unset; 48 | border-bottom-left-radius: inherit; 49 | } 50 | .dv-menu-horizontal > :where(li:last-child) { 51 | border-top-left-radius: unset; 52 | border-top-right-radius: inherit; 53 | border-bottom-right-radius: inherit; 54 | border-bottom-left-radius: unset; 55 | } 56 | .dv-menu-horizontal > :where(li:last-child) > :where(*:not(ul)) { 57 | border-top-left-radius: unset; 58 | border-top-right-radius: inherit; 59 | border-bottom-right-radius: inherit; 60 | border-bottom-left-radius: unset; 61 | } 62 | -------------------------------------------------------------------------------- /src/components/menu/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-menu-vertical { 2 | @apply flex-col; 3 | :where(li) { 4 | @apply flex-col; 5 | } 6 | } 7 | 8 | .dv-menu-vertical > :where(li) > :where(ul) { 9 | top: initial; 10 | left: 100%; 11 | } 12 | 13 | .dv-menu-horizontal { 14 | @apply inline-flex flex-row; 15 | :where(li) { 16 | @apply flex-row; 17 | } 18 | } 19 | 20 | .dv-menu-horizontal > :where(li) > :where(ul) { 21 | top: 100%; 22 | left: initial; 23 | } 24 | -------------------------------------------------------------------------------- /src/components/modal/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './base'; 2 | export * from './widgets'; 3 | -------------------------------------------------------------------------------- /src/components/modal/style/base.less: -------------------------------------------------------------------------------- 1 | :root { 2 | --modal-base-z-index: 1000; 3 | } 4 | 5 | .dv-modal-base { 6 | @apply cursor-pointer; 7 | @apply bg-neutral-focus bg-opacity-40 duration-200 ease-in-out; 8 | @apply fixed inset-0 outline-0; 9 | transition-property: transform, opacity; 10 | overflow: hidden auto; 11 | overscroll-behavior: contain; 12 | z-index: var(--modal-base-z-index); 13 | 14 | &[data-modal-status='close'] { 15 | .dv-modal-box { 16 | pointer-events: none; 17 | } 18 | } 19 | } 20 | 21 | .dv-modal-box { 22 | @apply max-w-full translate-y-10 transform bg-base-100 transition duration-200 ease-in-out rounded-box; 23 | @apply cursor-auto; 24 | position: absolute; 25 | left: 50%; 26 | top: 50%; 27 | transform: translate(-50%, -50%); 28 | pointer-events: auto; 29 | width: 34rem; 30 | max-height: calc(100vh - 5em); 31 | box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); 32 | overflow-y: auto; 33 | overscroll-behavior: contain; 34 | } 35 | 36 | .dv-modal-base-t-enter-active, 37 | .dv-modal-base-t-leave-active { 38 | transition-property: opacity; 39 | @apply duration-300 ease-in-out; 40 | } 41 | 42 | .dv-modal-base-t-enter-from, 43 | .dv-modal-base-t-leave-to { 44 | @apply opacity-0; 45 | } 46 | -------------------------------------------------------------------------------- /src/components/modal/style/widgets.less: -------------------------------------------------------------------------------- 1 | .dv-modal-title { 2 | @apply p-6 pb-0 relative; 3 | 4 | > h3 { 5 | @apply text-lg font-bold m-0; 6 | } 7 | 8 | &-close { 9 | @apply absolute right-2 top-2; 10 | } 11 | } 12 | 13 | .dv-modal-body { 14 | @apply py-4 px-6; 15 | } 16 | 17 | .dv-modal-action { 18 | @apply p-6 text-right; 19 | } 20 | -------------------------------------------------------------------------------- /src/components/modal/widgets.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { IconClose } from '../icon'; 4 | import { PropType } from 'vue'; 5 | import { Button } from '../button'; 6 | import style from './style/widgets.less'; 7 | import { useTheme } from 'daisyui-vue/shared/ctx'; 8 | 9 | // title ---------------------------------------------------------------------------- 10 | 11 | export const modalTitleProps = { 12 | closable: { 13 | type: Boolean, 14 | default: true, 15 | }, 16 | onClose: Function as PropType<(e: MouseEvent) => void>, 17 | }; 18 | 19 | export type IModalTitleProps = ExtractFromProps; 20 | 21 | export const ModalTitle = componentV2( 22 | { 23 | name: 'ModalTitle', 24 | props: modalTitleProps, 25 | setup: (props, { slots }) => { 26 | const theme = useTheme(); 27 | return () => ( 28 |
    29 |

    {slots.default?.()}

    30 | {props.closable ? ( 31 | 39 | ) : null} 40 |
    41 | ); 42 | }, 43 | }, 44 | [style], 45 | ); 46 | 47 | // body ---------------------------------------------------------------------------- 48 | 49 | export const modalBodyProps = {}; 50 | 51 | export type IModalBodyProps = ExtractFromProps; 52 | 53 | export const ModalBody = componentV2( 54 | { 55 | name: 'ModalBody', 56 | props: modalBodyProps, 57 | setup: (props, { slots }) => { 58 | const theme = useTheme(); 59 | return () => ( 60 |
    61 | {slots.default?.()} 62 |
    63 | ); 64 | }, 65 | }, 66 | [style], 67 | ); 68 | 69 | // action ---------------------------------------------------------------------------- 70 | 71 | export const modalActionProps = {}; 72 | 73 | export type IModalActionProps = ExtractFromProps; 74 | 75 | export const ModalAction = componentV2( 76 | { 77 | name: 'ModalAction', 78 | props: modalActionProps, 79 | setup: (props, { slots }) => { 80 | const theme = useTheme(); 81 | return () => ( 82 |
    83 | {slots.default?.()} 84 |
    85 | ); 86 | }, 87 | }, 88 | [style], 89 | ); 90 | -------------------------------------------------------------------------------- /src/components/navbar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './navbar'; 2 | -------------------------------------------------------------------------------- /src/components/navbar/navbar.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { HTMLAttributes } from 'vue'; 3 | import style from './style'; 4 | import { useTheme } from 'daisyui-vue/shared/ctx'; 5 | 6 | export const Navbar = componentV2( 7 | { 8 | name: 'Navbar', 9 | setup: (_, { slots }) => { 10 | const theme = useTheme(); 11 | return () => ( 12 |
    {slots.default?.()}
    13 | ); 14 | }, 15 | }, 16 | style, 17 | ); 18 | 19 | export const NavbarStart = componentV2( 20 | { 21 | name: 'NavbarStart', 22 | setup: (_, { slots }) => { 23 | const theme = useTheme(); 24 | return () => ( 25 |
    26 | {slots.default?.()} 27 |
    28 | ); 29 | }, 30 | }, 31 | style, 32 | ); 33 | 34 | export const NavbarCenter = componentV2( 35 | { 36 | name: 'NavbarCenter', 37 | setup: (_, { slots }) => { 38 | const theme = useTheme(); 39 | return () => ( 40 |
    41 | {slots.default?.()} 42 |
    43 | ); 44 | }, 45 | }, 46 | style, 47 | ); 48 | 49 | export const NavbarEnd = componentV2( 50 | { 51 | name: 'NavbarEnd', 52 | setup: (_, { slots }) => { 53 | const theme = useTheme(); 54 | return () => ( 55 |
    56 | {slots.default?.()} 57 |
    58 | ); 59 | }, 60 | }, 61 | style, 62 | ); 63 | -------------------------------------------------------------------------------- /src/components/navbar/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-navbar { 2 | padding: var(--navbar-padding, 0.5rem); 3 | min-height: 4rem; 4 | @apply w-full; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/navbar/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-navbar { 2 | @apply flex items-center; 3 | } 4 | :where(.dv-navbar > *) { 5 | @apply inline-flex items-center; 6 | } 7 | .dv-navbar-start { 8 | width: 50%; 9 | justify-content: flex-start; 10 | } 11 | .dv-navbar-center { 12 | flex-shrink: 0; 13 | } 14 | .dv-navbar-end { 15 | width: 50%; 16 | justify-content: flex-end; 17 | } 18 | -------------------------------------------------------------------------------- /src/components/navbar/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | export default [s1, s2]; 4 | -------------------------------------------------------------------------------- /src/components/progress/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { computed, PropType } from 'vue'; 3 | import { IColorType, ExtractFromProps } from 'daisyui-vue/shared/types/common'; 4 | import style, { radialProgressStyle } from './style'; 5 | import { cssUnit } from 'daisyui-vue/shared/utils'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const progressProps = { 9 | type: String as PropType, 10 | value: { 11 | type: Number, 12 | default: 0, 13 | }, 14 | max: { 15 | type: Number, 16 | default: 100, 17 | }, 18 | }; 19 | 20 | export type IProgressProps = ExtractFromProps; 21 | 22 | export const Progress = componentV2( 23 | { 24 | name: 'Progress', 25 | props: progressProps, 26 | setup: (props) => { 27 | const theme = useTheme(); 28 | const cls = computed(() => [ 29 | theme.className, 30 | 'dv-progress', 31 | { 32 | [`dv-progress-${props.type}`]: !!props.type, 33 | }, 34 | ]); 35 | return () => ( 36 | 37 | ); 38 | }, 39 | }, 40 | style, 41 | ); 42 | 43 | export const radialProgressProps = { 44 | type: String as PropType, 45 | value: { 46 | type: Number, 47 | default: 0, 48 | }, 49 | size: { 50 | type: [Number, String] as PropType, 51 | default: '80px', 52 | }, 53 | thickness: { 54 | type: [Number, String] as PropType, 55 | default: '', 56 | }, 57 | }; 58 | 59 | export type IRadialProgressProps = ExtractFromProps; 60 | 61 | export const RadialProgress = componentV2( 62 | { 63 | name: 'RadialProgress', 64 | props: radialProgressProps, 65 | setup: (props, { slots }) => { 66 | const theme = useTheme(); 67 | const cptdStyle = computed(() => ({ 68 | '--value': props.value!, 69 | '--size': cssUnit(props.size!), 70 | '--thickness': cssUnit(props.thickness!) || 'calc(var(--size)/10)', 71 | })); 72 | return () => ( 73 |
    83 | {slots.default?.() || props.value + '%'} 84 |
    85 | ); 86 | }, 87 | }, 88 | radialProgressStyle, 89 | ); 90 | -------------------------------------------------------------------------------- /src/components/progress/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-progress { 2 | @apply h-2 rounded-box; 3 | &::-moz-progress-bar { 4 | @apply bg-neutral; 5 | } 6 | &-primary::-moz-progress-bar { 7 | @apply bg-primary; 8 | } 9 | &-secondary::-moz-progress-bar { 10 | @apply bg-secondary; 11 | } 12 | &-accent::-moz-progress-bar { 13 | @apply bg-accent; 14 | } 15 | &-info::-moz-progress-bar { 16 | @apply bg-info; 17 | } 18 | &-success::-moz-progress-bar { 19 | @apply bg-success; 20 | } 21 | &-warning::-moz-progress-bar { 22 | @apply bg-warning; 23 | } 24 | &-error::-moz-progress-bar { 25 | @apply bg-error; 26 | } 27 | 28 | &:indeterminate::after { 29 | @apply bg-neutral; 30 | } 31 | &-primary:indeterminate::after { 32 | @apply bg-primary; 33 | } 34 | &-secondary:indeterminate::after { 35 | @apply bg-secondary; 36 | } 37 | &-accent:indeterminate::after { 38 | @apply bg-accent; 39 | } 40 | &-info:indeterminate::after { 41 | @apply bg-info; 42 | } 43 | &-success:indeterminate::after { 44 | @apply bg-success; 45 | } 46 | &-warning:indeterminate::after { 47 | @apply bg-warning; 48 | } 49 | &-error:indeterminate::after { 50 | @apply bg-error; 51 | } 52 | 53 | &::-webkit-progress-bar { 54 | @apply bg-neutral bg-opacity-20 rounded-box; 55 | } 56 | &::-webkit-progress-value { 57 | @apply bg-neutral-focus rounded-box; 58 | } 59 | &-primary::-webkit-progress-value { 60 | @apply bg-primary; 61 | } 62 | &-secondary::-webkit-progress-value { 63 | @apply bg-secondary; 64 | } 65 | &-accent::-webkit-progress-value { 66 | @apply bg-accent; 67 | } 68 | &-info::-webkit-progress-value { 69 | @apply bg-info; 70 | } 71 | &-success::-webkit-progress-value { 72 | @apply bg-success; 73 | } 74 | &-warning::-webkit-progress-value { 75 | @apply bg-warning; 76 | } 77 | &-error::-webkit-progress-value { 78 | @apply bg-error; 79 | } 80 | } 81 | 82 | .dv-progress:indeterminate::after { 83 | content: ''; 84 | @apply inset-y-0 -left-[40%] w-1/3 absolute rounded-box; 85 | animation: progress-loading 5s infinite ease-in-out; 86 | } 87 | 88 | @keyframes progress-loading { 89 | 50% { 90 | left: 107%; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/components/progress/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-progress { 2 | @apply relative w-full appearance-none overflow-hidden; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/progress/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | export default [s1, s2]; 4 | 5 | import rs1 from './radial-progress-c-us.css'; 6 | import rs2 from './radial-progress-c-s.css'; 7 | 8 | export const radialProgressStyle = [rs1, rs2]; 9 | -------------------------------------------------------------------------------- /src/components/progress/style/radial-progress-c-s.css: -------------------------------------------------------------------------------- 1 | .dv-radial-progress { 2 | --value: 0; 3 | --size: 5rem; 4 | --thickness: calc(var(--size) / 10); 5 | 6 | &:after { 7 | @apply bg-current; 8 | } 9 | 10 | &-primary { 11 | @apply text-primary; 12 | } 13 | &-secondary { 14 | @apply text-secondary; 15 | } 16 | &-accent { 17 | @apply text-accent; 18 | } 19 | &-info { 20 | @apply text-info; 21 | } 22 | &-success { 23 | @apply text-success; 24 | } 25 | &-warning { 26 | @apply text-warning; 27 | } 28 | &-error { 29 | @apply text-error; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/progress/style/radial-progress-c-us.css: -------------------------------------------------------------------------------- 1 | .dv-radial-progress { 2 | @apply w-[var(--size)] h-[var(--size)] bg-transparent rounded-full place-content-center inline-grid relative; 3 | vertical-align: middle; 4 | box-sizing: content-box; 5 | } 6 | .dv-radial-progress::-moz-progress-bar { 7 | @apply bg-transparent appearance-none; 8 | } 9 | .dv-radial-progress::-webkit-progress-value { 10 | @apply bg-transparent appearance-none; 11 | } 12 | .dv-radial-progress::-webkit-progress-bar { 13 | @apply bg-transparent appearance-none; 14 | } 15 | .dv-radial-progress:before, 16 | .dv-radial-progress:after { 17 | @apply absolute rounded-full; 18 | content: ''; 19 | } 20 | .dv-radial-progress:before { 21 | @apply inset-0; 22 | background: radial-gradient(farthest-side, currentColor 98%, #0000) 23 | top/var(--thickness) var(--thickness) no-repeat, 24 | conic-gradient(currentColor calc(var(--value) * 1%), #0000 0); 25 | -webkit-mask: radial-gradient( 26 | farthest-side, 27 | #0000 calc(99% - var(--thickness)), 28 | #000 calc(100% - var(--thickness)) 29 | ); 30 | mask: radial-gradient( 31 | farthest-side, 32 | #0000 calc(99% - var(--thickness)), 33 | #000 calc(100% - var(--thickness)) 34 | ); 35 | } 36 | .dv-radial-progress:after { 37 | inset: calc(50% - var(--thickness) / 2); 38 | transform: rotate(calc(var(--value) * 3.6deg - 90deg)) 39 | translate(calc(var(--size) / 2 - 50%)); 40 | } 41 | -------------------------------------------------------------------------------- /src/components/radio/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './group'; 2 | export * from './radio'; 3 | -------------------------------------------------------------------------------- /src/components/radio/state.tsx: -------------------------------------------------------------------------------- 1 | import { InputChangeEvent } from 'daisyui-vue/@types/dom'; 2 | import { ISize, IText } from 'daisyui-vue/shared/types/common'; 3 | 4 | export interface IRadioContext { 5 | value: IText; 6 | size: ISize; 7 | disabled: boolean; 8 | onChange: (e: InputChangeEvent) => void; 9 | } 10 | 11 | export const radioCtxKey = Symbol('RadioGroup'); 12 | -------------------------------------------------------------------------------- /src/components/radio/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-radio { 2 | --chkbg: var(--bc); 3 | @apply h-6 w-6 cursor-pointer appearance-none rounded-full border border-base-content border-opacity-20; 4 | transition: background, box-shadow var(--animation-input, 0.2s) ease-in-out; 5 | &:focus-visible { 6 | outline: 2px solid hsl(var(--bc)); 7 | outline-offset: 2px; 8 | } 9 | &:checked, 10 | &[aria-checked='true'] { 11 | @apply bg-base-content; 12 | animation: radiomark var(--animation-input, 0.2s) ease-in-out; 13 | box-shadow: 0 0 0 4px hsl(var(--b1)) inset, 0 0 0 4px hsl(var(--b1)) inset; 14 | } 15 | &-primary { 16 | --chkbg: var(--p); 17 | @apply border-primary hover:border-primary; 18 | &:focus-visible { 19 | outline: 2px solid hsl(var(--p)); 20 | } 21 | &:checked, 22 | &[aria-checked='true'] { 23 | @apply border-primary bg-primary text-primary-content; 24 | } 25 | } 26 | &-secondary { 27 | --chkbg: var(--s); 28 | @apply border-secondary hover:border-secondary; 29 | &:focus-visible { 30 | outline: 2px solid hsl(var(--s)); 31 | } 32 | &:checked, 33 | &[aria-checked='true'] { 34 | @apply border-secondary bg-secondary text-secondary-content; 35 | } 36 | } 37 | &-accent { 38 | --chkbg: var(--a); 39 | @apply border-accent hover:border-accent; 40 | &:focus-visible { 41 | outline: 2px solid hsl(var(--a)); 42 | } 43 | &:checked, 44 | &[aria-checked='true'] { 45 | @apply border-accent bg-accent text-accent-content; 46 | } 47 | } 48 | &:disabled { 49 | @apply cursor-not-allowed opacity-20; 50 | } 51 | } 52 | 53 | @keyframes radiomark { 54 | 0% { 55 | box-shadow: 0 0 0 12px hsl(var(--b1)) inset, 0 0 0 12px hsl(var(--b1)) inset; 56 | } 57 | 50% { 58 | box-shadow: 0 0 0 3px hsl(var(--b1)) inset, 0 0 0 3px hsl(var(--b1)) inset; 59 | } 60 | 100% { 61 | box-shadow: 0 0 0 4px hsl(var(--b1)) inset, 0 0 0 4px hsl(var(--b1)) inset; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/components/radio/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-radio { 2 | @apply shrink-0; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/radio/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s4 from 'daisyui-vue/components/_styles/common/checkbox-radio.less'; 5 | import s from './style.less'; 6 | 7 | export default [s1, s2, s3, s4, s]; 8 | -------------------------------------------------------------------------------- /src/components/radio/style/style.less: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daief/daisyui-vue/8150491449dc47467bf1dad98c9789e29dd5f127/src/components/radio/style/style.less -------------------------------------------------------------------------------- /src/components/radio/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-radio { 2 | &-xs { 3 | @apply h-4 w-4; 4 | } 5 | &-sm { 6 | @apply h-5 w-5; 7 | } 8 | &-md { 9 | @apply h-6 w-6; 10 | } 11 | &-lg { 12 | @apply h-8 w-8; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/components/space/index.tsx: -------------------------------------------------------------------------------- 1 | import { computed, HTMLAttributes, PropType, StyleValue } from 'vue'; 2 | import { componentV2 } from 'daisyui-vue/shared/styled'; 3 | import { ExtractFromProps, ISize } from 'daisyui-vue/shared/types/common'; 4 | import style from './style'; 5 | import { 6 | cssUnit, 7 | flatUntilNotFragment, 8 | isUndefined, 9 | } from 'daisyui-vue/shared/utils'; 10 | import { useTheme } from 'daisyui-vue/shared/ctx'; 11 | 12 | export const spaceProps = { 13 | align: { 14 | type: String as PropType<'start' | 'end' | 'center' | 'baseline'>, 15 | default: void 0, 16 | }, 17 | direction: { 18 | type: String as PropType<'vertical' | 'horizontal'>, 19 | default: 'horizontal', 20 | }, 21 | wrap: { 22 | type: Boolean, 23 | default: false, 24 | }, 25 | block: { 26 | type: Boolean, 27 | default: false, 28 | }, 29 | spacing: { 30 | type: [String, Number, Object] as PropType< 31 | ISize | string | number | Array 32 | >, 33 | default: 'md', 34 | }, 35 | }; 36 | 37 | export type ISpaceProps = ExtractFromProps; 38 | 39 | export const Space = componentV2( 40 | { 41 | name: 'Space', 42 | props: spaceProps, 43 | setup: (props, { slots }) => { 44 | const theme = useTheme(); 45 | 46 | const sizeMap: Record = { 47 | xs: '4px', 48 | sm: '8px', 49 | md: '16px', 50 | lg: '24px', 51 | }; 52 | 53 | const gap = computed(() => { 54 | let [x, y] = Array.isArray(props.spacing) 55 | ? props.spacing 56 | : [props.spacing, props.spacing]; 57 | y ||= x; 58 | [x, y] = [x, y].map((it) => sizeMap[it!] || cssUnit(it!)); 59 | return `${x} ${y}`; 60 | }); 61 | 62 | const style = computed(() => ({ 63 | flexWrap: props.wrap ? 'wrap' : void 0, 64 | display: props.block ? 'flex' : void 0, 65 | flexDirection: props.direction === 'vertical' ? 'column' : void 0, 66 | alignItems: 67 | isUndefined(props.align) && props.direction === 'horizontal' 68 | ? 'center' 69 | : props.align, 70 | gap: gap.value, 71 | })); 72 | 73 | return () => ( 74 |
    75 | {flatUntilNotFragment(slots.default?.()).map((it, i) => ( 76 |
    80 | {it} 81 |
    82 | ))} 83 |
    84 | ); 85 | }, 86 | }, 87 | style, 88 | ); 89 | -------------------------------------------------------------------------------- /src/components/space/style/index.ts: -------------------------------------------------------------------------------- 1 | import s from './style.less'; 2 | 3 | export default [s]; 4 | -------------------------------------------------------------------------------- /src/components/space/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-space { 2 | @apply inline-flex; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/swap/index.tsx: -------------------------------------------------------------------------------- 1 | import { componentV2 } from 'daisyui-vue/shared/styled'; 2 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 3 | import { getRenderResult, isUndefined } from 'daisyui-vue/shared/utils'; 4 | import { computed, h, PropType, reactive } from 'vue'; 5 | import styles from './style'; 6 | import { useTheme } from 'daisyui-vue/shared/ctx'; 7 | 8 | export const swapProps = { 9 | on: { 10 | default: '', 11 | }, 12 | off: { 13 | default: '', 14 | }, 15 | tag: { 16 | type: String, 17 | default: 'label', 18 | }, 19 | active: { 20 | type: Boolean, 21 | default: void 0, 22 | }, 23 | animation: { 24 | type: String as PropType<'rotate' | 'flip'>, 25 | default: '', 26 | }, 27 | onChange: { 28 | type: Function as PropType<(e: boolean) => void>, 29 | default: void 0, 30 | }, 31 | }; 32 | 33 | export type ISwapProps = ExtractFromProps; 34 | 35 | export const Swap = componentV2( 36 | { 37 | name: 'Swap', 38 | props: swapProps, 39 | setup: (props, { slots }) => { 40 | const theme = useTheme(); 41 | 42 | const state = reactive({ 43 | active: props.active, 44 | }); 45 | 46 | const finalActive = computed(() => 47 | isUndefined(props.active) ? state.active : props.active, 48 | ); 49 | 50 | const cls = computed(() => [ 51 | theme.className, 52 | 'dv-swap', 53 | { 54 | 'dv-swap-active': finalActive.value, 55 | [`dv-swap-${props.animation}`]: props.animation, 56 | }, 57 | ]); 58 | 59 | return () => { 60 | const on = getRenderResult('on', props, slots); 61 | const off = getRenderResult('off', props, slots); 62 | 63 | return h( 64 | props.tag!, 65 | { 66 | class: cls.value, 67 | onClick: () => { 68 | state.active = !finalActive.value; 69 | props.onChange?.(state.active); 70 | }, 71 | }, 72 | [ 73 |
    {on}
    , 74 |
    {off}
    , 75 | ], 76 | ); 77 | }; 78 | }, 79 | }, 80 | styles, 81 | ); 82 | -------------------------------------------------------------------------------- /src/components/swap/style/index.ts: -------------------------------------------------------------------------------- 1 | import style from './style.less'; 2 | 3 | export default [style]; 4 | -------------------------------------------------------------------------------- /src/components/swap/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-swap { 2 | @apply relative inline-grid select-none place-content-center; 3 | 4 | & > * { 5 | @apply col-start-1 row-start-1; 6 | } 7 | 8 | .dv-swap-on { 9 | @apply opacity-0; 10 | } 11 | 12 | .dv-swap-off { 13 | @apply opacity-100; 14 | } 15 | 16 | &.dv-swap-active { 17 | .dv-swap-on { 18 | @apply opacity-100; 19 | } 20 | .dv-swap-off { 21 | @apply opacity-0; 22 | } 23 | } 24 | } 25 | 26 | .dv-swap { 27 | @apply cursor-pointer; 28 | 29 | & > * { 30 | @apply transition-all duration-300 ease-in-out; 31 | } 32 | } 33 | 34 | .dv-swap-rotate { 35 | .dv-swap-on { 36 | @apply rotate-45; 37 | } 38 | 39 | &.dv-swap-active { 40 | .dv-swap-on { 41 | @apply rotate-0; 42 | } 43 | .dv-swap-off { 44 | @apply -rotate-45; 45 | } 46 | } 47 | } 48 | 49 | .dv-swap-flip { 50 | transform-style: preserve-3d; 51 | perspective: 16em; 52 | 53 | .dv-swap-on { 54 | transform: rotateY(180deg); 55 | backface-visibility: hidden; 56 | @apply opacity-100; 57 | } 58 | 59 | &.dv-swap-active { 60 | .dv-swap-on { 61 | transform: rotateY(0deg); 62 | } 63 | .dv-swap-off { 64 | transform: rotateY(-180deg); 65 | backface-visibility: hidden; 66 | @apply opacity-100; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/components/tab/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './tabs'; 2 | -------------------------------------------------------------------------------- /src/components/tab/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-tabs { 2 | @apply flex flex-wrap items-end; 3 | } 4 | .dv-tab { 5 | @apply relative inline-flex cursor-pointer select-none flex-wrap items-center justify-center text-center; 6 | @apply h-8 text-sm leading-loose; 7 | --tab-padding: 1rem; 8 | } 9 | -------------------------------------------------------------------------------- /src/components/tab/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-us.css'; 4 | import s from './style.less'; 5 | export default [s1, s2, s3, s]; 6 | -------------------------------------------------------------------------------- /src/components/tab/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-tabs { 2 | &-lifted-item { 3 | @apply flex-1 cursor-default tab tab-lifted; 4 | } 5 | &.dv-tabs-boxed { 6 | @apply inline-flex; 7 | } 8 | } 9 | 10 | .dv-tab-content { 11 | @apply mt-2; 12 | 13 | &--hidden { 14 | @apply hidden; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/components/tab/style/u-us.css: -------------------------------------------------------------------------------- 1 | .dv-tab { 2 | &-md { 3 | @apply h-8 text-sm leading-loose; 4 | --tab-padding: 1rem; 5 | } 6 | &-lg { 7 | @apply h-12 text-lg leading-loose; 8 | --tab-padding: 1.25rem; 9 | } 10 | &-sm { 11 | @apply h-6 text-sm leading-3; 12 | --tab-padding: 0.75rem; 13 | } 14 | &-xs { 15 | @apply h-5 text-xs leading-3; 16 | --tab-padding: 0.5rem; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/table/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './table'; 2 | -------------------------------------------------------------------------------- /src/components/table/style/c-s.css: -------------------------------------------------------------------------------- 1 | .dv-table { 2 | @apply text-left; 3 | :where(th, td) { 4 | @apply whitespace-nowrap p-4 align-middle; 5 | } 6 | tr.dv-active, 7 | tr.dv-active:nth-child(even) { 8 | th, 9 | td { 10 | @apply bg-base-300; 11 | } 12 | } 13 | tr.dv-hover:hover, 14 | tr.dv-hover:nth-child(even):hover { 15 | th, 16 | td { 17 | @apply bg-base-300; 18 | } 19 | } 20 | &:where(:not(.dv-table-zebra)) { 21 | :where(thead, tbody, tfoot) { 22 | :where(tr:not(:last-child) :where(th, td)) { 23 | @apply border-b border-base-200; 24 | } 25 | } 26 | } 27 | :where(thead, tfoot) { 28 | :where(th, td) { 29 | @apply bg-base-200 text-xs font-bold uppercase; 30 | } 31 | } 32 | 33 | :where(tbody th, tbody td) { 34 | @apply bg-base-100; 35 | } 36 | 37 | &-zebra tbody { 38 | tr:nth-child(even) { 39 | th, 40 | td { 41 | @apply bg-base-200; 42 | } 43 | } 44 | } 45 | } 46 | 47 | :where(.dv-table *:first-child) { 48 | :where(*:first-child) { 49 | :where(th, td) { 50 | &:first-child { 51 | @apply rounded-tl-lg; 52 | } 53 | 54 | &:last-child { 55 | @apply rounded-tr-lg; 56 | } 57 | } 58 | } 59 | } 60 | 61 | :where(.dv-table *:last-child) { 62 | :where(*:last-child) { 63 | :where(th, td) { 64 | &:first-child { 65 | @apply rounded-bl-lg; 66 | } 67 | 68 | &:last-child { 69 | @apply rounded-br-lg; 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/components/table/style/c-us.css: -------------------------------------------------------------------------------- 1 | .dv-table { 2 | @apply relative; 3 | th:first-child { 4 | @apply sticky left-0 z-[11]; 5 | /* because safari */ 6 | position: -webkit-sticky; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/components/table/style/index.ts: -------------------------------------------------------------------------------- 1 | import s1 from './c-us.css'; 2 | import s2 from './c-s.css'; 3 | import s3 from './u-s.css'; 4 | import s from './style.less'; 5 | export default [s1, s2, s3, s]; 6 | -------------------------------------------------------------------------------- /src/components/table/style/style.less: -------------------------------------------------------------------------------- 1 | .dv-table-wrap { 2 | @apply overflow-x-auto; 3 | } 4 | .dv-table { 5 | @apply min-w-full; 6 | 7 | colgroup col { 8 | width: 168px; 9 | } 10 | td { 11 | @apply break-all whitespace-normal; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/table/style/u-s.css: -------------------------------------------------------------------------------- 1 | .dv-table-normal { 2 | :where(th, td) { 3 | @apply p-4 text-base; 4 | } 5 | } 6 | .dv-table-compact { 7 | :where(th, td) { 8 | @apply p-2 text-sm; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/textarea/index.tsx: -------------------------------------------------------------------------------- 1 | import { InputChangeEvent } from 'daisyui-vue/@types/dom'; 2 | import { colorVariantProps, V_MODEL_EVENT } from 'daisyui-vue/shared/constants'; 3 | import { componentV2 } from 'daisyui-vue/shared/styled'; 4 | import { ExtractFromProps } from 'daisyui-vue/shared/types/common'; 5 | import { computed, InputHTMLAttributes } from 'vue'; 6 | import styles from './style'; 7 | import { useTheme } from 'daisyui-vue/shared/ctx'; 8 | 9 | export const textareaProps = { 10 | ...colorVariantProps, 11 | border: { 12 | type: Boolean, 13 | default: false, 14 | }, 15 | modelValue: { 16 | type: String, 17 | default: '', 18 | }, 19 | }; 20 | 21 | export type ITextareaProps = ExtractFromProps; 22 | 23 | export const Textarea = componentV2( 24 | { 25 | name: 'Textarea', 26 | props: textareaProps, 27 | emits: [V_MODEL_EVENT], 28 | setup: (props, { emit }) => { 29 | const theme = useTheme(); 30 | const cls = computed(() => ({ 31 | [theme.className]: true, 32 | 'dv-textarea': true, 33 | 'dv-textarea-bordered': props.border, 34 | [`dv-textarea-${props.variant}`]: !!props.variant, 35 | })); 36 | 37 | const handleOnInput = (e: InputChangeEvent) => { 38 | emit(V_MODEL_EVENT, e.target.value); 39 | }; 40 | 41 | return () => ( 42 |