srcdev-nuxt-components 6.1.24 → 6.1.26

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,164 @@
1
+ <template>
2
+ <component :is="tag" class="display-chip-core" :class="[shape, elementClasses]" :style="chipStyles">
3
+ <slot></slot>
4
+ </component>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ const props = defineProps({
9
+ tag: {
10
+ type: String,
11
+ default: "span",
12
+ validator(value: string) {
13
+ return ["div", "span"].includes(value)
14
+ },
15
+ },
16
+ shape: {
17
+ type: String as PropType<"circle" | "square">,
18
+ default: "circle",
19
+ validator(value: string) {
20
+ return ["circle", "square"].includes(value)
21
+ },
22
+ },
23
+ styleClassPassthrough: {
24
+ type: [String, Array] as PropType<string | string[]>,
25
+ default: () => [],
26
+ },
27
+ })
28
+
29
+ const chipConfig = defineModel<{
30
+ size: string
31
+ gap: string
32
+ offset: string
33
+ angle: string
34
+ }>({
35
+ type: Object as PropType<{
36
+ size: string
37
+ gap: string
38
+ offset: string
39
+ angle: string
40
+ }>,
41
+ default: () => ({
42
+ size: "12px",
43
+ gap: "4px",
44
+ offset: "0px",
45
+ angle: "90deg",
46
+ }),
47
+ required: false,
48
+ })
49
+
50
+ const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough)
51
+
52
+ // Compute the CSS custom properties based on chipConfig
53
+ const chipStyles = computed(() => ({
54
+ "--status-size": chipConfig.value.size,
55
+ "--status-gap": chipConfig.value.gap,
56
+ "--status-offset": chipConfig.value.offset,
57
+ "--status-angle": chipConfig.value.angle,
58
+ }))
59
+ </script>
60
+
61
+ <style lang="css">
62
+ .display-chip-core {
63
+ &.circle {
64
+ --d: calc(var(--status-size) + (var(--status-gap) * 2)); /* diameter of the mask */
65
+ --r: calc((100% / 2) + var(--status-offset)); /* distance from edge of avatar */
66
+ --x: calc(var(--r) * cos(var(--status-angle) - 90deg) + (100% / 2)); /* x coord of status/mask */
67
+ --y: calc(var(--r) * sin(var(--status-angle) - 90deg) + (100% / 2)); /* y coord of status/mask */
68
+ }
69
+
70
+ &.square {
71
+ /*
72
+ --normalized-angle: calc(var(--status-angle) - 90deg);
73
+ --abs-tan: abs(tan(var(--normalized-angle)));
74
+ --half-size: 50%;
75
+
76
+ --edge-distance: min(var(--half-size), var(--half-size) / var(--abs-tan));
77
+ --base-x: calc(var(--half-size) + var(--edge-distance) * cos(var(--normalized-angle)));
78
+ --base-y: calc(var(--half-size) + var(--edge-distance) * sin(var(--normalized-angle)));
79
+
80
+ --x: calc(var(--base-x) + var(--status-offset) * cos(var(--normalized-angle)));
81
+ --y: calc(var(--base-y) + var(--status-offset) * sin(var(--normalized-angle)));
82
+
83
+ --d: calc(var(--status-size) + (var(--status-gap) * 2));
84
+ */
85
+
86
+ /* Simple square positioning - clamp the circular calculation to square bounds */
87
+ --circle-x: calc(50% + (50% + var(--status-offset) + (var(--status-size) / 2)) * cos(var(--status-angle) - 90deg));
88
+ --circle-y: calc(50% + (50% + var(--status-offset) + (var(--status-size) / 2)) * sin(var(--status-angle) - 90deg));
89
+
90
+ /* Clamp to square bounds (0% to 100% with some padding) */
91
+ --x: clamp(calc(var(--status-offset) * -1), var(--circle-x), calc(100% + var(--status-offset)));
92
+ --y: clamp(calc(var(--status-offset) * -1), var(--circle-y), calc(100% + var(--status-offset)));
93
+
94
+ --d: calc(var(--status-size) + (var(--status-gap) * 2)); /* diameter of the mask (same as circle) */
95
+ }
96
+
97
+ /* colors */
98
+
99
+ --color-offline: slategrey;
100
+ --color-online: rgb(0, 255, 135);
101
+ --color-idle: rgb(255, 185, 51);
102
+ --color-dnd: rgb(255, 40, 80);
103
+
104
+ position: relative;
105
+ display: inline-block;
106
+
107
+ &::after {
108
+ content: "";
109
+ aspect-ratio: 1;
110
+ background: var(--color-offline);
111
+ position: absolute;
112
+ width: var(--status-size);
113
+ border-radius: 100%;
114
+ }
115
+
116
+ & > * {
117
+ /*
118
+ create the cutout mask around the image,
119
+ it's just a radial gradient positioned at the same place as the
120
+ psuedo-element ::after
121
+ */
122
+
123
+ mask-image: radial-gradient(
124
+ var(--d) var(--d) at var(--x) var(--y),
125
+ transparent calc(50% - 0.5px),
126
+ black calc(50% + 0.5px)
127
+ );
128
+ }
129
+
130
+ &.circle {
131
+ &::after {
132
+ top: calc(var(--y) - (var(--status-size) / 2));
133
+ left: calc(var(--x) - (var(--status-size) / 2));
134
+ }
135
+ }
136
+
137
+ &.square {
138
+ &::after {
139
+ top: calc(var(--y) - (var(--status-size) / 2));
140
+ left: calc(var(--x) - (var(--status-size) / 2));
141
+ }
142
+ }
143
+
144
+ &.online {
145
+ &::after {
146
+ background-color: var(--color-online);
147
+ }
148
+ }
149
+ &.idle {
150
+ &::after {
151
+ background-color: var(--color-idle);
152
+ }
153
+ }
154
+ &.dnd {
155
+ &::after {
156
+ background-color: var(--color-dnd);
157
+ }
158
+ }
159
+
160
+ .chip-label {
161
+ display: none;
162
+ }
163
+ }
164
+ </style>
@@ -22,7 +22,7 @@ const classLevel = computed(() => {
22
22
  })
23
23
 
24
24
  const tag = computed(() => `h${tagLevel.value}`)
25
- const classLevelClass = computed(() => `page-header-${classLevel.value}`)
25
+ const classLevelClass = computed(() => `page-heading-${classLevel.value}`)
26
26
 
27
27
  const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough ?? [])
28
28
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "6.1.24",
4
+ "version": "6.1.26",
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",