@noirmd/previewer 2.1.2 → 2.1.3

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.
package/dist/card.css CHANGED
@@ -1,143 +1,151 @@
1
- /* ============================================================
2
- NoirMD Vanilla — Card
3
- ============================================================ */
4
-
5
- .nr-card-grid {
6
- display: flex;
7
- flex-wrap: wrap;
8
- gap: 1.5rem;
9
- margin: 1.5rem 0;
10
- }
11
-
12
- .nr-card {
13
- display: flex;
14
- flex-direction: column;
15
- height: 100%;
16
- border-radius: var(--nr-radius-lg);
17
- border: 1px solid var(--nr-border);
18
- transition: all 0.2s;
19
- position: relative;
20
- overflow: hidden;
21
- min-width: 18rem;
22
- width: 18rem;
23
- max-width: 20rem;
24
- }
25
-
26
- .nr-card--interactive {
27
- cursor: pointer;
28
- border-color: rgba(14, 165, 233, 0.1);
29
- }
30
- .nr-card--interactive:hover {
31
- border-color: rgba(14, 165, 233, 0.5);
32
- }
33
-
34
- .nr-card__image {
35
- width: 100%;
36
- height: 160px;
37
- overflow: hidden;
38
- position: relative;
39
- }
40
- .nr-card__image--tall {
41
- height: 240px;
42
- }
43
-
44
- .nr-card__img {
45
- width: 100%;
46
- height: 100%;
47
- object-fit: cover;
48
- margin: 0;
49
- }
50
-
51
- .nr-card__gradient {
52
- position: absolute;
53
- inset: 0;
54
- background: linear-gradient(to top, color-mix(in srgb, var(--nr-bg) 40%, transparent), transparent);
55
- }
56
-
57
- .nr-card__body {
58
- display: flex;
59
- flex-direction: column;
60
- flex: 1;
61
- padding: 1.5rem;
62
- position: relative;
63
- border-top: 1px solid rgba(255, 255, 255, 0.05);
64
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
65
- }
66
- .nr-card__body--overlap {
67
- margin-top: -2.5rem;
68
- background: color-mix(in srgb, var(--nr-bg) 80%, transparent);
69
- border-radius: 0.75rem 0.75rem 0 0;
70
- }
71
-
72
- .nr-card__header {
73
- display: flex;
74
- align-items: center;
75
- gap: 0.75rem;
76
- margin-bottom: 0.75rem;
77
- }
78
-
79
- .nr-card__icon-wrap {
80
- width: 2.5rem;
81
- height: 2.5rem;
82
- font-size: 1.6em;
83
- border-radius: 0.75rem;
84
- background: rgba(14, 165, 233, 0.2);
85
- display: flex;
86
- align-items: center;
87
- justify-content: center;
88
- flex-shrink: 0;
89
- color: var(--nr-accent);
90
- }
91
-
92
- .nr-card__title {
93
- font-size: 1rem;
94
- font-weight: 900;
95
- letter-spacing: -0.025em;
96
- line-height: 1.25;
97
- margin: 0;
98
- }
99
-
100
- .nr-card__description {
101
- font-size: 0.875rem;
102
- opacity: 0.8;
103
- line-height: 1.625;
104
- font-weight: 500;
105
- }
106
-
107
- .nr-card__content {
108
- margin-top: 0.5rem;
109
- display: flex;
110
- flex-direction: column;
111
- gap: 0.5rem;
112
- flex: 1;
113
- }
114
-
115
- .nr-card__action {
116
- margin-top: 1.5rem;
117
- display: flex;
118
- justify-content: flex-end;
119
- }
120
-
121
- .nr-card__action-link {
122
- background: rgba(14, 165, 233, 0.2);
123
- padding: 0.5rem 1rem;
124
- border-radius: 0.75rem;
125
- display: flex;
126
- align-items: center;
127
- gap: 0.375rem;
128
- font-size: 0.625rem;
129
- font-weight: 900;
130
- text-transform: uppercase;
131
- letter-spacing: 0.1em;
132
- opacity: 0.5;
133
- color: var(--nr-text);
134
- text-decoration: none;
135
- transition: all 0.15s;
136
- }
137
- .nr-card:hover .nr-card__action-link {
138
- opacity: 1;
139
- color: var(--nr-accent);
140
- }
141
- .nr-card__action-link:hover {
142
- background: rgba(14, 165, 233, 0.3);
1
+ /* ============================================================
2
+ NoirMD Vanilla — Card
3
+ ============================================================ */
4
+
5
+ .nr-card-grid {
6
+ display: grid;
7
+ grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
8
+ gap: 1.5rem;
9
+ margin: 1.5rem 0;
10
+ }
11
+
12
+ /* ── Alignment variants ── */
13
+ .nr-card-grid--center {
14
+ justify-items: center;
15
+ }
16
+ .nr-card-grid--right {
17
+ justify-items: end;
18
+ }
19
+
20
+ .nr-card {
21
+ display: flex;
22
+ flex-direction: column;
23
+ height: 100%;
24
+ border-radius: var(--nr-radius-lg);
25
+ border: 1px solid var(--nr-border);
26
+ transition: all 0.2s;
27
+ position: relative;
28
+ overflow: hidden;
29
+ min-width: 0;
30
+ max-width: 20rem;
31
+ width: 100%;
32
+ }
33
+
34
+ .nr-card--interactive {
35
+ cursor: pointer;
36
+ border-color: rgba(14, 165, 233, 0.1);
37
+ }
38
+ .nr-card--interactive:hover {
39
+ border-color: rgba(14, 165, 233, 0.5);
40
+ }
41
+
42
+ .nr-card__image {
43
+ width: 100%;
44
+ height: 160px;
45
+ overflow: hidden;
46
+ position: relative;
47
+ }
48
+ .nr-card__image--tall {
49
+ height: 240px;
50
+ }
51
+
52
+ .nr-card__img {
53
+ width: 100%;
54
+ height: 100%;
55
+ object-fit: cover;
56
+ margin: 0;
57
+ }
58
+
59
+ .nr-card__gradient {
60
+ position: absolute;
61
+ inset: 0;
62
+ background: linear-gradient(to top, color-mix(in srgb, var(--nr-bg) 40%, transparent), transparent);
63
+ }
64
+
65
+ .nr-card__body {
66
+ display: flex;
67
+ flex-direction: column;
68
+ flex: 1;
69
+ padding: 1.5rem;
70
+ position: relative;
71
+ border-top: 1px solid rgba(255, 255, 255, 0.05);
72
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
73
+ }
74
+ .nr-card__body--overlap {
75
+ margin-top: -2.5rem;
76
+ background: color-mix(in srgb, var(--nr-bg) 80%, transparent);
77
+ border-radius: 0.75rem 0.75rem 0 0;
78
+ }
79
+
80
+ .nr-card__header {
81
+ display: flex;
82
+ align-items: center;
83
+ gap: 0.75rem;
84
+ margin-bottom: 0.75rem;
85
+ }
86
+
87
+ .nr-card__icon-wrap {
88
+ width: 2.5rem;
89
+ height: 2.5rem;
90
+ font-size: 1.6em;
91
+ border-radius: 0.75rem;
92
+ background: rgba(14, 165, 233, 0.2);
93
+ display: flex;
94
+ align-items: center;
95
+ justify-content: center;
96
+ flex-shrink: 0;
97
+ color: var(--nr-accent);
98
+ }
99
+
100
+ .nr-card__title {
101
+ font-size: 1rem;
102
+ font-weight: 900;
103
+ letter-spacing: -0.025em;
104
+ line-height: 1.25;
105
+ margin: 0;
106
+ }
107
+
108
+ .nr-card__description {
109
+ font-size: 0.875rem;
110
+ opacity: 0.8;
111
+ line-height: 1.625;
112
+ font-weight: 500;
113
+ }
114
+
115
+ .nr-card__content {
116
+ margin-top: 0.5rem;
117
+ display: flex;
118
+ flex-direction: column;
119
+ gap: 0.5rem;
120
+ flex: 1;
121
+ }
122
+
123
+ .nr-card__action {
124
+ margin-top: 1.5rem;
125
+ display: flex;
126
+ justify-content: flex-end;
127
+ }
128
+
129
+ .nr-card__action-link {
130
+ background: rgba(14, 165, 233, 0.2);
131
+ padding: 0.5rem 1rem;
132
+ border-radius: 0.75rem;
133
+ display: flex;
134
+ align-items: center;
135
+ gap: 0.375rem;
136
+ font-size: 0.625rem;
137
+ font-weight: 900;
138
+ text-transform: uppercase;
139
+ letter-spacing: 0.1em;
140
+ opacity: 0.5;
141
+ color: var(--nr-text);
142
+ text-decoration: none;
143
+ transition: all 0.15s;
144
+ }
145
+ .nr-card:hover .nr-card__action-link {
146
+ opacity: 1;
147
+ color: var(--nr-accent);
148
+ }
149
+ .nr-card__action-link:hover {
150
+ background: rgba(14, 165, 233, 0.3);
143
151
  }
package/dist/index.cjs CHANGED
@@ -12020,6 +12020,22 @@ var hovergalleryDirective = ({ props, slots }) => {
12020
12020
  var hovergallery_default = hovergalleryDirective;
12021
12021
 
12022
12022
  // vanilla/directives/chat.ts
12023
+ var CHAT_THEME_TOKENS = /* @__PURE__ */ new Set([
12024
+ "primary",
12025
+ "secondary",
12026
+ "accent",
12027
+ "neutral",
12028
+ "info",
12029
+ "success",
12030
+ "warning",
12031
+ "error"
12032
+ ]);
12033
+ function isArbitraryColor(value) {
12034
+ if (CHAT_THEME_TOKENS.has(value)) return false;
12035
+ if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
12036
+ if (/^[a-zA-Z]+$/.test(value)) return true;
12037
+ return false;
12038
+ }
12023
12039
  var chatItemDirective = ({ props, renderSlot }) => {
12024
12040
  const side = props.side === "end" ? "end" : "start";
12025
12041
  const wrap = document.createElement("div");
@@ -12050,8 +12066,14 @@ var chatItemDirective = ({ props, renderSlot }) => {
12050
12066
  avatar.appendChild(img);
12051
12067
  wrap.appendChild(avatar);
12052
12068
  }
12069
+ const isThemeToken = CHAT_THEME_TOKENS.has(props.color || "");
12070
+ const colorClass = isThemeToken ? ` nr-chat__bubble--${props.color}` : "";
12053
12071
  const bubble = document.createElement("div");
12054
- bubble.className = `nr-chat__bubble${props.color ? ` nr-chat__bubble--${props.color}` : ""}`;
12072
+ bubble.className = `nr-chat__bubble${colorClass}`;
12073
+ if (props.color && isArbitraryColor(props.color) && !isThemeToken) {
12074
+ bubble.style.background = props.color;
12075
+ bubble.style.color = "white";
12076
+ }
12055
12077
  bubble.appendChild(renderSlot("default"));
12056
12078
  wrap.appendChild(bubble);
12057
12079
  if (props.footer) {
@@ -12173,15 +12195,32 @@ var richlistDirective = ({ props, renderSlot }) => {
12173
12195
  var richlist_default = richlistDirective;
12174
12196
 
12175
12197
  // vanilla/directives/stat.ts
12198
+ var STAT_THEME_TOKENS = /* @__PURE__ */ new Set([
12199
+ "primary",
12200
+ "secondary",
12201
+ "info",
12202
+ "success",
12203
+ "warning",
12204
+ "error"
12205
+ ]);
12206
+ function isArbitraryColor2(value) {
12207
+ if (STAT_THEME_TOKENS.has(value)) return false;
12208
+ if (/^(#|rgb|hsl|oklch|oklab|lab|lch|color\()/i.test(value)) return true;
12209
+ if (/^[a-zA-Z]+$/.test(value)) return true;
12210
+ return false;
12211
+ }
12176
12212
  var statDirective = ({ props }) => {
12177
- const colorClass = props.color ? ` nr-stat--${props.color}` : "";
12213
+ const isThemeToken = STAT_THEME_TOKENS.has(props.color || "");
12214
+ const colorClass = isThemeToken ? ` nr-stat--${props.color}` : "";
12178
12215
  const stat = document.createElement("div");
12179
12216
  stat.className = `nr-stat${colorClass}`;
12180
12217
  if (props.class) stat.classList.add(...props.class.split(/\s+/).filter(Boolean));
12181
12218
  if (props.style) stat.setAttribute("style", props.style);
12219
+ const useInlineColor = props.color && isArbitraryColor2(props.color) && !isThemeToken;
12182
12220
  if (props.icon) {
12183
12221
  const figure = document.createElement("div");
12184
12222
  figure.className = "nr-stat__figure";
12223
+ if (useInlineColor) figure.style.color = props.color;
12185
12224
  figure.appendChild(createIcon(props.icon));
12186
12225
  stat.appendChild(figure);
12187
12226
  }
@@ -12194,6 +12233,7 @@ var statDirective = ({ props }) => {
12194
12233
  if (props.value) {
12195
12234
  const value = document.createElement("div");
12196
12235
  value.className = "nr-stat__value";
12236
+ if (useInlineColor) value.style.color = props.color;
12197
12237
  value.textContent = props.value;
12198
12238
  stat.appendChild(value);
12199
12239
  }
@@ -12320,7 +12360,9 @@ function processElements(elements, ctx, allElements) {
12320
12360
  }
12321
12361
  } else {
12322
12362
  const grid = document.createElement("div");
12323
- grid.className = BATCHED_DIRECTIVES[cards[0].directiveType];
12363
+ const gridClass = BATCHED_DIRECTIVES[cards[0].directiveType];
12364
+ const align = cards[0].props?.align;
12365
+ grid.className = align === "center" || align === "right" ? `${gridClass} ${gridClass}--${align}` : gridClass;
12324
12366
  for (const card of cards) {
12325
12367
  const rendered = renderElement(card, ctx, allElements);
12326
12368
  if (rendered) grid.appendChild(rendered);