srcdev-nuxt-components 6.1.30 → 6.1.32

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.
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <component
3
+ :is="props.chip ? DisplayChip : as"
4
+ tag="div"
5
+ v-bind="props.chip ? (typeof props.chip === 'object' ? { config: props.chip } : { config: chipDefaultConfig }) : {}"
6
+ class="display-avatar"
7
+ :class="[size, elementClasses]"
8
+ :style-class-passthrough="elementClasses"
9
+ >
10
+ <slot name="default">
11
+ <NuxtImg v-if="src" :src :alt="alt || 'Avatar'" width="100%" height="100%" class="avatar-image" />
12
+ <span v-else>{{ fallback }}</span>
13
+ </slot>
14
+ <slot name="icon"></slot>
15
+ </component>
16
+ </template>
17
+
18
+ <script lang="ts">
19
+ import DisplayChip from "../display-chip/DisplayChip.vue"
20
+ import type { DisplayChipProps, DisplayChipConfig } from "../../types"
21
+ export interface AvatarProps {
22
+ as?: any
23
+ src?: string
24
+ alt?: string
25
+ text?: string
26
+ size?: "xs" | "s" | "md" | "lg" | "xl" | string
27
+ chip?: boolean | DisplayChipProps
28
+ class?: any
29
+ style?: any
30
+ styleClassPassthrough?: string | string[]
31
+ }
32
+
33
+ export interface AvatarSlots {
34
+ default(props?: {}): any
35
+ icon(props?: {}): any
36
+ }
37
+ </script>
38
+
39
+ <script setup lang="ts">
40
+ const props = withDefaults(defineProps<AvatarProps>(), {
41
+ as: "span",
42
+ size: "md",
43
+ styleClassPassthrough: () => [],
44
+ })
45
+ defineSlots<AvatarSlots>()
46
+
47
+ const { elementClasses, resetElementClasses, updateElementClasses } = useStyleClassPassthrough(
48
+ props.styleClassPassthrough
49
+ )
50
+
51
+ if (props.chip && typeof props.chip === "object" && !("styleClassPassthrough" in props.chip)) {
52
+ updateElementClasses(["display-avatar", props.size])
53
+ }
54
+
55
+ const fallback = computed(
56
+ () =>
57
+ props.text ||
58
+ (props.alt || "")
59
+ .split(" ")
60
+ .map((word) => word.charAt(0))
61
+ .join("")
62
+ .substring(0, 2)
63
+ )
64
+
65
+ const chipDefaultConfig = {
66
+ size: "12px",
67
+ maskWidth: "4px",
68
+ offset: "0px",
69
+ angle: "90deg",
70
+ }
71
+
72
+ watch(
73
+ () => props.styleClassPassthrough,
74
+ () => {
75
+ resetElementClasses(props.styleClassPassthrough)
76
+ }
77
+ )
78
+ </script>
79
+
80
+ <style lang="css">
81
+ .display-avatar {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ border-radius: 50%;
86
+ color: var(--gray-3);
87
+
88
+ isolation: isolate;
89
+
90
+ &.xs {
91
+ width: 24px;
92
+ height: 24px;
93
+ font-size: 0.75rem;
94
+ }
95
+ &.s {
96
+ width: 32px;
97
+ height: 32px;
98
+ font-size: 0.875rem;
99
+ }
100
+ &.md {
101
+ width: 40px;
102
+ height: 40px;
103
+ font-size: 1rem;
104
+ }
105
+ &.lg {
106
+ width: 48px;
107
+ height: 48px;
108
+ font-size: 1.125rem;
109
+ }
110
+ &.xl {
111
+ width: 56px;
112
+ height: 56px;
113
+ font-size: 1.25rem;
114
+ }
115
+
116
+ .avatar-image {
117
+ width: 100%;
118
+ border-radius: 50%;
119
+ object-fit: cover;
120
+ }
121
+ }
122
+ </style>
@@ -1,6 +1,8 @@
1
1
  <template>
2
2
  <component :is="tag" class="display-chip-core" :class="[shape, elementClasses]" :style="chipStyles">
3
- <slot></slot>
3
+ <slot name="default"></slot>
4
+ <Icon v-if="config?.icon" :name="config.icon" class="chip-icon" />
5
+ <span v-if="config?.label" class="chip-label" :class="`length-${config.label.length}`">{{ validatedLabel }}</span>
4
6
  </component>
5
7
  </template>
6
8
 
@@ -10,17 +12,20 @@ export interface DisplayChipConfig {
10
12
  maskWidth: string
11
13
  offset: string
12
14
  angle: string
15
+ icon?: string
16
+ label?: string
13
17
  }
14
18
 
15
19
  export interface DisplayChipProps {
16
20
  tag?: "div" | "span"
17
21
  shape?: "circle" | "square"
22
+ config?: DisplayChipConfig
18
23
  styleClassPassthrough?: string | string[]
19
24
  }
20
25
 
21
26
  export interface ChipSlots {
22
27
  default(props?: {}): any
23
- content(props?: {}): any
28
+ // content(props?: {}): any
24
29
  }
25
30
  </script>
26
31
 
