@muibook/components 1.3.2 → 1.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.
@@ -1,7 +1,7 @@
1
- function u(e) {
2
- return ["positive", "info", "warning", "attention"].includes(e);
1
+ function A(n) {
2
+ return ["positive", "info", "warning", "attention"].includes(n);
3
3
  }
4
- class f extends HTMLElement {
4
+ class x extends HTMLElement {
5
5
  static get observedAttributes() {
6
6
  return ["variant"];
7
7
  }
@@ -9,46 +9,48 @@ class f extends HTMLElement {
9
9
  super(), this.attachShadow({ mode: "open" });
10
10
  }
11
11
  connectedCallback() {
12
- const i = this.getAttribute("variant") || "positive", r = {
12
+ var c;
13
+ const a = this.getAttribute("variant") || "positive", p = {
13
14
  success: "positive",
14
15
  error: "attention"
15
- }, t = u(i) ? i : r[i] || "positive";
16
+ }, t = A(a) ? a : p[a] || "positive";
16
17
  this.setAttribute("variant", t);
17
- const n = {
18
+ const s = {
18
19
  positive: "polite",
19
20
  info: "polite",
20
21
  warning: "assertive",
21
22
  attention: "assertive"
22
23
  };
23
- this.setAttribute("role", "alert"), this.setAttribute("aria-live", n[t] || "polite");
24
- const s = {
24
+ this.setAttribute("role", "alert"), this.setAttribute("aria-live", s[t] || "polite");
25
+ const g = {
25
26
  positive: "mui-icon-check",
26
27
  info: "mui-icon-info",
27
28
  warning: "mui-icon-warning",
28
29
  attention: "mui-icon-attention"
29
- }, c = {
30
+ }, u = {
30
31
  positive: "--feedback-positive-icon",
31
32
  info: "--feedback-info-icon",
32
33
  warning: "--feedback-warning-icon",
33
34
  attention: "--feedback-attention-icon"
34
- }, l = {
35
+ }, b = {
35
36
  positive: "--feedback-positive-text",
36
37
  info: "--feedback-info-text",
37
38
  warning: "--feedback-warning-text",
38
39
  attention: "--feedback-attention-text"
39
- }, d = {
40
+ }, v = {
40
41
  positive: "Success!",
41
42
  info: "Info:",
42
43
  warning: "Warning!",
43
44
  attention: "Error!"
44
45
  };
45
- this.setAttribute("aria-live", n[t]);
46
- const o = s[t], p = c[t], b = l[t], g = d[t], v = (
46
+ this.setAttribute("aria-live", s[t]);
47
+ const r = g[t], h = u[t], m = b[t], f = v[t], w = (
47
48
  /*css*/
48
49
  `
49
50
  :host {
50
51
  border-radius: var(--alert-radius);
51
- padding: var(--alert-padding);
52
+ padding-left: var(--alert-padding);
53
+ padding-right: var(--alert-padding);
52
54
  background: var(--white);
53
55
  box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.05);
54
56
  display: grid;
@@ -58,20 +60,31 @@ class f extends HTMLElement {
58
60
  box-sizing: border-box;
59
61
  }
60
62
 
61
- @media (min-width: 600px) {
62
- :host {
63
- gap: var(--alert-gap-horizontal-desktop);
64
- }
63
+ .icon,
64
+ mui-body {
65
+ padding-top: var(--alert-padding);
66
+ padding-bottom: var(--alert-padding);
67
+ }
68
+
69
+ :host([has-action]) {
70
+ padding-right: var(--space-100);
71
+ grid-template-columns: auto 1fr auto;
65
72
  }
66
73
 
74
+ ::slotted(mui-button[slot="action"]),
75
+ ::slotted(mui-link[slot="action"]) { padding-top: var(--space-100); }
76
+
77
+
67
78
  @media (min-width: 600px) {
68
- .icon {
69
- margin-top: var(--space-000);
70
- }
79
+ :host { gap: var(--alert-gap-horizontal-desktop); }
80
+ :host([has-action]) { padding-right: var(--space-100); }
81
+ ::slotted(mui-button[slot="action"]),
82
+ ::slotted(mui-link[slot="action"]) { align-self: center; padding-top: var(--space-000); }
71
83
  }
72
84
 
73
85
  .label {
74
- color: var(${b}); font-weight: var(--font-weight-bold);
86
+ color: var(${m});
87
+ font-weight: var(--font-weight-bold);
75
88
  }
76
89
 
77
90
  mui-body::part(display) {
@@ -83,27 +96,41 @@ class f extends HTMLElement {
83
96
  }
84
97
 
85
98
  ${["positive", "info", "warning", "attention"].map(
86
- (a) => (
99
+ (i) => (
87
100
  /*css*/
88
101
  `
89
- :host([variant="${a}"]) {
90
- border: var(--feedback-${a}-border);
91
- background: var(--feedback-${a}-background);
102
+ :host([variant="${i}"]) {
103
+ border: var(--feedback-${i}-border);
104
+ background: var(--feedback-${i}-background);
92
105
  }
93
106
  `
94
107
  )
95
108
  ).join("")}
96
109
  `
97
110
  );
98
- this.shadowRoot && (this.shadowRoot.innerHTML = /*html*/
111
+ if (!this.shadowRoot) return;
112
+ this.shadowRoot.innerHTML = /*html*/
99
113
  `
100
- <style>${v}</style>
101
- <${o} size="small" color="var(${p})" class="icon"></${o}>
114
+ <style>${w}</style>
115
+ <${r} size="small" color="var(${h})" class="icon"></${r}>
102
116
  <mui-body>
103
- <span class="label">${g}</span>
117
+ <span class="label">${f}</span>
104
118
  <slot></slot>
105
119
  </mui-body>
106
- `);
120
+ <slot name="action"></slot>
121
+ `;
122
+ const o = (c = this.shadowRoot) == null ? void 0 : c.querySelector('slot[name="action"]');
123
+ if (o) {
124
+ const i = () => {
125
+ const k = o.assignedElements();
126
+ let l = !1;
127
+ k.forEach((e) => {
128
+ const d = e.tagName;
129
+ (d === "MUI-BUTTON" || d === "MUI-LINK") && (l = !0, e.setAttribute("variant", "tertiary"), e.classList.add("alert-slot", `alert-${t}-slot`));
130
+ }), l ? this.setAttribute("has-action", "") : this.removeAttribute("has-action");
131
+ };
132
+ o.addEventListener("slotchange", i), requestAnimationFrame(i);
133
+ }
107
134
  }
108
135
  }
109
- customElements.define("mui-alert", f);
136
+ customElements.define("mui-alert", x);
@@ -65,6 +65,19 @@ class o extends HTMLElement {
65
65
  color: var(--text-color-error);
66
66
  }
67
67
 
68
+ :host([variant="default"]) ::slotted(.mui-icon) {
69
+ fill: var(--text-color);
70
+ }
71
+ :host([variant="success"]) ::slotted(.mui-icon) {
72
+ fill: var(--text-color-success);
73
+ }
74
+ :host([variant="warning"]) ::slotted(.mui-icon) {
75
+ fill: var(--text-color-warning);
76
+ }
77
+ :host([variant="error"]) ::slotted(.mui-icon) {
78
+ fill: var(--text-color-error);
79
+ }
80
+
68
81
  </style>
69
82
 
70
83
  <p part="${t}"><slot></slot></p>
@@ -1,5 +1,5 @@
1
- import { getPartMap as n } from "../../utils/part-map/index.js";
2
- class s extends HTMLElement {
1
+ import { getPartMap as c } from "../../utils/part-map/index.js";
2
+ class v extends HTMLElement {
3
3
  static get observedAttributes() {
4
4
  return ["onclick", "type", "aria-label", "disabled", "variant"];
5
5
  }
@@ -8,7 +8,7 @@ class s extends HTMLElement {
8
8
  }
9
9
  async connectedCallback() {
10
10
  if (await this.waitForPartMap(), !this.shadowRoot) return;
11
- let o = (
11
+ let a = (
12
12
  /*html*/
13
13
  `
14
14
  <style>
@@ -39,14 +39,14 @@ class s extends HTMLElement {
39
39
  }
40
40
 
41
41
  // Turned back on for focus-visible
42
- button:focus, button:active, button:hover { outline: var(--space-000); }
42
+ button:focus-visible, button:active, button:hover { outline: var(--space-000); }
43
43
 
44
44
  button:hover {
45
45
  background: var(--action-primary-background-hover);
46
46
  color: var(--action-primary-text-color-hover);
47
47
  }
48
48
 
49
- button:focus {
49
+ button:focus-visible {
50
50
  background: var(--action-primary-background-focus);
51
51
  color: var(--action-primary-text-color-focus);
52
52
  }
@@ -76,7 +76,7 @@ class s extends HTMLElement {
76
76
  border: var(--action-primary-stroke-hover);
77
77
  }
78
78
 
79
- :host([variant="primary"]) button:focus {
79
+ :host([variant="primary"]) button:focus-visible {
80
80
  background: var(--action-primary-background-focus);
81
81
  color: var(--action-primary-text-color-focus);
82
82
  border: var(--action-primary-stroke-focus);
@@ -89,10 +89,10 @@ class s extends HTMLElement {
89
89
  cursor: not-allowed;
90
90
  }
91
91
 
92
- :host([variant="primary"]) button ::slotted(.mui-icon) { fill: var(--action-primary-text-color); }
93
- :host([variant="primary"]) button:hover ::slotted(.mui-icon) { fill: var(--action-primary-text-color-hover); }
94
- :host([variant="primary"]) button:focus ::slotted(.mui-icon) { fill: var(--action-primary-text-color-focus); }
95
- :host([variant="primary"]) button:disabled ::slotted(.mui-icon) { fill: var(--action-primary-text-color-disabled); }
92
+ :host([variant="primary"]) ::slotted(.mui-icon) { fill: var(--action-primary-text-color); }
93
+ :host([variant="primary"]):hover ::slotted(.mui-icon) { fill: var(--action-primary-text-color-hover); }
94
+ :host([variant="primary"]):focus-visible ::slotted(.mui-icon) { fill: var(--action-primary-text-color-focus); }
95
+ :host([variant="primary"]):disabled ::slotted(.mui-icon) { fill: var(--action-primary-text-color-disabled); }
96
96
 
97
97
  /* Secondary
98
98
  ========================================= */
@@ -109,7 +109,7 @@ class s extends HTMLElement {
109
109
  border: var(--action-secondary-stroke-hover);
110
110
  }
111
111
 
112
- :host([variant="secondary"]) button:focus {
112
+ :host([variant="secondary"]) button:focus-visible {
113
113
  background: var(--action-secondary-background-focus);
114
114
  color: var(--action-secondary-text-color-focus);
115
115
  border: var(--action-secondary-stroke-focus);
@@ -122,10 +122,10 @@ class s extends HTMLElement {
122
122
  cursor: not-allowed;
123
123
  }
124
124
 
125
- :host([variant="secondary"]) button ::slotted(.mui-icon) { fill: var(--action-secondary-text-color); }
126
- :host([variant="secondary"]) button:hover ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-hover); }
127
- :host([variant="secondary"]) button:focus ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-focus); }
128
- :host([variant="secondary"]) button:disabled ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-disabled); }
125
+ :host([variant="secondary"]) ::slotted(.mui-icon) { fill: var(--action-secondary-text-color); }
126
+ :host([variant="secondary"]):hover ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-hover); }
127
+ :host([variant="secondary"]):focus-visible ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-focus); }
128
+ :host([variant="secondary"]):disabled ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-disabled); }
129
129
 
130
130
  /* Tertiary
131
131
  ========================================= */
@@ -142,7 +142,7 @@ class s extends HTMLElement {
142
142
  border: var(--action-tertiary-stroke-hover);
143
143
  }
144
144
 
145
- :host([variant="tertiary"]) button:focus {
145
+ :host([variant="tertiary"]) button:focus-visible {
146
146
  background: var(--action-tertiary-background-focus);
147
147
  color: var(--action-tertiary-text-color-focus);
148
148
  border: var(--action-tertiary-stroke-focus);
@@ -155,10 +155,10 @@ class s extends HTMLElement {
155
155
  cursor: not-allowed;
156
156
  }
157
157
 
158
- :host([variant="tertiary"]) button ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color); }
159
- :host([variant="tertiary"]) button:hover ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-hover); }
160
- :host([variant="tertiary"]) button:focus ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-focus); }
161
- :host([variant="tertiary"]) button:disabled ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-disabled); }
158
+ :host([variant="tertiary"]) ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color); }
159
+ :host([variant="tertiary"]):hover ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-hover); }
160
+ :host([variant="tertiary"]):focus-visible ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-focus); }
161
+ :host([variant="tertiary"]):disabled ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-disabled); }
162
162
 
