design-system-dashboard-devmunity 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # [0.4.0](https://github.com/vicventum/design-system-dashboard-devmunity/compare/v0.3.0...v0.4.0) (2025-11-17)
2
+
3
+
4
+ ### Features
5
+
6
+ * **components:** :recycle: Reubica y cambia el nombre a los componentes `BCardInner` y `BCardHeader` ([bf321ce](https://github.com/vicventum/design-system-dashboard-devmunity/commit/bf321ce9a7991e032349074a90b336680a79c2e2))
7
+ * **components:** :sparkles: Crea componente DUploadAvatar ([babbd45](https://github.com/vicventum/design-system-dashboard-devmunity/commit/babbd45ebaf47182375d95d8081e571314e12438))
8
+ * **components:** :sparkles: Crea componentes `BBadge` y `CBadgeStatus` ([7aeb85a](https://github.com/vicventum/design-system-dashboard-devmunity/commit/7aeb85ae765604fdbb6f334312a7615fda32a868))
9
+
10
+ # [0.3.0](https://github.com/vicventum/design-system-dashboard-devmunity/compare/v0.2.0...v0.3.0) (2025-11-15)
11
+
12
+
13
+ ### Features
14
+
15
+ * **components:** :sparkles: Crea componente `ADropdownAvatar` ([0aa9677](https://github.com/vicventum/design-system-dashboard-devmunity/commit/0aa96779530ed7c16389db6fb1ea9ead99e495ca))
16
+ * **components:** :sparkles: Crea componente `APill` ([5ed606e](https://github.com/vicventum/design-system-dashboard-devmunity/commit/5ed606e86f0e29d8c1d09e55d9e6d803e496bcd1))
17
+ * **components:** :sparkles: Crea componente AButtonAvatarDropdown ([d9e283d](https://github.com/vicventum/design-system-dashboard-devmunity/commit/d9e283dc20d3f70e214c56d9b26c55d688bec254))
18
+
1
19
  # [0.2.0](https://github.com/vicventum/design-system-dashboard-devmunity/compare/v0.1.0...v0.2.0) (2025-11-14)
2
20
 
3
21
 
@@ -1,38 +1,38 @@
1
1
  @layer base {
2
- * {
3
- /* @apply border-neutral-300; */
4
- }
5
- body {
6
- @apply overflow-x-hidden scroll-smooth text-pretty text-neutral-950;
7
- scrollbar-gutter: stable;
8
- }
9
- h1,
10
- h2,
11
- h3,
12
- h4,
13
- h5,
14
- h6 {
15
- @apply text-balance;
16
- }
2
+ * {
3
+ /* @apply border-neutral-300; */
4
+ }
5
+ body {
6
+ @apply text-default overflow-x-hidden scroll-smooth text-pretty;
7
+ scrollbar-gutter: stable;
8
+ }
9
+ h1,
10
+ h2,
11
+ h3,
12
+ h4,
13
+ h5,
14
+ h6 {
15
+ @apply text-balance;
16
+ }
17
17
 
18
- label {
19
- @apply block cursor-pointer text-sm font-medium text-neutral-800;
20
- }
18
+ label {
19
+ @apply block cursor-pointer text-sm font-medium text-neutral-800;
20
+ }
21
21
 
22
- ::-webkit-scrollbar {
23
- @apply size-1;
24
- }
25
- ::-webkit-scrollbar-thumb {
26
- @apply rounded-sm bg-primary-400 transition-colors;
27
- }
28
- ::-webkit-scrollbar-track {
29
- @apply bg-transparent;
30
- }
22
+ ::-webkit-scrollbar {
23
+ @apply size-1;
24
+ }
25
+ ::-webkit-scrollbar-thumb {
26
+ @apply bg-primary-400 rounded-sm transition-colors;
27
+ }
28
+ ::-webkit-scrollbar-track {
29
+ @apply bg-transparent;
30
+ }
31
31
 
32
- ::selection {
33
- @apply !bg-primary-500 text-neutral-50;
34
- }
35
- ::-moz-selection {
36
- @apply !bg-primary-500 text-neutral-50;
37
- }
32
+ ::selection {
33
+ @apply !bg-primary-500 text-neutral-50;
34
+ }
35
+ ::-moz-selection {
36
+ @apply !bg-primary-500 text-neutral-50;
37
+ }
38
38
  }
@@ -0,0 +1,7 @@
1
+ export default {
2
+ defaultVariants: {
3
+ color: 'neutral',
4
+ variant: 'soft',
5
+ size: 'sm',
6
+ },
7
+ }
@@ -0,0 +1 @@
1
+ export default /* ui */ {}
@@ -1,3 +1,4 @@
1
1
  export { default as card } from './components/card.js'
2
2
  export { default as button } from './components/button.js'
3
3
  export { default as modal } from './components/modal.js'
4
+ export { default as badge } from './components/badge.js'
@@ -0,0 +1,41 @@
1
+ <script lang="jsx" setup>
2
+ const props = defineProps({
3
+ src: {
4
+ type: String,
5
+ default: '/media/img/user-unknown.png',
6
+ required: false,
7
+ },
8
+ buttonSize: {
9
+ type: String,
10
+ default: 'md',
11
+ required: false,
12
+ },
13
+ avatarSize: {
14
+ type: String,
15
+ default: 'sm',
16
+ required: false,
17
+ },
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <!-- <UButton
23
+ class="bg-color-primary-100 flex items-center gap-2 rounded-full py-1 pr-2 pl-1 text-neutral-800 hover:text-neutral-50"
24
+ >
25
+ <UAvatar :src="src" size="sm" />
26
+ <UIcon name="heroicons:chevron-down-20-solid" class="size-5" />
27
+ </UButton> -->
28
+ <UButton
29
+ :avatar="{
30
+ src,
31
+ size: avatarSize,
32
+ }"
33
+ :size="buttonSize"
34
+ trailing-icon="heroicons:chevron-down-20-solid"
35
+ color="primary"
36
+ variant="ghost"
37
+ class="rounded-full"
38
+ >
39
+ <slot />
40
+ </UButton>
41
+ </template>
@@ -0,0 +1,65 @@
1
+ <script lang="jsx" setup>
2
+ const props = defineProps({
3
+ items: {
4
+ type: Array,
5
+ default: () => [],
6
+ required: true,
7
+ },
8
+ userName: {
9
+ type: String,
10
+ default: '',
11
+ required: true,
12
+ },
13
+ userEmail: {
14
+ type: String,
15
+ default: '',
16
+ required: false,
17
+ },
18
+ userTo: {
19
+ type: String,
20
+ default: '',
21
+ required: false,
22
+ },
23
+ })
24
+
25
+ const uiStyles = computed(() => {
26
+ if (props.userTo) return {}
27
+ return {
28
+ item: 'data-highlighted:first:before:bg-transparent data-[state=open]:first:before:bg-transparent',
29
+ }
30
+ })
31
+
32
+ const itemsComputed = computed(() => [
33
+ {
34
+ userName: props.userName,
35
+ userEmail: props.userEmail,
36
+ slot: 'user',
37
+ onSelect: () => {
38
+ const path = props.userTo
39
+ if (path) navigateTo(path)
40
+ },
41
+ },
42
+ ...props.items,
43
+ ])
44
+ </script>
45
+
46
+ <template>
47
+ <UDropdownMenu :items="itemsComputed" :ui="uiStyles">
48
+ <slot />
49
+
50
+ <template #user="{ item }">
51
+ <div class="text-start">
52
+ <span class="text-highlighted block text-lg font-bold">
53
+ {{ item.userName }}
54
+ </span>
55
+ <span v-if="item?.userEmail" class="text-muted block truncate font-medium">
56
+ {{ item?.userEmail }}
57
+ </span>
58
+ </div>
59
+ </template>
60
+
61
+ <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
62
+ <slot :name="name" v-bind="slotData" />
63
+ </template>
64
+ </UDropdownMenu>
65
+ </template>
@@ -0,0 +1,104 @@
1
+ <script lang="jsx" setup>
2
+ const props = defineProps({
3
+ src: {
4
+ type: String,
5
+ default: '/media/img/user-unknown.png',
6
+ required: false,
7
+ },
8
+ label: {
9
+ type: String,
10
+ default: '',
11
+ required: false,
12
+ },
13
+ color: {
14
+ type: String,
15
+ default: 'neutral',
16
+ required: false,
17
+ },
18
+ variant: {
19
+ type: String,
20
+ default: 'outline',
21
+ required: false,
22
+ validator: (value) => ['solid', 'outline', 'soft', 'subtle'].includes(value),
23
+ },
24
+ size: {
25
+ type: String,
26
+ default: 'sm',
27
+ required: false,
28
+ validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(value),
29
+ },
30
+ hasAvatar: {
31
+ type: Boolean,
32
+ default: true,
33
+ required: false,
34
+ },
35
+ isClosable: {
36
+ type: Boolean,
37
+ default: true,
38
+ required: false,
39
+ },
40
+ })
41
+
42
+ const emit = defineEmits('on-close')
43
+
44
+ const trailingIconSize = computed(() => {
45
+ const sizeMap = {
46
+ xs: 'size-3.5 ',
47
+ sm: 'size-3.5 ',
48
+ md: 'size-3.5 ',
49
+ lg: 'size-3.5 ',
50
+ xl: 'size-4 ',
51
+ }
52
+ return sizeMap[props.size] || 'md'
53
+ })
54
+ const textSize = computed(() => {
55
+ const sizeMap = {
56
+ xs: 'text-xs p-1 gap-1.5',
57
+ sm: 'text-xs p-1 gap-1.5',
58
+ md: 'text-sm p-1 gap-1.5',
59
+ lg: 'text-sm p-1 gap-2',
60
+ xl: 'text-base p-1 gap-2 ',
61
+ }
62
+ return sizeMap[props.size] || 'md'
63
+ })
64
+ </script>
65
+
66
+ <template>
67
+ <div class="flex gap-2">
68
+ <UBadge
69
+ :avatar="
70
+ hasAvatar
71
+ ? {
72
+ src,
73
+ size,
74
+ }
75
+ : null
76
+ "
77
+ :label="label"
78
+ :trailing-icon="isClosable ? 'heroicons:x-mark' : ''"
79
+ :size="size"
80
+ :ui="{
81
+ base: textSize,
82
+ }"
83
+ :color="color"
84
+ :variant="variant"
85
+ class="rounded-full font-normal"
86
+ >
87
+ <template #trailing>
88
+ <UButton
89
+ v-if="isClosable"
90
+ :size="size"
91
+ :ui="{
92
+ leadingIcon: trailingIconSize,
93
+ icon: trailingIconSize,
94
+ }"
95
+ :color="color"
96
+ :variant="variant === 'solid' ? 'solid' : 'icon'"
97
+ icon="heroicons:x-mark"
98
+ class="rounded-full p-0.5 font-normal"
99
+ @click="emit('on-close')"
100
+ />
101
+ </template>
102
+ </UBadge>
103
+ </div>
104
+ </template>
@@ -0,0 +1,31 @@
1
+ <script lang="jsx" setup>
2
+ import { badge } from '~/assets/css/themes'
3
+
4
+ const props = defineProps({
5
+ label: {
6
+ type: String,
7
+ required: true,
8
+ },
9
+ value: {
10
+ type: String,
11
+ default: true,
12
+ },
13
+ styles: {
14
+ type: Object,
15
+ default: () => ({}),
16
+ required: true,
17
+ },
18
+ defaultStyle: {
19
+ type: Object,
20
+ default: () => badge,
21
+ },
22
+ })
23
+ </script>
24
+
25
+ <template>
26
+ <UBadge :label="label" v-bind="styles[value] ?? props.defaultStyle">
27
+ <template v-for="(_, name) in $slots" v-slot:[name]="slotData">
28
+ <slot :name="name" v-bind="slotData" />
29
+ </template>
30
+ </UBadge>
31
+ </template>
@@ -0,0 +1,39 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ label: {
4
+ type: String,
5
+ default: '',
6
+ required: true,
7
+ },
8
+ value: {
9
+ type: String,
10
+ default: '',
11
+ required: true,
12
+ },
13
+ })
14
+
15
+ const styles = {
16
+ PLANNED: {
17
+ color: 'accent',
18
+ variant: 'soft',
19
+ },
20
+ FINISHED: {
21
+ color: 'success',
22
+ variant: 'soft',
23
+ },
24
+ CANCELLED: {
25
+ color: 'error',
26
+ variant: 'soft',
27
+ icon: 'material-symbols:info-outline',
28
+ },
29
+ OTHER: {
30
+ color: 'neutral',
31
+ variant: 'soft',
32
+ },
33
+ }
34
+ const defaultStyle = styles.OTHER
35
+ </script>
36
+
37
+ <template>
38
+ <BBadge :label="label" :value="value" :styles="styles" :default-style="defaultStyle" />
39
+ </template>
@@ -55,9 +55,9 @@ function handleClickLeftButtonIcon() {
55
55
  </script>
56
56
 
57
57
  <template>
58
- <BCardInner
58
+ <ACardInner
59
59
  :class="[
60
- 'flex items-center justify-between',
60
+ 'text-default flex items-center justify-between',
61
61
  { 'bg-muted border-y border-neutral-200': variant === 'secondary' },
62
62
  ]"
63
63
  >
@@ -98,5 +98,5 @@ function handleClickLeftButtonIcon() {
98
98
  <div v-if="$slots.actions" class="p-0">
99
99
  <slot name="actions" />
100
100
  </div>
101
- </BCardInner>
101
+ </ACardInner>
102
102
  </template>
@@ -0,0 +1,76 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ src: {
4
+ type: String,
5
+ default: '',
6
+ required: false,
7
+ },
8
+ buttonSize: {
9
+ type: String,
10
+ default: 'sm',
11
+ required: false,
12
+ validator: (value) => ['xs', 'sm', 'md', 'lg', 'xl'].includes(value),
13
+ },
14
+ buttonColor: {
15
+ type: String,
16
+ default: 'neutral',
17
+ required: false,
18
+ },
19
+ })
20
+ const emit = defineEmits('on-upload-image')
21
+
22
+ // Data
23
+
24
+ const fileName = ref(null)
25
+ const inputFileRef = ref(null)
26
+
27
+ // Computed
28
+
29
+ const getImage = computed(() => {
30
+ if (fileName.value) {
31
+ const imgUrl = globalThis.URL.createObjectURL(fileName.value)
32
+ return imgUrl
33
+ } else if (props.src) {
34
+ return props.src
35
+ }
36
+
37
+ return null
38
+ })
39
+
40
+ // Methods
41
+
42
+ function handleUploadImage(event) {
43
+ if (event.target.files) {
44
+ fileName.value = event.target.files[0]
45
+ } else {
46
+ fileName.value = event.dataTransfer.files[0]
47
+ }
48
+
49
+ emit('on-upload-image', fileName.value)
50
+ }
51
+ </script>
52
+
53
+ <template>
54
+ <div class="flex items-end gap-x-6">
55
+ <div>
56
+ <input
57
+ ref="inputFileRef"
58
+ type="file"
59
+ accept="image/*"
60
+ class="sr-only"
61
+ @change="handleUploadImage"
62
+ />
63
+ <img v-if="getImage" :src="getImage" alt="User image" class="size-20 rounded-md object-cover" />
64
+ <div
65
+ v-else
66
+ class="bg-primary-50 grid size-20 place-items-center rounded-md"
67
+ @click="inputFileRef.click()"
68
+ >
69
+ <UIcon name="heroicons:photo" class="size-6 text-neutral-900" />
70
+ </div>
71
+ </div>
72
+ <UButton :color="buttonColor" variant="outline" @click="inputFileRef.click()" :size="buttonSize">
73
+ {{ 'Cambiar' }}
74
+ </UButton>
75
+ </div>
76
+ </template>
@@ -9,9 +9,9 @@ const modalDanger = overlay.create(CModalDanger)
9
9
  </script>
10
10
 
11
11
  <template>
12
- <div class="h-screen">
12
+ <div class="mb-16 min-h-full">
13
13
  <UContainer>
14
- <BCardInner class="h-full">
14
+ <ACardInner class="h-full">
15
15
  <BCard :has-footer-divider="false">
16
16
  <template #header>
17
17
  <h1>Header</h1>
@@ -23,13 +23,13 @@ const modalDanger = overlay.create(CModalDanger)
23
23
  </BCard>
24
24
  <UCard variant="ghost"> oli </UCard>
25
25
  <AButtonBack icon="heroicons:arrow-left-16-solid" is-back-action />
26
- </BCardInner>
26
+ </ACardInner>
27
27
 
28
28
  <hr class="my-6" />
29
29
 
30
30
  <BCard>
31
31
  <template #header>
32
- <BCardHeader title="Crear una nueva actividad" subtitle="Subtitle" has-left-button-icon>
32
+ <DCardHeader title="Crear una nueva actividad" subtitle="Subtitle" has-left-button-icon>
33
33
  <template #actions>
34
34
  <DActionButtons
35
35
  primary-button-text="Guardar"
@@ -38,16 +38,16 @@ const modalDanger = overlay.create(CModalDanger)
38
38
  is-block-buttons
39
39
  />
40
40
  </template>
41
- </BCardHeader>
41
+ </DCardHeader>
42
42
  </template>
43
43
 
44
- <BCardInner>
44
+ <ACardInner>
45
45
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci eos perspiciatis
46
46
  asperiores suscipit voluptate magni excepturi. Doloribus in fugit quam voluptatibus,
47
47
  molestiae maxime illum explicabo ut corrupti, distinctio atque dolor.
48
- </BCardInner>
48
+ </ACardInner>
49
49
 
50
- <BCardHeader
50
+ <DCardHeader
51
51
  title="Crear una nueva actividad"
52
52
  subtitle="Subtitle"
53
53
  variant="secondary"
@@ -57,9 +57,9 @@ const modalDanger = overlay.create(CModalDanger)
57
57
  <template #actions>
58
58
  <UButton label="Action" />
59
59
  </template>
60
- </BCardHeader>
60
+ </DCardHeader>
61
61
 
62
- <BCardInner class="space-y-2">
62
+ <ACardInner class="space-y-2">
63
63
  <p>
64
64
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Adipisci eos perspiciatis
65
65
  asperiores suscipit voluptate magni excepturi. Doloribus in fugit quam voluptatibus,
@@ -73,7 +73,7 @@ const modalDanger = overlay.create(CModalDanger)
73
73
  class-buttons="w-[200px]"
74
74
  has-buttons-block
75
75
  />
76
- </BCardInner>
76
+ </ACardInner>
77
77
  </BCard>
78
78
 
79
79
  <hr class="my-6" />
@@ -110,6 +110,55 @@ const modalDanger = overlay.create(CModalDanger)
110
110
 
111
111
  <!-- <template #footer> footer </template> -->
112
112
  </BModal>
113
+
114
+ <hr class="my-6" />
115
+
116
+ <ADropdownAvatar
117
+ :items="[
118
+ {
119
+ label: 'Configuraciones',
120
+ icon: 'i-heroicons-cog-8-tooth',
121
+ onSelect: () => {
122
+ navigateTo('/')
123
+ },
124
+ },
125
+ {
126
+ test: 'test',
127
+ slot: 'test',
128
+ },
129
+ ]"
130
+ user-name="Victor Alvarez"
131
+ user-email="test@test.com"
132
+ user-to="/"
133
+ >
134
+ <AButtonAvatarDropdown />
135
+
136
+ <template #test="{ item }">
137
+ {{ item.test }}
138
+ </template>
139
+ </ADropdownAvatar>
140
+
141
+ <hr class="my-6" />
142
+
143
+ <!-- <APill text="test 1" /> -->
144
+ <p>
145
+ <APill label="xs" size="xs" />
146
+ <APill label="sm" size="sm" color="warning" variant="subtle" />
147
+ <APill label="md" size="md" color="error" />
148
+ <APill label="lg" size="lg" color="success" />
149
+ <APill label="xl" size="xl" />
150
+ </p>
151
+
152
+ <hr class="my-6" />
153
+
154
+ <DUploadAvatar button-size="xl" button-color="error" />
155
+
156
+ <hr class="my-6" />
157
+
158
+ <div class="flex gap-x-2">
159
+ <CBadgeStatus label="Urgente" value="CANCELLED" />
160
+ <CBadgeStatus label="Normal" value="normal" />
161
+ </div>
113
162
  </UContainer>
114
163
  </div>
115
164
  </template>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "design-system-dashboard-devmunity",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "scripts": {
6
6
  "build": "nuxt build",
7
7
  "dev": "nuxt dev",