jd-solanki / anu Goto Github PK
View Code? Open in Web Editor NEWAnu - DX focused utility based vue component library built on top of UnoCSS & VueUse β‘οΈπ₯
Home Page: https://anu-vue.netlify.app/
License: MIT License
Anu - DX focused utility based vue component library built on top of UnoCSS & VueUse β‘οΈπ₯
Home Page: https://anu-vue.netlify.app/
License: MIT License
<template>
<AList items="items" />
</template>
<template>
<AList items="items" style="--a-list-padding-y:0.55rem" />
</template>
It should allow adjusting list item padding using CSS vars
It should allow customizing behavior of list item touching the border of list
Slots: append
, prepend
Support avatar (Might break existing icons prop feature)
Props: cardProps for adding list title & subtitleicon
, append-icon
,
use useLayer
composable for list item to:
Allow activating multiple list item as we might have checkboxes in list item
Use CSS property to adjust the gap between each list item
Add list items before
and after
slot for injecting custom content like footer or search before items
If someone has a better prop name for rather than items-pill
for "List item touching the list borders" please suggest
π§ͺ Experiments
Create a nuxt module
so we can easily use it with our Nuxt 3
projects. It will make it easier to setup since Nuxt
makes it super powerful to auto import and compassables with @nuxt/kit
.
https://github.com/unocss/unocss/tree/main/packages/nuxt
Thanks π
The @import
isn't resolving properly for me. It seems to be trying to find a local file inside preset-theme-default
instead of looking for @unocss/reset
package.
@use
fixes this issue for me.
Documentation link not work.
After 07cba14 commit we can render the demo card in few lines of code π₯³
Update all demos to use new way of rendering demo card so other contributors creating new demos know and follow it
At the examples page the Slot example is not working. The dropdown appearing nicely, but whatever the user selects it is not appearing in the input box:
Why
Right now we have to add display: inline-block
to icon if icon doesn't have flex parent and icon is rendered via i
tag. e.g. <i class="inline-block i-bx-home" />
If we don't add inline-block
class icon won't appear because its size will be 0x0.
Process
display: inline-block
to all icons is safe and doesn't create any side effects'display': 'inline-block'
to extraProperties
in presetIcons
<ABtn>
<AMenu>
<AList>
<!-- list content -->
</AList>
</AMenu>
</ABtn>
v-model
: hide & show menupersistent
: Don't dismiss the menu on outside click or esc
[boolean | content
] => 'content' don't close menu if content is clickedplacement
: https://floating-ui.com/docs/computePosition#placementstrategy
: https://floating-ui.com/docs/computePosition#strategymiddleware
: https://floating-ui.com/docs/computePosition#middlewaretrigger
: click | hover
transition
: transition to apply for showing & hiding menu-contentdefault
: Render menu content (most probably AList
wrapped by ACard
)<template>
<div class="flex justify-center w-full" >
<div class="" w-full>
<ATable
:rows="rows"
:columns="columns"
>
</ATable>
</div>
</div>
</template>
<script setup lang="ts">
import { ATable } from "anu-vue"
const rows = [
{
name:"12222",
age:"address",
address:"ssssss"
}
]
const columns = [
{ name: 'αα¬αααΊ' },
{ name: 'α‘αααΊ'},
{ name: 'ααααΊα
α¬' },
]
</script>
i hope it will be like that:
const columns = [
{ name: 'name' ,title:"αα¬αααΊ"},
{ name: "age',title:"α‘αααΊ"},
{ name: 'address',title:"ααααΊα
α¬" },
]
v-slots closure causes the view layer to be unbound?
I love the components so far!
I have noticed when I was testing that ASwitch
component cannot not get a keyboard focus. This also means that it cannot be toggled by keyboard, only by mouse, which from the accessibility POV not ideal.
I believe the internal hidden input[type='checkbox']
is hidden, and that leads to this problem.
I have seen other frameworks are not hiding this internal input, but making it "invisible" with CSS like:
border: 0;
clip: rect(0 0 0 0);
height: 1px;
width: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
I'm not sure tough that this is the best solution...
As a temporary solution one can apply a similar CSS rule which at least makes it indeed possible to get a keyboard focus on the component, but also a visual clue would be also needed that the component has a keyboard focus.
v-model
bordered
boolean prop to add white (update in dark) border around the badgeπ§ͺ Experiments
icon
prop to badge itself which is technically possible but not ideal logically. So, if someone have better idea on this point please comment.ARadio
component use variant group classes, but transformerVariantGroup
isn't explicitly imported in install doc
I don't find any other variant group classes except in the doc (but the uno.config.ts for the doc use transformerVariantGroup
).
Should we replace classes in ARadio
or add transformerVariantGroup
in default config ?
Hi ππ»
--a-spacer
--a-spacing
CSS var we will try to provide more flexibility on sizing usePopper
to handle popups & dialogs. This will be used in the select, menu and if possible we will try to implement it in Drawer & dialog as well.packages
dir--a-spacer
to handle font size easily considering DX. I prefer not to write a-card-text
everytime I need card text, to be honest.icon
prop but it is consumed by avatar
component. Hence, we have to render icon via the avatar
component which requires a few adjustments to sizing. We will try to differentiate avatar component's prop via new prop $avatar
or something else to separate general props & internal component props. This will ease development and will be clear if we provide passing props for multiple internal components in a single parent component.ARow
& ACol
+ ACol
& repeat
prop (repeat prop will improve the DX π)P.S. Soon I will make a project for our upcoming updates and interations
ATable pagination footer shows for the actual page info in a [FROM] - [TO] of [TOTAL] format.
However, the [TO] is always a static number, depending on the page size. You can check in the docs example if you try to move to the second page, it shows "6-5 of 10"m insetad of the correct "6-10 of 10":
<ATextarea v-model="value.body" height="h-200px" readonly label="body" />
if value.body
is higher than height, scroll bar will not work.
import { presetCore, presetThemeDefault } from 'anu-vue'
I was dreaming of a UI framework with vueUse and unoCSS and you have done. Awesome! Thanks.
I followed the file contributing to install in my computer and fix some issue.
But it was a little bit painful. I had to do ni (pnpm i)
everywhere. In the root folder, in packages/anu-vue
and packages/documentation
.
Also, from the root folder, nr dev
and nr dev:docs
don't work. I had to start two terminal instances not from the root folder but from both packages
to prevent vite and vitepress errors.
I wonder how is your dev workflow?
I just updated to v0.11.0, but its missing dependencies for preset-theme-default
:
[vite:css] Preprocessor dependency "sass" not found. Did you install it?
file: .../node_modules/.pnpm/@[email protected]/node_modules/@anu-vue/preset-theme-default/dist/styles.scss
Resolved with pnpm add -D sass
.
Setting up a brand new vitesse project, anu will make the build to fail saying "Unknown Word".
Steps to reproduce:
pages/index.vue
:<ACard variant="outline" title="MyCard" subtitle="This is the subtitle" />
pnpm dev
In all framework's docs, there's a demo and its code snippet. That's it.
However, I think when a developer looks though docs to find the required code he/she only wants to check out the code that is necessary to recreate the shown demo.
For example:
color
prop matters so we should only highlight the color prop line.script
block and some additional markup in template
block but what really matters is the usage of slot show we should highlight the lines that demonstrate the slot for that demo.We already done this in some snippets but it is great docs improvement if we consider this for all snippets.
npm ERR! code EUNSUPPORTEDPROTOCOL
npm ERR! Unsupported URL Type "link:": link:/Users/jd/Projects/oss/anu/packages/anu-vue/dist
When I set the rows Prop of the ATable to a reactive Array it displays the content as expected. If I change the reactive Array (like adding a new element) ATable does not refresh its content. If I change the pagination the new row becomes visible.
Here the relavant code:
<script setup lang="ts">
const fakeDatabase: User[] = [
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere@april
...
}]
const dbRef = ref<User[]>(fakeDatabase)
function addRow() {
dbRef.value.push({
id: 100,
name: 'New User',
username: 'newuser',
email: '[email protected]',
...
})
}
</script>
<template>
<div class="cards-demo-container">
<ABtn @click="addRow">Add New Item</ABtn>
<ATable :rows="dbRef" :columns="cols" :page-size="15" />
</div>
</template>
Looking at the code recalculateCurrentPageData
is only called when the search or the sorting is changed, but not when the rows are changing.
In general, the question is what the designated way is to update the content of the ATable?
useLayer
is evolving composable and started as an experiment. As this is used as a base for various components and provides greater flexibility even at the component level it now requires its own docs.
when i want to try it in nuxt 3 (stable version) the unocss.config.ts throws jiti error
ERROR Cannot start nuxt: Cannot find module 'anu-vue' 11:09:18
Require stack:
..../unocss.config.ts
Require stack:
nr docs:dev
fail with:
nr docs:dev ξ² 1 β
> [email protected] docs:dev /home/manu/Sites/npm/anu2
> pnpm --filter @anu-vue/documentation dev
> @anu-vue/[email protected] dev /home/manu/Sites/npm/anu2/docs
> vitepress dev
vitepress v1.0.0-alpha.29
/home/manu/Sites/npm/anu2/packages/preset-theme-default/src/scss/index.scss:1
@import '@unocss/reset/tailwind.css';
^
SyntaxError: Invalid or unexpected token
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1033:15)
at Module._compile (node:internal/modules/cjs/loader:1069:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Module._load (node:internal/modules/cjs/loader:827:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at jiti (/home/manu/Sites/npm/anu2/node_modules/.pnpm/[email protected]/node_modules/jiti/dist/jiti.js:1:245552)
at /home/manu/Sites/npm/anu2/packages/preset-theme-default/src/index.ts:7:1
at jiti (/home/manu/Sites/npm/anu2/node_modules/.pnpm/[email protected]/node_modules/jiti/dist/jiti.js:1:247502)
at /home/manu/Sites/npm/anu2/docs/uno.config.ts:9:14
at jiti (/home/manu/Sites/npm/anu2/node_modules/.pnpm/[email protected]/node_modules/jiti/dist/jiti.js:1:247502)
at loadConfigFile (/home/manu/Sites/npm/anu2/node_modules/.pnpm/[email protected]/node_modules/unconfig/dist/index.cjs:155:11)
at async Object.load (/home/manu/Sites/npm/anu2/node_modules/.pnpm/[email protected]/node_modules/unconfig/dist/index.cjs:84:24)
at async Object.loadConfig (/home/manu/Sites/npm/anu2/node_modules/.pnpm/@[email protected]/node_modules/@unocss/config/dist/index.cjs:50:18)
at async reloadConfig (/home/manu/Sites/npm/anu2/node_modules/.pnpm/@[email protected][email protected]/node_modules/@unocss/vite/dist/index.cjs:74:20)
Node.js v18.3.0
/home/manu/Sites/npm/anu2/docs:
βERR_PNPM_RECURSIVE_RUN_FIRST_FAILβ @anu-vue/[email protected] dev: `vitepress dev`
Exit status 1
βELIFECYCLEβ Command failed with exit code 1.
So I investigate a little bit more and it seems that everything is ok in packages/preset-theme-default
.
When I go to this folder and run pnpm buid
, the build works with the styles.css
file.
The error come from the doc build. In the log, we can see the line at /home/manu/Sites/npm/anu2/packages/preset-theme-default/src/index.ts:7:1
. This file is called from this line of docs/uno.config.ts
So, I replaced src by dist : import { presetThemeDefault } from '../packages/preset-theme-default/src/index'
for import { presetThemeDefault } from '../packages/preset-theme-default/dist/index'
and it works !
But I don't know the implication of this change. Maybe we can develop both preset-theme-default
and the doc at the same time...
If we useASelect
inside the ADrawer
, its options are not visible because .a-select-options-container
has z-index 10 and .a-drawer
has z-index 52
I noticed that the project has a @antfu/eslint-config-vue
package and and there are some eslint errors(e.g. 'vue' import should occur before import of '@/composables/useLayer'
in AAvatar.tsx
). But I don't know if I should fix it, because it will affect the code style. In addition I tried to switch it to @antfu/eslint-config and delete the unused config. But there were some other eslint errors, such as 'xxx' was used before it was defined
. Would you consider using @antfu/eslint-config, which can bring better code specification to the project.
At the moment, we are reusing/passing component props in another component. E.g. We are resuing ATypography
props in many components however, we don't have a solid API/composable/method to reuse them in a safe way with DRY.
We also have some duplicate code (unsynced) in some components list AList
were resolving this will simplify the code base.
Reference
vuejs/composition-api#628
Steps to reproduce
Check dialog demos randomly multiple times you might get below bug where when you open the dialog window/page suddenly scrolls to the top
Notice when we click on show dialog page is scrolled to the top and when we close the dialog page is back to its position.
What is expected
It should not scroll back to the top when we click on show dialog button
What is actually happening?
Window/page is scrolled to the top when the dialog is visible
I want to build a collapsed items list. But item
slot doesn't work as expected.
How to create a simple collapse with AList
?
Here is the code :
<script lang="ts" setup>
import { ref } from 'vue'
const items = [{
title: 'Apparence',
subtitle: 'Apparence desc...',
},
{
title: 'Network',
subtitle: 'Network desc...',
}]
const selected = ref(new Set())
</script>
<template>
<AList
v-model="selected"
:items="items"
multi
class="[--a-list-gap:0.25rem]"
>
<template #item="{ item, itemIndex }">
<ATypography
:title="[item.title, 'text-red']"
:subtitle="item.subtitle"
/>
<div v-if="selected.has(itemIndex)">I want to put collapsed content here, but this slot is not displayed ! Title isn't red.</div>
</template>
<template #append="{ itemIndex }">
<div
i-fa-chevron-right
class="transition-transform text-gray hover:bg-opacity-0"
:class="selected.has(itemIndex) && 'rotate-90'"
/>
</template>
</AList>
</template>
Wow, this is awesome and beautiful. Love it.
Q1. Not sure, can you please add functionality how to create nice chip & chip groups?
Q2. Is there a CDN version of this to use via the <script> tag?
Thank you so much!
When I try to join discord, I got an invalid invitation.
Discord link : https://discord.com/invite/vSp3a2Yn
I see that Volar
support for Vue
was recently added.
Can package for Nuxt
be patched as well with Volar
?
This is the error I currently get in VSCode in my nuxt
app
Cannot find type definition file for 'anu-vue/volar'.
The file is in the program because:
Entry point of type library 'anu-vue/volar' specified in compilerOptions
In version 0.8.0 and higher we lost the ability to override shortcuts from presetThemeDefault.
If we use shortcutOverrides option like this:
presetThemeDefault({
shortcutOverrides: {
btn: 'px-[0.75em] py-[0.375em] rounded-[0.375em] gap-x-[0.375em] whitespace-nowrap',
},
})
it will raise this error
[vite] Internal server error: result.flatMap is not a function
at UnoGenerator.expandShortcut (/Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/@[email protected]/node_modules/@unocss/core/dist/index.cjs:817:14)
at UnoGenerator.parseToken (/Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/@[email protected]/node_modules/@unocss/core/dist/index.cjs:497:27)
at /Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/@[email protected]/node_modules/@unocss/core/dist/index.cjs:524:34
at Array.map (<anonymous>)
at UnoGenerator.generate (/Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/@[email protected]/node_modules/@unocss/core/dist/index.cjs:521:46)
at Context.load (/Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/@[email protected][email protected]/node_modules/@unocss/vite/dist/index.cjs:502:30)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.load (file:///Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-db16f19c.js:41084:32)
at async loadAndTransform (file:///Users/brojor/dev/testing/anu-9.1-test/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-db16f19c.js:37312:24)
Hi,
I've struggling with the colors and variants props, so I installed histoire.dev. Histoire is a pure vuejs alternative of storybook. It's a tool to build UI components in isolation.
You can try it with this branch : https://github.com/ManUtopiK/anu/tree/histoire and start with nr clean && ni && nr build && nr story:dev
.
I started to build ABtn
and especially AList
, here are the screenshots:
What do you think about this?
To reproduce:
<script lang="ts" setup>
const items = [
{ title: 'Donut jujubes' },
{ title: 'Sesame snaps' },
{ title: 'I love jelly' },
{ title: 'Cake gummi', disable: true },
]
</script>
<template>
<div class="cards-demo-container">
<ACard>
<AList>
<li v-for="item in items" :key="item.title">
{{ item.title }}
</li>
</AList>
</ACard>
</div>
</template>
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'value')
at setup (anu-vue.js:1094:27)
at callWithErrorHandling (runtime-core.esm-bundler.js:155:22)
at setupStatefulComponent (runtime-core.esm-bundler.js:7204:29)
at setupComponent (runtime-core.esm-bundler.js:7159:11)
at mountComponent (runtime-core.esm-bundler.js:5508:13)
at processComponent (runtime-core.esm-bundler.js:5483:17)
at patch (runtime-core.esm-bundler.js:5085:21)
at mountChildren (runtime-core.esm-bundler.js:5269:13)
at mountElement (runtime-core.esm-bundler.js:5179:13)
at processElement (runtime-core.esm-bundler.js:5162:13)
I was looking over the demo site, (so I assume it is up to date).
https://anu-vue.netlify.app/guide/components/select.html
In the first example, if you choose banana, and then try to choose banana again. It doesn't work. It leaves the choices open waiting for a selection instead of closing it.
Great work overall.
Cheers.
Hi,
i use your library in our internal company blog (VitePress, UnoCSS, Anu) and a tooltip component would be really helpful for our custom components inside this blog.
Because there are not to many good examples on VitePress for easy blogging i made a starter project built on my learnings so far and included Anu as component framework vitepress-blog-starter.
@jd-solanki Really like your work! Great Job!
Thanks and a great coding time,
Tom
I think it would be nice to have a bottom sheet component for mobile that looks like almost native.
Examples:
https://github.com/gorhom/react-native-bottom-sheet
https://github.com/stipsan/react-spring-bottom-sheet
let me know what you think!
Thanks π
Hi @jd-solanki -- very excited to give this library a try. I created a simple repo using vite/pnpm:
https://github.com/marr/vite-project
I'm not sure what the issue is, I think I followed the getting started instructions properly.
https://github.com/marr/vite-project/blob/main/src/components/HelloWorld.vue#L13
When loading the dev server, there is no button rendered. The console warns:
Failed to resolve component: ABtn
I want to build a simple actions menu, but using AList
is not relevant as we can't handle click on each list items.
How to do that ?
Here is my code :
<script lang="ts" setup>
import { ref } from 'vue'
const items = [
{ title: 'Send' },
{ title: 'Edit' },
{ title: 'Delete' },
]
const selected = ref(0)
watch(selected, () => {
console.log(selected.value)
// We should handle value with item index ?
})
</script>
<template>
<ABtn variant="text" class="!text-gray" icon="i-bi-three-dots-vertical" icon-only>
<AMenu
trigger="hover"
placement="bottom-end"
>
<AList
v-model="selected"
:items="items"
class="[--a-list-gap:0.25rem]"
/>
</AMenu>
</ABtn>
</template>
Also, item 0
is selected at mount time. I don't want that.
If I use const selected = ref()
, hovering item don't trigger background overlay.
types
path in package.json of anu-vue
nr dev
ARadio
component's input element also gets the same classes applied to the root input wrapper. Doc example: ListItem slot exampleATable
AServerTable
ATable
as base. Will have UI for sorting, searching, pagination & pagination meta that emits the event.ADataTable
AServerTable
as base. Will perform sorting, filtering, and pagination on passed rows via rows
.A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.