@studious-creative/yumekit 0.1.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.
@@ -0,0 +1,104 @@
1
+ class YumeAvatar extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ["src", "alt", "size", "shape"];
4
+ }
5
+
6
+ constructor() {
7
+ super();
8
+ this.attachShadow({ mode: "open" });
9
+ this.render();
10
+ }
11
+
12
+ attributeChangedCallback(name, oldValue, newValue) {
13
+ if (oldValue !== newValue) {
14
+ this.render();
15
+ }
16
+ }
17
+
18
+ render() {
19
+ const src = this.getAttribute("src");
20
+ const altRaw = this.getAttribute("alt") || "AN";
21
+ const shape = this.getAttribute("shape") || "circle";
22
+ const borderRadius = `var(--component-avatar-border-radius-${shape}, 9999px)`;
23
+
24
+ let dimensions;
25
+ const size = this.getAttribute("size") || "medium";
26
+
27
+ switch (size) {
28
+ case "small":
29
+ dimensions = "var(--component-avatar-size-small, 27px)";
30
+ break;
31
+ case "large":
32
+ dimensions = "var(--component-avatar-size-large, 51px)";
33
+ break;
34
+ case "medium":
35
+ default:
36
+ dimensions = "var(--component-avatar-size-medium, 35px)";
37
+ break;
38
+ }
39
+
40
+ const componentSheet = new CSSStyleSheet();
41
+ let componentStyles = "";
42
+
43
+ if (src) {
44
+ componentStyles = `
45
+ :host {
46
+ display: inline-block;
47
+ height: ${dimensions};
48
+ min-width: ${dimensions};
49
+ }
50
+ img {
51
+ width: 100%;
52
+ height: 100%;
53
+ object-fit: cover;
54
+ border-radius: ${borderRadius};
55
+ }
56
+ `;
57
+ } else {
58
+ componentStyles = `
59
+ :host {
60
+ display: inline-block;
61
+ width: ${dimensions};
62
+ height: ${dimensions};
63
+ min-width: ${dimensions};
64
+ font-family: var(--font-family-header, "Lexend"), sans-serif;
65
+ text-transform: uppercase;
66
+ }
67
+ .avatar {
68
+ width: 100%;
69
+ height: 100%;
70
+ border-radius: ${borderRadius};
71
+ background-color: var(--primary-content--, rgba(4, 134, 209, 1));
72
+ color: var(--primary-background-component, rgba(245, 250, 250, 1));
73
+ display: flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ }
77
+ .avatar h5 {
78
+ margin: 0;
79
+ font-size: calc(${dimensions} * 0.5);
80
+ }
81
+ `;
82
+ }
83
+
84
+ componentSheet.replaceSync(componentStyles);
85
+ this.shadowRoot.adoptedStyleSheets = [componentSheet];
86
+
87
+ if (src) {
88
+ this.shadowRoot.innerHTML = `<img src="${src}" alt="${altRaw}" part="avatar" />`;
89
+ } else {
90
+ const words = altRaw.trim().split(/\s+/);
91
+ const displayText =
92
+ words.length >= 2
93
+ ? words[0].charAt(0) + words[1].charAt(0)
94
+ : altRaw.substring(0, 2);
95
+ this.shadowRoot.innerHTML = `<div class="avatar" part="avatar"><h5>${displayText}</h5></div>`;
96
+ }
97
+ }
98
+ }
99
+
100
+ if (!customElements.get("y-avatar")) {
101
+ customElements.define("y-avatar", YumeAvatar);
102
+ }
103
+
104
+ export { YumeAvatar };
@@ -0,0 +1,149 @@
1
+ class YumeBadge extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ["value", "position", "alignment", "color", "size"];
4
+ }
5
+
6
+ constructor() {
7
+ super();
8
+ this.attachShadow({ mode: "open" });
9
+ this.render();
10
+ }
11
+
12
+ connectedCallback() {
13
+ this.render();
14
+ }
15
+
16
+ attributeChangedCallback(name, oldValue, newValue) {
17
+ if (oldValue !== newValue) {
18
+ this.render();
19
+ }
20
+ }
21
+
22
+ get alignment() {
23
+ return this.getAttribute("alignment") || "right";
24
+ }
25
+
26
+ get color() {
27
+ return this.getAttribute("color") || "primary";
28
+ }
29
+
30
+ get position() {
31
+ return this.getAttribute("position") || "top";
32
+ }
33
+
34
+ get size() {
35
+ return this.getAttribute("size") || "small";
36
+ }
37
+
38
+ get value() {
39
+ return this.getAttribute("value") || "";
40
+ }
41
+
42
+ getBadgeColor(color) {
43
+ const colorMap = {
44
+ primary: "var(--primary-content--)",
45
+ secondary: "var(--secondary-content--)",
46
+ base: "var(--base-content--)",
47
+ success: "var(--success-content--)",
48
+ warning: "var(--warning-content--)",
49
+ error: "var(--error-content--)",
50
+ help: "var(--help-content--)",
51
+ };
52
+ return colorMap[color] || color;
53
+ }
54
+
55
+ getBadgePosition(position, alignment) {
56
+ const offset = "var(--spacing-small, 6px)";
57
+ const vertical =
58
+ position === "top"
59
+ ? `top: calc(${offset} * -1);`
60
+ : `bottom: calc(${offset} * -1);`;
61
+ const horizontal =
62
+ alignment === "right"
63
+ ? `right: calc(${offset} * -1);`
64
+ : `left: calc(${offset} * -1);`;
65
+ return `${vertical} ${horizontal}`;
66
+ }
67
+
68
+ getSizeAttributes(size) {
69
+ const sizeMap = {
70
+ small: {
71
+ fontSize: "var(--font-size-small, 0.8em)",
72
+ padding: "var(--component-badge-padding-small)",
73
+ minSize: "var(--component-badge-size-small)",
74
+ },
75
+ medium: {
76
+ fontSize: "var(--font-size-label, 0.83em)",
77
+ padding: "var(--component-badge-padding-medium)",
78
+ minSize: "var(--component-badge-size-medium)",
79
+ },
80
+ large: {
81
+ fontSize: "var(--font-size-paragraph, 1em)",
82
+ padding: "var(--component-badge-padding-large)",
83
+ minSize: "var(--component-badge-size-large)",
84
+ },
85
+ };
86
+ return sizeMap[size] || sizeMap.small;
87
+ }
88
+
89
+ hasTargetContent() {
90
+ return Array.from(this.childNodes).some((node) => {
91
+ if (node.nodeType === Node.ELEMENT_NODE) return true;
92
+ if (node.nodeType === Node.TEXT_NODE) {
93
+ return node.textContent.trim() !== "";
94
+ }
95
+ return false;
96
+ });
97
+ }
98
+
99
+ render() {
100
+ const badgeColor = this.getBadgeColor(this.color);
101
+ const { fontSize, padding, minSize } = this.getSizeAttributes(
102
+ this.size,
103
+ );
104
+ const positionStyles = this.getBadgePosition(
105
+ this.position,
106
+ this.alignment,
107
+ );
108
+ const hasTarget = this.hasTargetContent();
109
+
110
+ this.shadowRoot.innerHTML = `
111
+ <style>
112
+ :host {
113
+ position: ${hasTarget ? "relative" : "static"};
114
+ display: inline-flex;
115
+ align-items: center;
116
+ }
117
+ .badge {
118
+ position: ${hasTarget ? "absolute" : "static"};
119
+ ${hasTarget ? positionStyles : ""}
120
+ background: ${badgeColor};
121
+ color: var(--base-background-component, #fff);
122
+ font-size: ${fontSize};
123
+ font-weight: bold;
124
+ padding: ${padding};
125
+ border-radius: var(--component-badge-border-radius-circle, 9999px);
126
+ display: flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ font-family: var(--font-family-body, sans-serif);
130
+ min-width: ${minSize};
131
+ height: ${minSize};
132
+ z-index: 20;
133
+ }
134
+ ::slotted(*) {
135
+ position: relative;
136
+ display: inline-block;
137
+ }
138
+ </style>
139
+ ${hasTarget ? "<slot></slot>" : ""}
140
+ <div class="badge" part="badge">${this.value}</div>
141
+ `;
142
+ }
143
+ }
144
+
145
+ if (!customElements.get("y-badge")) {
146
+ customElements.define("y-badge", YumeBadge);
147
+ }
148
+
149
+ export { YumeBadge };