@@ -28,33 +33,40 @@ export interface ChipSlots {
28
33
  const props = withDefaults(defineProps<DisplayChipProps>(), {
29
34
  tag: "div",
30
35
  shape: "circle",
31
- styleClassPassthrough: () => [],
32
- })
33
- defineSlots<ChipSlots>()
34
-
35
- const chipConfig = defineModel<DisplayChipConfig>({
36
- type: Object as PropType<{
37
- size: string
38
- maskWidth: string
39
- offset: string
40
- angle: string
41
- }>,
42
- default: () => ({
36
+ config: () => ({
43
37
  size: "12px",
44
38
  maskWidth: "4px",
45
39
  offset: "0px",
46
40
  angle: "90deg",
41
+ icon: undefined,
42
+ label: undefined,
47
43
  }),
48
- required: false,
44
+ styleClassPassthrough: () => [],
49
45
  })
46
+ const slots = defineSlots<ChipSlots>()
47
+ // const slots = useSlots()
50
48
 
51
49
  const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
52
50
 
51
+ // Validate and truncate label to max 3 characters
52
+ const validatedLabel = computed(() => {
53
+ if (!props.config?.label) return props.config?.label
54
+ if (props.config.label.length > 3) {
55
+ console.warn(
56
+ `DisplayChip: label "${
57
+ props.config.label
58
+ }" exceeds maximum length of 3 characters. Truncating to "${props.config.label.slice(0, 3)}"`
59
+ )
60
+ return props.config.label.slice(0, 3)
61
+ }
62
+ return props.config.label
63
+ })
64
+
53
65
  const chipStyles = computed(() => ({
54
- "--chip-size": chipConfig.value.size,
55
- "--chip-mask-width": chipConfig.value.maskWidth,
56
- "--chip-offset": chipConfig.value.offset,
57
- "--chip-angle": chipConfig.value.angle,
66
+ "--chip-size": props.config?.size,
67
+ "--chip-mask-width": props.config?.maskWidth,
68
+ "--chip-offset": props.config?.offset,
69
+ "--chip-angle": props.config?.angle,
58
70
  }))
59
71
  </script>
60
72
 
@@ -92,6 +104,43 @@ const chipStyles = computed(() => ({
92
104
  position: absolute;
93
105
  width: var(--chip-size);
94
106
  border-radius: 100%;
107
+ z-index: 1;
108
+ }
109
+ .chip-icon {
110
+ position: absolute;
111
+ width: var(--chip-size);
112
+ height: var(--chip-size);
113
+ border-radius: 100%;
114
+ display: flex;
115
+ align-items: center;
116
+ justify-content: center;
117
+ color: black;
118
+ z-index: 2;
119
+ }
120
+
121
+ .chip-label {
122
+ --_font-size-adjust: 0.7;
123
+ position: absolute;
124
+ width: var(--chip-size);
125
+ height: var(--chip-size);
126
+ border-radius: 100%;
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ color: black;
131
+ z-index: 2;
132
+ font-size: calc(var(--chip-size) * var(--_font-size-adjust));
133
+ line-height: 1;
134
+ letter-spacing: -0.05rem;
135
+ user-select: none;
136
+
137
+ &.length-2 {
138
+ --_font-size-adjust: 0.6;
139
+ }
140
+
141
+ &.length-3 {
142
+ --_font-size-adjust: 0.5;
143
+ }
95
144
  }
96
145
 
97
146
  & > * {
@@ -101,23 +150,29 @@ const chipStyles = computed(() => ({
101
150
  psuedo-element ::after
102
151
  */
103
152
 
104
- mask-image: radial-gradient(
105
- var(--computed-mask-diameter) var(--computed-mask-diameter) at var(--computed-position-x)
106
- var(--computed-position-y),
107
- transparent calc(50% - 0.5px),
108
- black calc(50% + 0.5px)
109
- );
153
+ &:not(.chip-icon, .chip-label) {
154
+ mask-image: radial-gradient(
155
+ var(--computed-mask-diameter) var(--computed-mask-diameter) at var(--computed-position-x)
156
+ var(--computed-position-y),
157
+ transparent calc(50% - 0.5px),
158
+ black calc(50% + 0.5px)
159
+ );
160
+ }
110
161
  }
111
162
 
112
163
  &.circle {
113
- &::after {
164
+ &::after,
165
+ .chip-icon,
166
+ .chip-label {
114
167
  top: calc(var(--computed-position-y) - (var(--chip-size) / 2));
115
168
  left: calc(var(--computed-position-x) - (var(--chip-size) / 2));
116
169
  }
117
170
  }
118
171
 
119
172
  &.square {
120
- &::after {
173
+ &::after,
174
+ .chip-icon,
175
+ .chip-label {
121
176
  top: calc(var(--computed-position-y) - (var(--chip-size) / 2));
122
177
  left: calc(var(--computed-position-x) - (var(--chip-size) / 2));
123
178
  }
@@ -138,9 +193,5 @@ const chipStyles = computed(() => ({
138
193
  background-color: var(--color-dnd);
139
194
  }
140
195
  }
141
-
142
- .chip-label {
143
- display: none;
144
- }
145
196
  }
146
197
  </style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "6.1.30",
4
+ "version": "6.1.32",
5
5
  "main": "nuxt.config.ts",
6
6
  "scripts": {
7
7
  "clean": "rm -rf .nuxt && rm -rf .output && rm -rf .playground/.nuxt && rm -rf .playground/.output",