@vibe-flags/core 0.1.0 → 0.1.2

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,36 +1,39 @@
1
- import { LitElement as b, html as a, nothing as u, css as w } from "lit";
2
- import { customElement as x, property as f, state as h } from "lit/decorators.js";
3
- var m = Object.getOwnPropertyDescriptor, k = (r, e, t, s) => {
4
- for (var o = s > 1 ? void 0 : s ? m(e, t) : e, i = r.length - 1, n; i >= 0; i--)
5
- (n = r[i]) && (o = n(o) || o);
6
- return o;
1
+ import { LitElement as u, html as a, nothing as y, css as S } from "lit";
2
+ import { customElement as b, property as f, state as c } from "lit/decorators.js";
3
+ var O = Object.getOwnPropertyDescriptor, _ = (t, e, r, o) => {
4
+ for (var s = o > 1 ? void 0 : o ? O(e, r) : e, i = t.length - 1, n; i >= 0; i--)
5
+ (n = t[i]) && (s = n(s) || s);
6
+ return s;
7
7
  };
8
- let y = class extends b {
8
+ let F = class extends u {
9
9
  render() {
10
10
  return a`<slot></slot>`;
11
11
  }
12
12
  };
13
- y = k([
14
- x("vibe-flags")
15
- ], y);
16
- const g = "vibe-flags:";
17
- class S extends EventTarget {
13
+ F = _([
14
+ b("vibe-flags")
15
+ ], F);
16
+ const h = "vibe-flags:";
17
+ function k(t) {
18
+ return t.type === "boolean" ? !1 : t.options[0] || "";
19
+ }
20
+ class M extends EventTarget {
18
21
  constructor() {
19
22
  super(...arguments), this.configs = /* @__PURE__ */ new Map(), this.state = {}, this.listening = !1, this.onStorageEvent = (e) => {
20
- if (!e.key?.startsWith(g)) return;
21
- const t = e.key.slice(g.length);
22
- if (this.configs.has(t))
23
+ if (!e.key?.startsWith(h)) return;
24
+ const r = e.key.slice(h.length), o = this.configs.get(r);
25
+ if (o)
23
26
  try {
24
- const s = e.newValue ? JSON.parse(e.newValue) : this.configs.get(t).default;
25
- this.state[t] = s, this.dispatch(t);
27
+ const s = e.newValue ? JSON.parse(e.newValue) : k(o);
28
+ this.state[r] = s, this.dispatch(r);
26
29
  } catch {
27
30
  }
28
31
  };
29
32
  }
30
33
  register(e) {
31
34
  this.configs.set(e.key, e);
32
- const t = this.readFromStorage(e.key);
33
- this.state[e.key] = t ?? e.default, this.listening || (this.listening = !0, typeof window < "u" && window.addEventListener("storage", this.onStorageEvent)), this.dispatch(e.key);
35
+ const r = this.readFromStorage(e.key);
36
+ this.state[e.key] = r ?? k(e), this.listening || (this.listening = !0, typeof window < "u" && window.addEventListener("storage", this.onStorageEvent)), this.dispatch(e.key);
34
37
  }
35
38
  unregister(e) {
36
39
  this.configs.delete(e), delete this.state[e], this.dispatch();
@@ -38,9 +41,9 @@ class S extends EventTarget {
38
41
  get(e) {
39
42
  return this.state[e];
40
43
  }
41
- set(e, t) {
42
- const s = this.configs.get(e);
43
- s && (s.type === "boolean" && typeof t != "boolean" || s.type === "select" && (typeof t != "string" || !s.options.includes(t)) || (this.state[e] = t, this.writeToStorage(e, t), this.dispatch(e)));
44
+ set(e, r) {
45
+ const o = this.configs.get(e);
46
+ o && (o.type === "boolean" && typeof r != "boolean" || o.type === "select" && (typeof r != "string" || !o.options.includes(r)) || (this.state[e] = r, this.writeToStorage(e, r), this.dispatch(e)));
44
47
  }
45
48
  getAll() {
46
49
  return { ...this.state };
@@ -52,118 +55,201 @@ class S extends EventTarget {
52
55
  return this.configs.get(e);
53
56
  }
54
57
  reset() {
55
- for (const [e, t] of this.configs)
56
- this.state[e] = t.default, this.removeFromStorage(e);
58
+ for (const [e, r] of this.configs)
59
+ this.state[e] = k(r), this.removeFromStorage(e);
57
60
  this.dispatch();
58
61
  }
59
62
  readFromStorage(e) {
60
63
  if (typeof window > "u") return null;
61
64
  try {
62
- const t = localStorage.getItem(g + e);
63
- return t === null ? null : JSON.parse(t);
65
+ const r = localStorage.getItem(h + e);
66
+ return r === null ? null : JSON.parse(r);
64
67
  } catch {
65
68
  return null;
66
69
  }
67
70
  }
68
- writeToStorage(e, t) {
71
+ writeToStorage(e, r) {
69
72
  if (!(typeof window > "u"))
70
73
  try {
71
- localStorage.setItem(g + e, JSON.stringify(t));
74
+ localStorage.setItem(h + e, JSON.stringify(r));
72
75
  } catch {
73
76
  }
74
77
  }
75
78
  removeFromStorage(e) {
76
79
  if (!(typeof window > "u"))
77
80
  try {
78
- localStorage.removeItem(g + e);
81
+ localStorage.removeItem(h + e);
79
82
  } catch {
80
83
  }
81
84
  }
82
85
  dispatch(e) {
83
- const t = { key: e, state: this.getAll() }, s = new CustomEvent("vibe-flags-changed", {
84
- detail: t,
86
+ const r = { key: e, state: this.getAll() }, o = new CustomEvent("vibe-flags-changed", {
87
+ detail: r,
85
88
  bubbles: !0
86
89
  });
87
- this.dispatchEvent(s), typeof window < "u" && window.dispatchEvent(new CustomEvent("vibe-flags-changed", { detail: t }));
90
+ this.dispatchEvent(o), typeof window < "u" && window.dispatchEvent(new CustomEvent("vibe-flags-changed", { detail: r }));
88
91
  }
89
92
  }
90
- const p = new S();
91
- var C = Object.defineProperty, F = Object.getOwnPropertyDescriptor, d = (r, e, t, s) => {
92
- for (var o = s > 1 ? void 0 : s ? F(e, t) : e, i = r.length - 1, n; i >= 0; i--)
93
- (n = r[i]) && (o = (s ? n(e, t, o) : n(o)) || o);
94
- return s && o && C(e, t, o), o;
93
+ const l = new M();
94
+ var E = Object.defineProperty, P = Object.getOwnPropertyDescriptor, g = (t, e, r, o) => {
95
+ for (var s = o > 1 ? void 0 : o ? P(e, r) : e, i = t.length - 1, n; i >= 0; i--)
96
+ (n = t[i]) && (s = (o ? n(e, r, s) : n(s)) || s);
97
+ return o && s && E(e, r, s), s;
95
98
  };
96
- let l = class extends b {
99
+ if (typeof document < "u" && !document.getElementById("vibe-flag-fouc")) {
100
+ const t = document.createElement("style");
101
+ t.id = "vibe-flag-fouc", t.textContent = "vibe-flag-boolean:not(:defined),vibe-flag-boolean:defined,vibe-flag-select:not(:defined),vibe-flag-select:defined,vibe-flag-option:not(:defined),vibe-flag-option:defined{visibility:hidden}", document.head.appendChild(t);
102
+ }
103
+ let p = class extends u {
97
104
  constructor() {
98
- super(...arguments), this.key = "", this.description = "", this.type = "boolean", this.value = "true", this.defaultValue = "", this.options = "", this.isMatch = !1, this.registered = !1, this.onFlagChange = () => {
105
+ super(...arguments), this.name = "", this.description = "", this.value = "", this.isMatch = !1, this.ready = !1, this.onFlagChange = () => {
99
106
  this.evaluate();
100
107
  };
101
108
  }
102
109
  connectedCallback() {
103
- super.connectedCallback(), window.addEventListener("vibe-flags-changed", this.onFlagChange), this.registerFlag(), this.evaluate();
110
+ super.connectedCallback(), window.addEventListener("vibe-flags-changed", this.onFlagChange), this.registerFlag();
104
111
  }
105
112
  disconnectedCallback() {
106
113
  super.disconnectedCallback(), window.removeEventListener("vibe-flags-changed", this.onFlagChange);
107
114
  }
108
- willUpdate(r) {
109
- ["key", "description", "type", "defaultValue", "options"].some((t) => r.has(t)) && this.registerFlag();
115
+ willUpdate(t) {
116
+ (t.has("name") || t.has("description")) && this.registerFlag();
110
117
  }
111
118
  registerFlag() {
112
- if (!this.key) return;
113
- const r = this.type === "select" ? {
114
- key: this.key,
115
- type: "select",
116
- default: this.defaultValue || this.parseOptions()[0] || "",
117
- options: this.parseOptions(),
118
- label: this.description || void 0
119
- } : {
120
- key: this.key,
119
+ this.name && (l.getConfigForKey(this.name) || l.register({
120
+ key: this.name,
121
121
  type: "boolean",
122
- default: this.defaultValue ? this.defaultValue === "true" : !1,
123
122
  label: this.description || void 0
124
- };
125
- p.register(r), this.registered = !0, this.evaluate();
126
- }
127
- parseOptions() {
128
- return this.options.split(",").map((r) => r.trim()).filter(Boolean);
123
+ }), this.evaluate());
129
124
  }
130
125
  evaluate() {
131
- const r = p.get(this.key);
132
- if (r === void 0) {
133
- this.isMatch = !1;
134
- return;
135
- }
136
- this.isMatch = String(r) === this.value;
126
+ const t = l.get(this.name);
127
+ t === void 0 ? this.isMatch = !1 : this.value === "" ? this.isMatch = !0 : this.isMatch = String(t) === this.value, this.ready || (this.ready = !0, this.style.visibility = "visible");
137
128
  }
138
129
  render() {
139
- return this.isMatch ? a`<slot></slot>` : u;
130
+ return this.isMatch ? a`<slot></slot>` : y;
140
131
  }
141
132
  };
142
- d([
133
+ g([
143
134
  f({ type: String })
144
- ], l.prototype, "key", 2);
145
- d([
135
+ ], p.prototype, "name", 2);
136
+ g([
146
137
  f({ type: String })
147
- ], l.prototype, "description", 2);
148
- d([
138
+ ], p.prototype, "description", 2);
139
+ g([
149
140
  f({ type: String })
150
- ], l.prototype, "type", 2);
151
- d([
141
+ ], p.prototype, "value", 2);
142
+ g([
143
+ c()
144
+ ], p.prototype, "isMatch", 2);
145
+ g([
146
+ c()
147
+ ], p.prototype, "ready", 2);
148
+ p = g([
149
+ b("vibe-flag-boolean")
150
+ ], p);
151
+ var T = Object.defineProperty, j = Object.getOwnPropertyDescriptor, w = (t, e, r, o) => {
152
+ for (var s = o > 1 ? void 0 : o ? j(e, r) : e, i = t.length - 1, n; i >= 0; i--)
153
+ (n = t[i]) && (s = (o ? n(e, r, s) : n(s)) || s);
154
+ return o && s && T(e, r, s), s;
155
+ };
156
+ let v = class extends u {
157
+ constructor() {
158
+ super(...arguments), this.name = "", this.description = "", this.ready = !1, this.onFlagChange = () => {
159
+ this.syncOptions();
160
+ };
161
+ }
162
+ connectedCallback() {
163
+ super.connectedCallback(), window.addEventListener("vibe-flags-changed", this.onFlagChange), queueMicrotask(() => this.registerFlag());
164
+ }
165
+ disconnectedCallback() {
166
+ super.disconnectedCallback(), window.removeEventListener("vibe-flags-changed", this.onFlagChange);
167
+ }
168
+ willUpdate(t) {
169
+ (t.has("name") || t.has("description")) && this.registerFlag();
170
+ }
171
+ getOptions() {
172
+ return Array.from(this.querySelectorAll("vibe-flag-option"));
173
+ }
174
+ registerFlag() {
175
+ if (!this.name) return;
176
+ const t = this.getOptions().map((e) => e.value).filter(Boolean);
177
+ t.length !== 0 && (l.getConfigForKey(this.name) || l.register({
178
+ key: this.name,
179
+ type: "select",
180
+ options: t,
181
+ label: this.description || void 0
182
+ }), this.syncOptions());
183
+ }
184
+ syncOptions() {
185
+ const t = l.get(this.name);
186
+ for (const e of this.getOptions())
187
+ e.active = e.value === t;
188
+ this.ready || (this.ready = !0, this.style.visibility = "visible");
189
+ }
190
+ render() {
191
+ return a`<slot></slot>`;
192
+ }
193
+ };
194
+ w([
152
195
  f({ type: String })
153
- ], l.prototype, "value", 2);
154
- d([
155
- f({ type: String, attribute: "default" })
156
- ], l.prototype, "defaultValue", 2);
157
- d([
196
+ ], v.prototype, "name", 2);
197
+ w([
158
198
  f({ type: String })
159
- ], l.prototype, "options", 2);
160
- d([
161
- h()
162
- ], l.prototype, "isMatch", 2);
163
- l = d([
164
- x("vibe-flag")
165
- ], l);
166
- const $ = w`
199
+ ], v.prototype, "description", 2);
200
+ w([
201
+ c()
202
+ ], v.prototype, "ready", 2);
203
+ v = w([
204
+ b("vibe-flag-select")
205
+ ], v);
206
+ var I = Object.defineProperty, z = Object.getOwnPropertyDescriptor, C = (t, e, r, o) => {
207
+ for (var s = o > 1 ? void 0 : o ? z(e, r) : e, i = t.length - 1, n; i >= 0; i--)
208
+ (n = t[i]) && (s = (o ? n(e, r, s) : n(s)) || s);
209
+ return o && s && I(e, r, s), s;
210
+ };
211
+ let m = class extends u {
212
+ constructor() {
213
+ super(...arguments), this.value = "", this.active = !1;
214
+ }
215
+ render() {
216
+ return this.active ? a`<slot></slot>` : y;
217
+ }
218
+ };
219
+ C([
220
+ f({ type: String })
221
+ ], m.prototype, "value", 2);
222
+ C([
223
+ c()
224
+ ], m.prototype, "active", 2);
225
+ m = C([
226
+ b("vibe-flag-option")
227
+ ], m);
228
+ const D = S`
229
+ :host {
230
+ --vf-bg: #0a0a0a;
231
+ --vf-bg-muted: #171717;
232
+ --vf-bg-hover: #262626;
233
+ --vf-border: #2e2e2e;
234
+ --vf-text: #fafafa;
235
+ --vf-text-muted: #a3a3a3;
236
+ --vf-primary: #fafafa;
237
+ --vf-primary-fg: #0a0a0a;
238
+ --vf-accent: #818cf8;
239
+ --vf-accent-fg: #ffffff;
240
+ --vf-destructive: #ef4444;
241
+ --vf-radius: 6px;
242
+ --vf-radius-lg: 8px;
243
+ --vf-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
244
+ 'Helvetica Neue', Arial, sans-serif;
245
+ --vf-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4),
246
+ 0 1px 2px -1px rgba(0, 0, 0, 0.4);
247
+ --vf-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5),
248
+ 0 4px 6px -4px rgba(0, 0, 0, 0.5);
249
+ --vf-shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6),
250
+ 0 8px 10px -6px rgba(0, 0, 0, 0.6);
251
+ }
252
+ `, B = S`
167
253
  :host {
168
254
  --vf-bg: #ffffff;
169
255
  --vf-bg-muted: #f5f5f5;
@@ -188,25 +274,41 @@ const $ = w`
188
274
  0 8px 10px -6px rgba(0, 0, 0, 0.1);
189
275
  }
190
276
  `;
191
- var O = Object.defineProperty, E = Object.getOwnPropertyDescriptor, v = (r, e, t, s) => {
192
- for (var o = s > 1 ? void 0 : s ? E(e, t) : e, i = r.length - 1, n; i >= 0; i--)
193
- (n = r[i]) && (o = (s ? n(e, t, o) : n(o)) || o);
194
- return s && o && O(e, t, o), o;
277
+ var A = Object.defineProperty, V = Object.getOwnPropertyDescriptor, x = (t, e, r, o) => {
278
+ for (var s = o > 1 ? void 0 : o ? V(e, r) : e, i = t.length - 1, n; i >= 0; i--)
279
+ (n = t[i]) && (s = (o ? n(e, r, s) : n(s)) || s);
280
+ return o && s && A(e, r, s), s;
195
281
  };
196
- let c = class extends b {
282
+ const $ = "vibeFlagsTheme";
283
+ let d = class extends u {
197
284
  constructor() {
198
- super(...arguments), this.open = !1, this.flags = {}, this.configs = [], this.onFlagChange = () => {
285
+ super(...arguments), this.open = !1, this.flags = {}, this.configs = [], this.darkMode = !0, this.onFlagChange = () => {
199
286
  this.syncFromStore();
200
287
  };
201
288
  }
202
289
  connectedCallback() {
203
- super.connectedCallback(), window.addEventListener("vibe-flags-changed", this.onFlagChange), this.syncFromStore();
290
+ super.connectedCallback(), window.addEventListener("vibe-flags-changed", this.onFlagChange), this.syncFromStore(), this.loadTheme();
204
291
  }
205
292
  disconnectedCallback() {
206
293
  super.disconnectedCallback(), window.removeEventListener("vibe-flags-changed", this.onFlagChange);
207
294
  }
295
+ loadTheme() {
296
+ if (typeof window > "u") return;
297
+ const t = localStorage.getItem($);
298
+ this.darkMode = t ? t === "dark" : !0, this.applyTheme();
299
+ }
300
+ toggleTheme() {
301
+ this.darkMode = !this.darkMode, localStorage.setItem($, this.darkMode ? "dark" : "light"), this.applyTheme();
302
+ }
303
+ applyTheme() {
304
+ const t = this.darkMode ? D : B, e = new CSSStyleSheet();
305
+ e.replaceSync(t.cssText), this.shadowRoot.adoptedStyleSheets = [
306
+ ...d.elementStyles.map((r) => r.styleSheet),
307
+ e
308
+ ];
309
+ }
208
310
  syncFromStore() {
209
- this.configs = p.getConfig(), this.flags = p.getAll();
311
+ this.configs = l.getConfig(), this.flags = l.getAll();
210
312
  }
211
313
  toggleSidebar() {
212
314
  this.open = !this.open;
@@ -214,16 +316,16 @@ let c = class extends b {
214
316
  closeSidebar() {
215
317
  this.open = !1;
216
318
  }
217
- onToggle(r) {
218
- const e = this.flags[r];
219
- p.set(r, !e);
319
+ onToggle(t) {
320
+ const e = this.flags[t];
321
+ l.set(t, !e);
220
322
  }
221
- onSelect(r, e) {
222
- const t = e.target;
223
- p.set(r, t.value);
323
+ onSelect(t, e) {
324
+ const r = e.target;
325
+ l.set(t, r.value);
224
326
  }
225
327
  onReset() {
226
- p.reset();
328
+ l.reset();
227
329
  }
228
330
  renderFlagIcon() {
229
331
  return a`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>`;
@@ -234,20 +336,26 @@ let c = class extends b {
234
336
  renderChevronDown() {
235
337
  return a`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
236
338
  }
237
- renderBooleanFlag(r) {
238
- const e = this.flags[r.key] === !0;
339
+ renderSunIcon() {
340
+ return a`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>`;
341
+ }
342
+ renderMoonIcon() {
343
+ return a`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>`;
344
+ }
345
+ renderBooleanFlag(t) {
346
+ const e = this.flags[t.key] === !0;
239
347
  return a`
240
348
  <div class="flag-item">
241
349
  <div class="flag-row">
242
350
  <div class="flag-info">
243
- <div class="flag-label">${r.label || r.key}</div>
244
- <div class="flag-key">${r.key}</div>
351
+ <div class="flag-label">${t.label || t.key}</div>
352
+ <div class="flag-key">${t.key}</div>
245
353
  </div>
246
354
  <label class="toggle">
247
355
  <input
248
356
  type="checkbox"
249
357
  .checked=${e}
250
- @change=${() => this.onToggle(r.key)}
358
+ @change=${() => this.onToggle(t.key)}
251
359
  />
252
360
  <span class="toggle-track"></span>
253
361
  <span class="toggle-thumb"></span>
@@ -256,25 +364,25 @@ let c = class extends b {
256
364
  </div>
257
365
  `;
258
366
  }
259
- renderSelectFlag(r) {
260
- if (r.type !== "select") return u;
261
- const e = this.flags[r.key];
367
+ renderSelectFlag(t) {
368
+ if (t.type !== "select") return y;
369
+ const e = this.flags[t.key];
262
370
  return a`
263
371
  <div class="flag-item">
264
372
  <div class="flag-row">
265
373
  <div class="flag-info">
266
- <div class="flag-label">${r.label || r.key}</div>
267
- <div class="flag-key">${r.key}</div>
374
+ <div class="flag-label">${t.label || t.key}</div>
375
+ <div class="flag-key">${t.key}</div>
268
376
  </div>
269
377
  <div class="select-wrapper">
270
378
  <select
271
379
  class="select"
272
380
  .value=${e}
273
- @change=${(t) => this.onSelect(r.key, t)}
381
+ @change=${(r) => this.onSelect(t.key, r)}
274
382
  >
275
- ${r.options.map(
276
- (t) => a`<option value=${t} ?selected=${t === e}>
277
- ${t}
383
+ ${t.options.map(
384
+ (r) => a`<option value=${r} ?selected=${r === e}>
385
+ ${r}
278
386
  </option>`
279
387
  )}
280
388
  </select>
@@ -286,7 +394,7 @@ let c = class extends b {
286
394
  }
287
395
  render() {
288
396
  return a`
289
- ${this.open ? u : a`
397
+ ${this.open ? y : a`
290
398
  <button class="fab" @click=${this.toggleSidebar} aria-label="Toggle feature flags">
291
399
  ${this.renderFlagIcon()}
292
400
  </button>
@@ -301,14 +409,19 @@ let c = class extends b {
301
409
  VibeFlags
302
410
  <span class="badge">${this.configs.length}</span>
303
411
  </h2>
304
- <button class="close-btn" @click=${this.closeSidebar} aria-label="Close">
305
- ${this.renderCloseIcon()}
306
- </button>
412
+ <div class="header-actions">
413
+ <button class="icon-btn" @click=${this.toggleTheme} aria-label="Toggle theme" title="${this.darkMode ? "Switch to light theme" : "Switch to dark theme"}">
414
+ ${this.darkMode ? this.renderSunIcon() : this.renderMoonIcon()}
415
+ </button>
416
+ <button class="icon-btn" @click=${this.closeSidebar} aria-label="Close">
417
+ ${this.renderCloseIcon()}
418
+ </button>
419
+ </div>
307
420
  </div>
308
421
 
309
422
  <div class="flags">
310
423
  ${this.configs.length === 0 ? a`<div class="empty">No flags configured</div>` : this.configs.map(
311
- (r) => r.type === "boolean" ? this.renderBooleanFlag(r) : this.renderSelectFlag(r)
424
+ (t) => t.type === "boolean" ? this.renderBooleanFlag(t) : this.renderSelectFlag(t)
312
425
  )}
313
426
  </div>
314
427
 
@@ -321,9 +434,8 @@ let c = class extends b {
321
434
  `;
322
435
  }
323
436
  };
324
- c.styles = [
325
- $,
326
- w`
437
+ d.styles = [
438
+ S`
327
439
  * {
328
440
  box-sizing: border-box;
329
441
  margin: 0;
@@ -410,6 +522,12 @@ c.styles = [
410
522
  flex-shrink: 0;
411
523
  }
412
524
 
525
+ .header-left {
526
+ display: flex;
527
+ align-items: center;
528
+ gap: 8px;
529
+ }
530
+
413
531
  .header h2 {
414
532
  font-size: 16px;
415
533
  font-weight: 600;
@@ -425,6 +543,12 @@ c.styles = [
425
543
  color: var(--vf-accent);
426
544
  }
427
545
 
546
+ .header-actions {
547
+ display: flex;
548
+ align-items: center;
549
+ gap: 4px;
550
+ }
551
+
428
552
  .badge {
429
553
  font-size: 11px;
430
554
  font-weight: 500;
@@ -435,7 +559,7 @@ c.styles = [
435
559
  border: 1px solid var(--vf-border);
436
560
  }
437
561
 
438
- .close-btn {
562
+ .icon-btn {
439
563
  width: 32px;
440
564
  height: 32px;
441
565
  border: none;
@@ -449,12 +573,12 @@ c.styles = [
449
573
  transition: all 0.15s ease;
450
574
  }
451
575
 
452
- .close-btn:hover {
576
+ .icon-btn:hover {
453
577
  background: var(--vf-bg-muted);
454
578
  color: var(--vf-text);
455
579
  }
456
580
 
457
- .close-btn svg {
581
+ .icon-btn svg {
458
582
  width: 16px;
459
583
  height: 16px;
460
584
  }
@@ -627,21 +751,26 @@ c.styles = [
627
751
  }
628
752
  `
629
753
  ];
630
- v([
631
- h()
632
- ], c.prototype, "open", 2);
633
- v([
634
- h()
635
- ], c.prototype, "flags", 2);
636
- v([
637
- h()
638
- ], c.prototype, "configs", 2);
639
- c = v([
640
- x("vibe-toolbar")
641
- ], c);
754
+ x([
755
+ c()
756
+ ], d.prototype, "open", 2);
757
+ x([
758
+ c()
759
+ ], d.prototype, "flags", 2);
760
+ x([
761
+ c()
762
+ ], d.prototype, "configs", 2);
763
+ x([
764
+ c()
765
+ ], d.prototype, "darkMode", 2);
766
+ d = x([
767
+ b("vibe-toolbar")
768
+ ], d);
642
769
  export {
643
- l as VibeFlag,
644
- y as VibeFlags,
645
- c as VibeToolbar,
646
- p as flagStore
770
+ p as VibeFlagBoolean,
771
+ m as VibeFlagOption,
772
+ v as VibeFlagSelect,
773
+ F as VibeFlags,
774
+ d as VibeToolbar,
775
+ l as flagStore
647
776
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-flags/core",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/vibe-flags.js",
6
6
  "module": "./dist/vibe-flags.js",