163
163
  /* Attention
164
164
  ========================================= */
@@ -174,7 +174,7 @@ class s extends HTMLElement {
174
174
  border: var(--action-attention-stroke-hover);
175
175
  }
176
176
 
177
- :host([variant="attention"]) button:focus {
177
+ :host([variant="attention"]) button:focus-visible {
178
178
  background: var(--action-attention-background-focus);
179
179
  color: var(--action-attention-text-color-focus);
180
180
  border: var(--action-attention-stroke-focus);
@@ -187,10 +187,10 @@ class s extends HTMLElement {
187
187
  cursor: not-allowed;
188
188
  }
189
189
 
190
- :host([variant="attention"]) button ::slotted(.mui-icon) { fill: var(--action-attention-text-color); }
191
- :host([variant="attention"]) button:hover ::slotted(.mui-icon) { fill: var(--action-attention-text-color-hover); }
192
- :host([variant="attention"]) button:focus ::slotted(.mui-icon) { fill: var(--action-attention-text-color-focus); }
193
- :host([variant="attention"]) button:disabled ::slotted(.mui-icon) { fill: var(--action-attention-text-color-disabled); }
190
+ :host([variant="attention"]) ::slotted(.mui-icon) { fill: var(--action-attention-text-color); }
191
+ :host([variant="attention"]):hover ::slotted(.mui-icon) { fill: var(--action-attention-text-color-hover); }
192
+ :host([variant="attention"]):focus-visible ::slotted(.mui-icon) { fill: var(--action-attention-text-color-focus); }
193
+ :host([variant="attention"]):disabled ::slotted(.mui-icon) { fill: var(--action-attention-text-color-disabled); }
194
194
 
195
195
  /* Icon only
196
196
  ========================================= */
@@ -247,7 +247,7 @@ class s extends HTMLElement {
247
247
  }
248
248
 
249
249
  :host([slot="after"]) button:hover,
250
- :host([slot="after"]) button:focus {
250
+ :host([slot="after"]) button:focus-visible {
251
251
  background: var(--action-secondary-background-hover);
252
252
  color: var(--action-secondary-text-color-hover);
253
253
  border-color: var(--form-default-border-color-hover);
@@ -256,41 +256,117 @@ class s extends HTMLElement {
256
256
  /* ========================================================================== */
257
257
 
258
258
 
259
+ :host(.alert-positive-slot) {
260
+ --alert-text: var(--feedback-positive-text);
261
+ --alert-icon: var(--feedback-positive-icon);
262
+ --alert-bg-hover: var(--feedback-positive-action-background);
263
+ }
264
+
265
+ :host(.alert-info-slot) {
266
+ --alert-text: var(--feedback-info-text);
267
+ --alert-icon: var(--feedback-info-icon);
268
+ --alert-bg-hover: var(--feedback-info-action-background);
269
+ }
270
+
271
+ :host(.alert-warning-slot) {
272
+ --alert-text: var(--feedback-warning-text);
273
+ --alert-icon: var(--feedback-warning-icon);
274
+ --alert-bg-hover: var(--feedback-warning-action-background);
275
+ }
276
+
277
+ :host(.alert-attention-slot) {
278
+ --alert-text: var(--feedback-attention-text);
279
+ --alert-icon: var(--feedback-attention-icon);
280
+ --alert-bg-hover: var(--feedback-attention-action-background);
281
+ }
282
+
283
+ :host(.alert-slot) button {
284
+ font-weight: var(--font-weight-semi-bold);
285
+ color: var(--alert-text);
286
+ }
287
+
288
+ :host(.alert-slot) button:hover,
289
+ :host(.alert-slot) button:focus-visible {
290
+ background: var(--alert-bg-hover);
291
+ color: var(--alert-text);
292
+ }
293
+
294
+ :host(.alert-slot) ::slotted(.mui-icon),
295
+ :host(.alert-slot):hover ::slotted(.mui-icon),
296
+ :host(.alert-slot):focus-visible ::slotted(.mui-icon) {
297
+ fill: var(--alert-icon);
298
+ }
299
+
300
+
301
+ /* Before & After Icon
302
+ ========================================= */
303
+ :host(.has-after) button,
304
+ :host(.has-before) button,
305
+ :host(.has-after.has-before) button {
306
+ display: grid;
307
+ align-items: center;
308
+ gap: var(--space-100);
309
+ }
310
+
311
+ :host(.has-after.has-before) button {
312
+ grid-template-columns: auto 1fr auto;
313
+ padding-right: var(--space-300);
314
+ padding-left: var(--space-300);
315
+ }
316
+
317
+ :host(.has-after) button {
318
+ grid-template-columns: 1fr auto;
319
+ padding-right: var(--space-300);
320
+ padding-left: var(--space-400);
321
+ }
322
+
323
+ :host(.has-before) button {
324
+ grid-template-columns: auto 1fr;
325
+ padding-right: var(--space-400);
326
+ padding-left: var(--space-300);
327
+ }
328
+
259
329
  </style>
260
330
 
261
331
  <button
262
- part="${n("text", "spacing", "layout", "visual")}"
332
+ part="${c("text", "spacing", "layout", "visual")}"
263
333
  onclick="${this.getAttribute("onclick")}"
264
334
  type="${this.getAttribute("type") || "button"}"
265
335
  aria-label="${this.getAttribute("aria-label") || ""}"
266
336
  ${this.hasAttribute("disabled") ? "disabled" : ""}
267
337
  >
338
+ <slot name="before"></slot>
268
339
  <slot></slot>
340
+ <slot name="after"></slot>
269
341
  </button>
270
342
 
271
343
  `
272
344
  );
273
- this.shadowRoot.innerHTML = o, await customElements.whenDefined("mui-button"), requestAnimationFrame(() => {
274
- var e;
275
- const a = (e = this.shadowRoot) == null ? void 0 : e.querySelector("slot");
276
- ((a == null ? void 0 : a.assignedNodes({ flatten: !0 })) || []).every((t) => {
277
- var i;
345
+ this.shadowRoot.innerHTML = a, await customElements.whenDefined("mui-button"), requestAnimationFrame(() => {
346
+ const e = this.shadowRoot;
347
+ if (!e) return;
348
+ const n = e.querySelector("slot:not([name]"), l = e.querySelector('slot[name="before"]'), d = e.querySelector('slot[name="after"]'), s = (t) => t ? t.assignedNodes({ flatten: !0 }).some((o) => {
349
+ var r;
350
+ return o.nodeType === Node.ELEMENT_NODE || o.nodeType === Node.TEXT_NODE && !!((r = o.textContent) != null && r.trim());
351
+ }) : !1, b = s(l), u = s(d);
352
+ this.classList.toggle("has-before", b), this.classList.toggle("has-after", u), ((n == null ? void 0 : n.assignedNodes({ flatten: !0 })) ?? []).every((t) => {
353
+ var o;
278
354
  if (t.nodeType === Node.ELEMENT_NODE) {
279
- const c = t;
280
- return c.tagName.toLowerCase() === "svg" || c.classList.contains("mui-icon");
355
+ const r = t;
356
+ return r.tagName.toLowerCase() === "svg" || r.classList.contains("mui-icon");
281
357
  }
282
- return t.nodeType === Node.TEXT_NODE && !((i = t.textContent) != null && i.trim());
358
+ return t.nodeType === Node.TEXT_NODE && !((o = t.textContent) != null && o.trim());
283
359
  }) ? this.setAttribute("icon-only", "") : this.removeAttribute("icon-only");
284
360
  });
285
361
  }
286
362
  waitForPartMap() {
287
- return new Promise((r) => {
288
- if (typeof n == "function") return r();
289
- const o = () => {
290
- typeof n == "function" ? r() : requestAnimationFrame(o);
363
+ return new Promise((i) => {
364
+ if (typeof c == "function") return i();
365
+ const a = () => {
366
+ typeof c == "function" ? i() : requestAnimationFrame(a);
291
367
  };
292
- o();
368
+ a();
293
369
  });
294
370
  }
295
371
  }
296
- customElements.define("mui-button", s);
372
+ customElements.define("mui-button", v);
@@ -10,21 +10,23 @@ class r extends HTMLElement {
10
10
  connectedCallback() {
11
11
  this.render(), this.passAttributesToChild();
12
12
  }
13
- attributeChangedCallback(t, e, a) {
13
+ attributeChangedCallback(t, e, s) {
14
14
  (t === "variant" || t === "message") && (this.render(), this.passAttributesToChild());
15
15
  }
16
16
  passAttributesToChild() {
17
- var i;
17
+ var a;
18
18
  if (!this.shadowRoot) return;
19
- const t = this.shadowRoot.querySelector("slot"), e = (i = t == null ? void 0 : t.assignedElements) == null ? void 0 : i.call(t)[0];
19
+ const t = this.shadowRoot.querySelector("slot"), e = (a = t == null ? void 0 : t.assignedElements) == null ? void 0 : a.call(t)[0];
20
20
  if (!e) return;
21
- ["variant", "label", "hide-label"].forEach((s) => {
22
- this.hasAttribute(s) ? e.setAttribute(s, this.getAttribute(s) || "") : e.removeAttribute(s);
21
+ ["variant", "label", "hide-label"].forEach((i) => {
22
+ this.hasAttribute(i) ? e.setAttribute(i, this.getAttribute(i) || "") : e.removeAttribute(i);
23
23
  });
24
24
  }
25
25
  render() {
26
26
  const t = this.getAttribute("message"), e = this.getAttribute("variant");
27
- this.shadowRoot && (this.shadowRoot.innerHTML = /*html*/
27
+ if (!this.shadowRoot) return;
28
+ let s = "";
29
+ e === "success" ? s = "check" : e === "warning" ? s = "warning" : e === "error" && (s = "attention"), this.shadowRoot.innerHTML = /*html*/
28
30
  `
29
31
  <style>
30
32
  :host {
@@ -32,13 +34,26 @@ class r extends HTMLElement {
32
34
  }
33
35
 
34
36
  mui-body {
35
- margin-top: var(--space-100);
37
+ margin-top: var(--space-200);
38
+ }
39
+ mui-body::part(display) {
40
+ display: flex;
41
+ }
42
+ mui-body::part(align-items) {
43
+ align-items: center;
44
+ }
45
+ mui-body::part(gap) {
46
+ gap: var(--space-100);
36
47
  }
37
48
  </style>
38
49
 
39
50
  <slot></slot>
40
- ${t ? `<mui-body size="small" variant="${e}">${t}</mui-body>` : ""}
41
- `);
51
+ ${t ? `
52
+ <mui-body size="small" variant="${e}">
53
+ ${s ? `<mui-icon-${s}></mui-icon-${s}>` : ""}
54
+ ${t}
55
+ </mui-body>` : ""}
56
+ `;
42
57
  }
43
58
  }
44
59
  customElements.define("mui-field", r);
@@ -1,17 +1,17 @@
1
- import { getPartMap as i } from "../../utils/part-map/index.js";
2
- class s extends HTMLElement {
1
+ import { getPartMap as s } from "../../utils/part-map/index.js";
2
+ class u extends HTMLElement {
3
3
  static get observedAttributes() {
4
4
  return ["target", "href", "variant", "weight", "size"];
5
5
  }
6
6
  constructor() {
7
7
  super(), this.attachShadow({ mode: "open" });
8
- const o = this.getAttribute("size") || "medium", t = this.getAttribute("weight") || "regular";
9
- this.setAttribute("size", o), this.setAttribute("weight", t);
8
+ const r = this.getAttribute("size") || "medium", o = this.getAttribute("weight") || "regular";
9
+ this.setAttribute("size", r), this.setAttribute("weight", o);
10
10
  }
11
11
  async connectedCallback() {
12
12
  if (!this.shadowRoot) return;
13
13
  await this.waitForPartMap();
14
- let t = (
14
+ let o = (
15
15
  /*html*/
16
16
  `
17
17
  <style>
@@ -95,8 +95,7 @@ class s extends HTMLElement {
95
95
  border: var(--action-primary-stroke-hover);
96
96
  }
97
97
 
98
- :host([variant="primary"]) a:focus,
99
- :host([variant="tertiary"]) a:focus-visible {
98
+ :host([variant="primary"]) a:focus-visible {
100
99
  background: var(--action-primary-background-focus);
101
100
  color: var(--action-primary-text-color-focus);
102
101
  border: var(--action-primary-stroke-focus);
@@ -109,10 +108,10 @@ class s extends HTMLElement {
109
108
  cursor: not-allowed;
110
109
  }
111
110
 
112
- :host([variant="primary"]) a ::slotted(.mui-icon) { fill: var(--action-primary-text-color); }
113
- :host([variant="primary"]) a:hover ::slotted(.mui-icon) { fill: var(--action-primary-text-color-hover); }
114
- :host([variant="primary"]) a:focus ::slotted(.mui-icon) { fill: var(--action-primary-text-color-focus); }
115
- :host([variant="primary"]) a:disabled ::slotted(.mui-icon) { fill: var(--action-primary-text-color-disabled); }
111
+ :host([variant="primary"]) ::slotted(.mui-icon) { fill: var(--action-primary-text-color); }
112
+ :host([variant="primary"]):hover ::slotted(.mui-icon) { fill: var(--action-primary-text-color-hover); }
113
+ :host([variant="primary"]):focus ::slotted(.mui-icon) { fill: var(--action-primary-text-color-focus); }
114
+ :host([variant="primary"]):disabled ::slotted(.mui-icon) { fill: var(--action-primary-text-color-disabled); }
116
115
 
117
116
  /* Button Secondary
118
117
  ========================================= */
@@ -128,7 +127,6 @@ class s extends HTMLElement {
128
127
  border: var(--action-secondary-stroke-hover);
129
128
  }
130
129
 
131
- :host([variant="secondary"]) a:focus,
132
130
  :host([variant="secondary"]) a:focus-visible {
133
131
  background: var(--action-secondary-background-focus);
134
132
  color: var(--action-secondary-text-color-focus);
@@ -142,10 +140,10 @@ class s extends HTMLElement {
142
140
  cursor: not-allowed;
143
141
  }
144
142
 
145
- :host([variant="secondary"]) a ::slotted(.mui-icon) { fill: var(--action-secondary-text-color); }
146
- :host([variant="secondary"]) a:hover ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-hover); }
147
- :host([variant="secondary"]) a:focus ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-focus); }
148
- :host([variant="secondary"]) a:disabled ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-disabled); }
143
+ :host([variant="secondary"]) ::slotted(.mui-icon) { fill: var(--action-secondary-text-color); }
144
+ :host([variant="secondary"]):hover ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-hover); }
145
+ :host([variant="secondary"]):focus ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-focus); }
146
+ :host([variant="secondary"]):disabled ::slotted(.mui-icon) { fill: var(--action-secondary-text-color-disabled); }
149
147
 
150
148
  /* Button Tertiary
151
149
  ========================================= */
@@ -161,7 +159,6 @@ class s extends HTMLElement {
161
159
  border: var(--action-tertiary-stroke-hover);
162
160
  }
163
161
 
164
- :host([variant="tertiary"]) a:focus,
165
162
  :host([variant="tertiary"]) a:focus-visible {
166
163
  color: var(--action-tertiary-text-color-focus);
167
164
  background: var(--action-tertiary-background-focus);
@@ -175,10 +172,10 @@ class s extends HTMLElement {
175
172
  cursor: not-allowed;
176
173
  }
177
174
 
178
- :host([variant="tertiary"]) a ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color); }
179
- :host([variant="tertiary"]) a:hover ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-hover); }
180
- :host([variant="tertiary"]) a:focus ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-focus); }
181
- :host([variant="tertiary"]) a:disabled ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-disabled); }
175
+ :host([variant="tertiary"]) ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color); }
176
+ :host([variant="tertiary"]):hover ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-hover); }
177
+ :host([variant="tertiary"]):focus ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-focus); }
178
+ :host([variant="tertiary"]):disabled ::slotted(.mui-icon) { fill: var(--action-tertiary-text-color-disabled); }
182
179
 
183
180
  /* Button Attention
184
181
  ========================================= */
@@ -194,7 +191,6 @@ class s extends HTMLElement {
194
191
  border: var(--action-attention-stroke-hover);
195
192
  }
196
193
 
197
- :host([variant="attention"]) a:focus,
198
194
  :host([variant="attention"]) a:focus-visible {
199
195
  background: var(--action-attention-background-focus);
200
196
  color: var(--action-attention-text-color-focus);
@@ -208,10 +204,10 @@ class s extends HTMLElement {
208
204
  cursor: not-allowed;
209
205
  }
210
206
 
211
- :host([variant="attention"]) a ::slotted(.mui-icon) { fill: var(--action-attention-text-color); }
212
- :host([variant="attention"]) a:hover ::slotted(.mui-icon) { fill: var(--action-attention-text-color-hover); }
213
- :host([variant="attention"]) a:focus ::slotted(.mui-icon) { fill: var(--action-attention-text-color-focus); }
214
- :host([variant="attention"]) a:disabled ::slotted(.mui-icon) { fill: var(--action-attention-text-color-disabled); }
207
+ :host([variant="attention"]) ::slotted(.mui-icon) { fill: var(--action-attention-text-color); }
208
+ :host([variant="attention"]):hover ::slotted(.mui-icon) { fill: var(--action-attention-text-color-hover); }
209
+ :host([variant="attention"]):focus ::slotted(.mui-icon) { fill: var(--action-attention-text-color-focus); }
210
+ :host([variant="attention"]):disabled ::slotted(.mui-icon) { fill: var(--action-attention-text-color-disabled); }
215
211
 
216
212
  /* Icon only
217
213
  ========================================= */
@@ -225,39 +221,113 @@ class s extends HTMLElement {
225
221
  }
226
222
  /* ===================================== */
227
223
 
224
+ :host(.alert-positive-slot) {
225
+ --alert-text: var(--feedback-positive-text);
226
+ --alert-icon: var(--feedback-positive-icon);
227
+ --alert-bg-hover: var(--feedback-positive-action-background);
228
+ }
229
+
230
+ :host(.alert-info-slot) {
231
+ --alert-text: var(--feedback-info-text);
232
+ --alert-icon: var(--feedback-info-icon);
233
+ --alert-bg-hover: var(--feedback-info-action-background);
234
+ }
235
+
236
+ :host(.alert-warning-slot) {
237
+ --alert-text: var(--feedback-warning-text);
238
+ --alert-icon: var(--feedback-warning-icon);
239
+ --alert-bg-hover: var(--feedback-warning-action-background);
240
+ }
241
+
242
+ :host(.alert-attention-slot) {
243
+ --alert-text: var(--feedback-attention-text);
244
+ --alert-icon: var(--feedback-attention-icon);
245
+ --alert-bg-hover: var(--feedback-attention-action-background);
246
+ }
247
+
248
+ :host(.alert-slot) a {
249
+ font-weight: var(--font-weight-semi-bold);
250
+ color: var(--alert-text);
251
+ }
252
+
253
+ :host(.alert-slot) a:hover,
254
+ :host(.alert-slot) a:focus-visible {
255
+ background: var(--alert-bg-hover);
256
+ color: var(--alert-text);
257
+ }
258
+
259
+ :host(.alert-slot) ::slotted(.mui-icon),
260
+ :host(.alert-slot):hover ::slotted(.mui-icon),
261
+ :host(.alert-slot):focus-visible ::slotted(.mui-icon) {
262
+ fill: var(--alert-icon);
263
+ }
264
+
265
+ /* Before & After Icon
266
+ ========================================= */
267
+ :host(.has-after) a,
268
+ :host(.has-before) a,
269
+ :host(.has-after.has-before) a {
270
+ display: grid;
271
+ align-items: center;
272
+ gap: var(--space-100);
273
+ }
274
+
275
+ :host(.has-after.has-before) a {
276
+ grid-template-columns: auto 1fr auto;
277
+ padding-right: var(--space-300);
278
+ padding-left: var(--space-300);
279
+ }
280
+
281
+ :host(.has-after) a {
282
+ grid-template-columns: 1fr auto;
283
+ padding-right: var(--space-300);
284
+ padding-left: var(--space-400);
285
+ }
286
+
287
+ :host(.has-before) a {
288
+ grid-template-columns: auto 1fr;
289
+ padding-right: var(--space-400);
290
+ padding-left: var(--space-300);
291
+ }
228
292
 
229
293
  </style>
230
294
 
231
295
  <a
232
- part="${i("text", "spacing", "layout", "visual")}"
296
+ part="${s("text", "spacing", "layout", "visual")}"
233
297
  target="${this.getAttribute("target") || "_self"}"
234
298
  href="${this.getAttribute("href") || "#"}"
235
299
  >
300
+ <slot name="before"></slot>
236
301
  <slot></slot>
302
+ <slot name="after"></slot>
237
303
  </a>
238
304
  `
239
305
  );
240
- this.shadowRoot.innerHTML = t, await customElements.whenDefined("mui-link"), requestAnimationFrame(() => {
241
- var e;
242
- const r = (e = this.shadowRoot) == null ? void 0 : e.querySelector("slot");
243
- ((r == null ? void 0 : r.assignedNodes({ flatten: !0 })) || []).every((a) => {
244
- var n;
245
- if (a.nodeType === Node.ELEMENT_NODE) {
246
- const c = a;
247
- return c.tagName.toLowerCase() === "svg" || c.classList.contains("mui-icon");
306
+ this.shadowRoot.innerHTML = o, await customElements.whenDefined("mui-link"), requestAnimationFrame(() => {
307
+ const i = this.shadowRoot;
308
+ if (!i) return;
309
+ const n = i.querySelector("slot:not([name]"), l = i.querySelector('slot[name="before"]'), d = i.querySelector('slot[name="after"]'), c = (t) => t ? t.assignedNodes({ flatten: !0 }).some((a) => {
310
+ var e;
311
+ return a.nodeType === Node.ELEMENT_NODE || a.nodeType === Node.TEXT_NODE && !!((e = a.textContent) != null && e.trim());
312
+ }) : !1, v = c(l), h = c(d);
313
+ this.classList.toggle("has-before", v), this.classList.toggle("has-after", h), ((n == null ? void 0 : n.assignedNodes({ flatten: !0 })) ?? []).every((t) => {
314
+ var a;
315
+ if (t.nodeType === Node.ELEMENT_NODE) {
316
+ const e = t;
317
+ return e.tagName.toLowerCase() === "svg" || e.classList.contains("mui-icon");
248
318
  }
249
- return a.nodeType === Node.TEXT_NODE && !((n = a.textContent) != null && n.trim());
319
+ return t.nodeType === Node.TEXT_NODE && !((a = t.textContent) != null && a.trim());
250
320
  }) ? this.setAttribute("icon-only", "") : this.removeAttribute("icon-only");
251
321
  });
252
322
  }
253
323
  waitForPartMap() {
254
- return new Promise((o) => {
255
- if (typeof i == "function") return o();
256
- const t = () => {
257
- typeof i == "function" ? o() : requestAnimationFrame(t);
324
+ return new Promise((r) => {
325
+ if (typeof s == "function") return r();
326
+ const o = () => {
327
+ typeof s == "function" ? r() : requestAnimationFrame(o);
258
328
  };
259
- t();
329
+ o();
260
330
  });
261
331
  }
262
332
  }
263
- customElements.define("mui-link", s);
333
+ customElements.define("mui-link", u);
@@ -135,7 +135,7 @@ class f extends HTMLElement {
135
135
  right: var(--space-300);
136
136
  top: 50%;
137
137
  transform: translateY(-50%);
138
- padding: var(--space-300);
138
+ padding: var(--space-200);
139
139
  padding-left: var(--space-000);
140
140
  padding-right: var(--space-000);
141
141
  background: var(--input-background);
@@ -248,6 +248,13 @@ html[data-theme="light"] {
248
248
  --feedback-info-text: var(--blue-900);
249
249
  --feedback-warning-text: var(--orange-900);
250
250
  --feedback-attention-text: var(--red-900);
251
+ /* Feedback - Action (Button & Link) */
252
+ --feedback-neutral-action-background: var(--grey-200);
253
+ --feedback-positive-action-background: var(--green-200);
254
+ --feedback-info-action-background: var(--blue-200);
255
+ --feedback-warning-action-background: var(--orange-200);
256
+ --feedback-attention-action-background: var(--red-200);
257
+
251
258
  /* Action - Primary (Button & Link) */
252
259
  --action-primary-stroke: var(--stroke-size-200) var(--stroke-solid) var(--black-opacity-0);
253
260
  --action-primary-stroke-hover: var(--stroke-size-200) var(--stroke-solid) var(--black-opacity-0);
@@ -403,17 +410,23 @@ html[data-theme="dark"] {
403
410
  --feedback-warning-background: var(--orange-800);
404
411
  --feedback-attention-background: var(--red-800);
405
412
  /* Feedback - Icon (Alerts & Messages) */
406
- --feedback-neutral-icon: var(--grey-300);
407
- --feedback-positive-icon: var(--green-300);
408
- --feedback-info-icon: var(--blue-300);
409
- --feedback-warning-icon: var(--orange-300);
410
- --feedback-attention-icon: var(--red-300);
413
+ --feedback-neutral-icon: var(--grey-200);
414
+ --feedback-positive-icon: var(--green-200);
415
+ --feedback-info-icon: var(--blue-200);
416
+ --feedback-warning-icon: var(--orange-200);
417
+ --feedback-attention-icon: var(--red-200);
411
418
  /* Feedback - Text (Alerts & Messages) */
412
419
  --feedback-neutral-text: var(--grey-100);
413
420
  --feedback-positive-text: var(--green-100);
414
421
  --feedback-info-text: var(--blue-100);
415
422
  --feedback-warning-text: var(--orange-100);
416
423
  --feedback-attention-text: var(--red-100);
424
+ /* Feedback - Action (Button & Link) */
425
+ --feedback-neutral-action-background: var(--grey-900);
426
+ --feedback-positive-action-background: var(--green-900);
427
+ --feedback-info-action-background: var(--blue-900);
428
+ --feedback-warning-action-background: var(--orange-900);
429
+ --feedback-attention-action-background: var(--red-900);
417
430
  /* Action - Primary (Button & Link) */
418
431
  --action-primary-stroke: var(--stroke-size-200) var(--stroke-solid) var(--black-opacity-0);
419
432
  --action-primary-stroke-hover: var(--stroke-size-200) var(--stroke-solid) var(--black-opacity-0);
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@muibook/components",
3
- "version": "1.3.2",
3
+ "version": "1.4.0",
4
+ "type": "module",
4
5
  "description": "A library of MUI-based design system components.",
5
6
  "author": "Michael Trilford",
6
7
  "homepage": "https://muibook.com",
package/readme.md CHANGED
@@ -183,6 +183,23 @@ npm pack --dry-run # Preview what will be published
183
183
  - Use the preview scripts to verify production builds before deployment
184
184
  - Follow semantic versioning for releases
185
185
 
186
+ ### Slot Implementation Approach (MUI Design System)
187
+
188
+ When implementing slots in MUI components, we use a consistent approach for styling and interaction:
189
+
190
+ #### Children Concerns
191
+
192
+ - We use JavaScript to query and manage slotted elements.
193
+ - To apply styles to a slotted item, we append a class in the format: [parent-component]-slot.
194
+ - The slotted component detects this class via :host(.parent-component) and applies the relevant styles.
195
+
196
+ #### Parent Concerns
197
+
198
+ - If the parent component needs to react to the presence of a specific slotted item, we add an attribute like has-[slottedComponentName] to the host.
199
+ - The parent component can then target this via :host([has-slottedComponentName]) for conditional styling.
200
+
201
+ This method keeps slot behavior declarative and styles predictable across components.
202
+
186
203
  ---
187
204
 
188
205
  ### License