@polymarbot/nuxt-layer-shadcn-ui 0.9.6 → 0.10.1

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.
@@ -1,8 +1,9 @@
1
+ import type { Component } from 'vue'
1
2
  import type { DropdownItem } from '../Dropdown/types'
2
3
 
3
4
  export interface AdminLayoutSidebarMenuItem {
4
5
  label: string
5
- icon?: string
6
+ icon?: string | Component
6
7
  href?: string
7
8
  command?: () => void
8
9
  group?: string
@@ -14,7 +15,7 @@ export interface AdminLayoutSidebarMenuItem {
14
15
  export interface AdminLayoutSidebarDropdownProfile {
15
16
  title?: string
16
17
  subtitle?: string
17
- icon?: string
18
+ icon?: string | Component
18
19
  image?: string
19
20
  }
20
21
 
@@ -54,13 +54,9 @@ const hasDescription = computed(() => Boolean(slots.default || props.description
54
54
  <ShadcnAlert :class="mergedClass">
55
55
  <slot name="icon">
56
56
  <Icon
57
- v-if="typeof icon === 'string' && icon"
57
+ v-if="icon"
58
58
  :name="icon"
59
59
  />
60
- <component
61
- :is="icon"
62
- v-else-if="icon"
63
- />
64
60
  <Icon
65
61
  v-else-if="defaultIconName"
66
62
  :name="defaultIconName"
@@ -1,6 +1,8 @@
1
+ import type { Component } from 'vue'
2
+
1
3
  export interface BreadcrumbItem {
2
4
  label?: string
3
- icon?: string
5
+ icon?: string | Component
4
6
  href?: string
5
7
  target?: string
6
8
  }
@@ -1,4 +1,5 @@
1
1
  import type { ButtonVariants } from '../../shadcn/button'
2
+ import type { Component } from 'vue'
2
3
  import type { RouteLocationRaw } from 'vue-router'
3
4
 
4
5
  export type ButtonVariant = ButtonVariants['variant']
@@ -10,7 +11,7 @@ export interface ButtonProps {
10
11
  loading?: boolean
11
12
  disabled?: boolean
12
13
  rounded?: boolean
13
- icon?: string
14
+ icon?: string | Component
14
15
  iconPosition?: 'start' | 'end'
15
16
  href?: string
16
17
  to?: RouteLocationRaw
@@ -3,7 +3,6 @@ import { cva } from 'class-variance-authority'
3
3
  import type { DropdownActionItem } from './types'
4
4
 
5
5
  const props = defineProps<{
6
- /** Icon name (lucide kebab-case) or a Vue component. */
7
6
  icon: DropdownActionItem['icon']
8
7
  /** Override icon color independently of the surrounding item color. */
9
8
  iconColor?: DropdownActionItem['iconColor']
@@ -29,13 +28,8 @@ const colorClass = computed(() => iconColorVariants({ color: props.iconColor }))
29
28
 
30
29
  <template>
31
30
  <Icon
32
- v-if="typeof icon === 'string'"
31
+ v-if="icon"
33
32
  :name="icon"
34
33
  :class="colorClass"
35
34
  />
36
- <component
37
- :is="icon"
38
- v-else-if="icon"
39
- :class="cn('size-4', colorClass)"
40
- />
41
35
  </template>
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import { Coffee } from 'lucide-vue-next'
2
3
  import Icon from './index.vue'
3
4
 
4
5
  const commonIcons = [
@@ -75,6 +76,30 @@ export const CommonIcons: Story = {
75
76
  }),
76
77
  }
77
78
 
79
+ export const FromComponent: Story = {
80
+ parameters: {
81
+ ...noControls,
82
+ docs: {
83
+ source: {
84
+ code: `
85
+ <script setup lang="ts">
86
+ import { Coffee } from 'lucide-vue-next'
87
+ </script>
88
+
89
+ <template>
90
+ <Icon :name="Coffee" class="size-6" />
91
+ </template>
92
+ `.trim(),
93
+ },
94
+ },
95
+ },
96
+ render: () => ({
97
+ components: { Icon },
98
+ setup: () => ({ Coffee }),
99
+ template: '<Icon :name="Coffee" class="size-6" />',
100
+ }),
101
+ }
102
+
78
103
  export const Sizes: Story = {
79
104
  parameters: {
80
105
  ...noControls,
@@ -14,6 +14,7 @@ function toPascalCase (str: string): string {
14
14
  }
15
15
 
16
16
  const iconComponent = computed<Component | undefined>(() => {
17
+ if (typeof props.name !== 'string') return props.name
17
18
  const pascalName = toPascalCase(props.name)
18
19
  return (icons as Record<string, Component>)[pascalName]
19
20
  })
@@ -1,5 +1,7 @@
1
+ import type { Component } from 'vue'
2
+
1
3
  export interface IconProps {
2
- /** Icon name in kebab-case (e.g. "mail", "arrow-left", "circle-question-mark") */
3
- name: string
4
+ /** Lucide icon name in kebab-case (e.g. "arrow-left") or a Vue component. */
5
+ name: string | Component
4
6
  class?: ClassValue
5
7
  }
@@ -1,9 +1,9 @@
1
- import type { VNode } from 'vue'
1
+ import type { Component, VNode } from 'vue'
2
2
 
3
3
  export type ModalContentType = 'default' | 'success' | 'info' | 'help' | 'warn' | 'danger' | 'error'
4
4
 
5
5
  export interface ModalContentProps {
6
6
  type?: ModalContentType
7
- icon?: string
7
+ icon?: string | Component
8
8
  content?: string | VNode | HTMLElement
9
9
  }
@@ -34,7 +34,7 @@ function getTriggerClass (item: TabsItem) {
34
34
  const showsOnlyIcon = !!item.icon && (props.iconOnly || !item.title)
35
35
  return cn(
36
36
  props.rounded && 'rounded-full',
37
- showsOnlyIcon && 'aspect-square flex-none px-0',
37
+ showsOnlyIcon && 'px-0 aspect-square flex-none',
38
38
  props.triggerClass,
39
39
  )
40
40
  }
@@ -62,13 +62,9 @@ function getTriggerClass (item: TabsItem) {
62
62
  :active="activeValue === item.value"
63
63
  >
64
64
  <Icon
65
- v-if="item.icon && typeof item.icon === 'string'"
65
+ v-if="item.icon"
66
66
  :name="item.icon"
67
67
  />
68
- <component
69
- :is="item.icon"
70
- v-else-if="item.icon"
71
- />
72
68
  <span v-if="item.title && !iconOnly">
73
69
  {{ item.title }}
74
70
  </span>
@@ -0,0 +1,27 @@
1
+ {
2
+ "drag": {
3
+ "title": "Click or drag file to this area to upload",
4
+ "titleDirectory": "Click or drag a directory to this area to upload",
5
+ "titleMultiple": "Click or drag files to this area to upload"
6
+ },
7
+ "empty": "No files",
8
+ "error": {
9
+ "accept": "{files} is not an accepted file type ({accept}).",
10
+ "oversize": "{files} exceeds the {size} size limit."
11
+ },
12
+ "hint": {
13
+ "accept": "Accepted: {types}.",
14
+ "acceptAudio": "audio",
15
+ "acceptImage": "images",
16
+ "acceptVideo": "videos",
17
+ "max": "Up to {max} files can be selected.",
18
+ "maxSize": "Max size per file: {size}.",
19
+ "multiple": "Multiple files can be selected.",
20
+ "single": "Only a single file can be selected."
21
+ },
22
+ "preview": "Preview",
23
+ "remove": "Remove",
24
+ "upload": "Upload",
25
+ "uploadDirectory": "Upload Directory",
26
+ "uploading": "Uploading"
27
+ }