@strands.gg/accui 2.15.11 → 2.15.14

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.
Files changed (30) hide show
  1. package/dist/StrandsUIPlugin-D9RVai-I.cjs.js +1 -0
  2. package/dist/{StrandsUIPlugin-JP858JzQ.es.js → StrandsUIPlugin-Dws5Nqi_.es.js} +243 -53
  3. package/dist/accui.css +1 -1
  4. package/dist/index.cjs.js +1 -1
  5. package/dist/index.es.js +67 -18
  6. package/dist/vite.cjs.js +1 -1
  7. package/dist/vite.es.js +1 -1
  8. package/dist/webcomponents/define-element.d.ts +25 -0
  9. package/dist/webcomponents/entries/strands-alert.d.ts +12 -0
  10. package/dist/webcomponents/entries/strands-button.d.ts +12 -0
  11. package/dist/webcomponents/entries/strands-card.d.ts +12 -0
  12. package/dist/webcomponents/entries/strands-checkbox-group.d.ts +11 -0
  13. package/dist/webcomponents/entries/strands-divider.d.ts +12 -0
  14. package/dist/webcomponents/entries/strands-input.d.ts +14 -0
  15. package/dist/webcomponents/entries/strands-link.d.ts +12 -0
  16. package/dist/webcomponents/entries/strands-loader-spinner.d.ts +10 -0
  17. package/dist/webcomponents/entries/strands-modal.d.ts +16 -0
  18. package/dist/webcomponents/entries/strands-pill.d.ts +11 -0
  19. package/dist/webcomponents/entries/strands-radio-group.d.ts +11 -0
  20. package/dist/webcomponents/entries/strands-slider.d.ts +10 -0
  21. package/dist/webcomponents/entries/strands-table.d.ts +13 -0
  22. package/dist/webcomponents/entries/strands-tabs.d.ts +12 -0
  23. package/dist/webcomponents/entries/strands-theme-toggle.d.ts +10 -0
  24. package/dist/webcomponents/entries/strands-toggle.d.ts +10 -0
  25. package/dist/webcomponents/entries/strands-tooltip.d.ts +12 -0
  26. package/dist/webcomponents/index.d.ts +8 -0
  27. package/dist/webcomponents/loader.d.ts +73 -0
  28. package/dist/webcomponents/registry.d.ts +41 -0
  29. package/package.json +3 -1
  30. package/dist/StrandsUIPlugin-DSCUXdBp.cjs.js +0 -1
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
- import { _ as _export_sfc, S as StrandsUiButton, U as UiButtonContent, a as _sfc_main$G, b as _sfc_main$H, c as _sfc_main$I, d as createLucideIcon, M as Minus, e as StrandsUiCard, f as UiTooltip, g as UiDivider, u as useFloatingPosition, C as ChevronDown, h as StrandsUiInput, i as StrandsUiLoader, j as StrandsUiTabs, k as StrandsUiLink, l as StrandsUiAlert } from "./StrandsUIPlugin-JP858JzQ.es.js";
2
- import { m } from "./StrandsUIPlugin-JP858JzQ.es.js";
3
- import { defineComponent, computed, provide, onMounted, onUnmounted, createElementBlock, openBlock, normalizeClass, createElementVNode, createBlock, renderSlot, Teleport, createCommentVNode, toDisplayString, createTextVNode, ref, reactive, watch, withModifiers, createStaticVNode, createVNode, withDirectives, withCtx, unref, vModelText, nextTick, Fragment, Transition, createSlots, normalizeStyle, renderList, mergeProps, useSlots, inject, resolveDynamicComponent, onBeforeUnmount, withKeys, h, isMemoSame, getCurrentInstance } from "vue";
1
+ import { _ as _export_sfc, S as StrandsUiButton, U as UiButtonContent, a as _sfc_main$G, b as _sfc_main$H, c as _sfc_main$I, d as createLucideIcon, M as Minus, e as StrandsUiCard, f as UiTooltip, g as UiDivider, u as useFloatingPosition, C as ChevronDown, h as StrandsUiInput, i as StrandsUiLoader, j as StrandsUiTabs, k as StrandsUiLink, l as StrandsUiAlert } from "./StrandsUIPlugin-Dws5Nqi_.es.js";
2
+ import { m } from "./StrandsUIPlugin-Dws5Nqi_.es.js";
3
+ import { defineComponent, computed, provide, onMounted, onUnmounted, createElementBlock, openBlock, normalizeClass, createElementVNode, createBlock, renderSlot, Teleport, createCommentVNode, toDisplayString, ref, watch, createTextVNode, reactive, withModifiers, createStaticVNode, createVNode, withDirectives, withCtx, unref, vModelText, nextTick, Fragment, Transition, createSlots, normalizeStyle, renderList, mergeProps, useSlots, inject, resolveDynamicComponent, onBeforeUnmount, withKeys, h, isMemoSame, getCurrentInstance } from "vue";
4
4
  import { u as useStrandsConfig, p as provideStrandsConfig } from "./useStrandsConfig-fRu-OG08.es.js";
5
5
  import { s } from "./useStrandsConfig-fRu-OG08.es.js";
6
6
  import { u as useStrandsAuth } from "./useStrandsAuth-BCnUxo-R.es.js";
@@ -216,34 +216,60 @@ const _hoisted_4$u = ["id", "aria-pressed", "aria-labelledby"];
216
216
  const _sfc_main$E = /* @__PURE__ */ defineComponent({
217
217
  __name: "UiToggle",
218
218
  props: {
219
- modelValue: { type: Boolean, default: false },
219
+ modelValue: { type: Boolean, default: void 0 },
220
+ checked: { type: [Boolean, String], default: void 0 },
220
221
  disabled: { type: Boolean, default: false },
221
222
  id: {},
222
223
  label: {},
223
224
  required: { type: Boolean }
224
225
  },
225
- emits: ["update:modelValue"],
226
+ emits: ["update:modelValue", "change"],
226
227
  setup(__props, { emit: __emit }) {
227
228
  const props = __props;
228
229
  const emit = __emit;
230
+ const internalValue = ref(false);
231
+ const isChecked = computed(() => {
232
+ if (props.modelValue !== void 0) {
233
+ return Boolean(props.modelValue);
234
+ }
235
+ if (props.checked !== void 0) {
236
+ if (typeof props.checked === "string") {
237
+ return props.checked === "" || props.checked === "true";
238
+ }
239
+ return Boolean(props.checked);
240
+ }
241
+ return internalValue.value;
242
+ });
243
+ watch(() => props.checked, (newVal) => {
244
+ if (newVal !== void 0) {
245
+ if (typeof newVal === "string") {
246
+ internalValue.value = newVal === "" || newVal === "true";
247
+ } else {
248
+ internalValue.value = Boolean(newVal);
249
+ }
250
+ }
251
+ }, { immediate: true });
229
252
  const toggleId = computed(() => props.id || `ui-toggle-${Math.random().toString(36).substr(2, 9)}`);
230
253
  const toggleClasses = computed(() => [
231
254
  "ui-toggle",
232
255
  {
233
- "ui-toggle--on": props.modelValue,
234
- "ui-toggle--off": !props.modelValue,
256
+ "ui-toggle--on": isChecked.value,
257
+ "ui-toggle--off": !isChecked.value,
235
258
  "ui-toggle--disabled": props.disabled
236
259
  }
237
260
  ]);
238
261
  const thumbClasses = computed(() => [
239
262
  {
240
- "ui-toggle-thumb--on": props.modelValue,
241
- "ui-toggle-thumb--off": !props.modelValue
263
+ "ui-toggle-thumb--on": isChecked.value,
264
+ "ui-toggle-thumb--off": !isChecked.value
242
265
  }
243
266
  ]);
244
267
  const handleToggle = () => {
245
268
  if (props.disabled) return;
246
- emit("update:modelValue", !props.modelValue);
269
+ const newValue = !isChecked.value;
270
+ internalValue.value = newValue;
271
+ emit("update:modelValue", newValue);
272
+ emit("change", newValue);
247
273
  };
248
274
  return (_ctx, _cache) => {
249
275
  return openBlock(), createElementBlock("div", _hoisted_1$B, [
@@ -259,7 +285,7 @@ const _sfc_main$E = /* @__PURE__ */ defineComponent({
259
285
  id: toggleId.value,
260
286
  type: "button",
261
287
  class: normalizeClass(toggleClasses.value),
262
- "aria-pressed": _ctx.modelValue,
288
+ "aria-pressed": isChecked.value,
263
289
  "aria-labelledby": _ctx.label ? `${toggleId.value}-label` : void 0,
264
290
  onClick: handleToggle
265
291
  }, [
@@ -271,7 +297,7 @@ const _sfc_main$E = /* @__PURE__ */ defineComponent({
271
297
  };
272
298
  }
273
299
  });
274
- const UiToggle = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-ba05b9e3"]]);
300
+ const UiToggle = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["__scopeId", "data-v-aefb58fe"]]);
275
301
  const _hoisted_1$A = { class: "accui-component-scope" };
276
302
  const _hoisted_2$v = { class: "avatar-editor-simple" };
277
303
  const _hoisted_3$u = {
@@ -6029,7 +6055,8 @@ const _hoisted_14$f = {
6029
6055
  const _sfc_main$u = /* @__PURE__ */ defineComponent({
6030
6056
  __name: "UiSlider",
6031
6057
  props: {
6032
- modelValue: { default: 0 },
6058
+ modelValue: { default: void 0 },
6059
+ value: { default: void 0 },
6033
6060
  min: { default: 0 },
6034
6061
  max: { default: 100 },
6035
6062
  step: { default: 1 },
@@ -6048,7 +6075,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6048
6075
  color: { default: "primary" },
6049
6076
  inputId: {}
6050
6077
  },
6051
- emits: ["update:modelValue", "change", "focus", "blur"],
6078
+ emits: ["update:modelValue", "change", "input", "focus", "blur"],
6052
6079
  setup(__props, { emit: __emit }) {
6053
6080
  const props = __props;
6054
6081
  const emit = __emit;
@@ -6056,13 +6083,33 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6056
6083
  const isDragging = ref(false);
6057
6084
  const inputCount = ref(0);
6058
6085
  const dragTimeout = ref(null);
6086
+ const internalValue = ref(0);
6087
+ const currentValue = computed(() => {
6088
+ if (props.modelValue !== void 0) {
6089
+ return Number(props.modelValue);
6090
+ }
6091
+ if (props.value !== void 0) {
6092
+ return Number(props.value);
6093
+ }
6094
+ return internalValue.value;
6095
+ });
6096
+ watch(() => props.value, (newVal) => {
6097
+ if (newVal !== void 0) {
6098
+ internalValue.value = Number(newVal);
6099
+ }
6100
+ }, { immediate: true });
6101
+ watch(() => props.modelValue, (newVal) => {
6102
+ if (newVal !== void 0) {
6103
+ internalValue.value = Number(newVal);
6104
+ }
6105
+ }, { immediate: true });
6059
6106
  const progressPercentage = computed(() => {
6060
6107
  const range = props.max - props.min;
6061
- const value = (props.modelValue - props.min) / range * 100;
6108
+ const value = (currentValue.value - props.min) / range * 100;
6062
6109
  return Math.max(0, Math.min(100, value));
6063
6110
  });
6064
6111
  const displayValue = computed(() => {
6065
- return props.modelValue?.toFixed(props.step < 1 ? 1 : 0) || "0";
6112
+ return currentValue.value?.toFixed(props.step < 1 ? 1 : 0) || "0";
6066
6113
  });
6067
6114
  const sizeClasses = computed(() => {
6068
6115
  return `slider-size-${props.size}`;
@@ -6100,7 +6147,9 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6100
6147
  inputCount.value = 0;
6101
6148
  }, 100);
6102
6149
  }
6150
+ internalValue.value = value;
6103
6151
  emit("update:modelValue", value);
6152
+ emit("input", value);
6104
6153
  };
6105
6154
  const handleChange = (event) => {
6106
6155
  const target = event.target;
@@ -6156,7 +6205,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6156
6205
  ref_key: "sliderRef",
6157
6206
  ref: sliderRef,
6158
6207
  type: "range",
6159
- value: _ctx.modelValue,
6208
+ value: currentValue.value,
6160
6209
  min: _ctx.min,
6161
6210
  max: _ctx.max,
6162
6211
  step: _ctx.step,
@@ -6204,7 +6253,7 @@ const _sfc_main$u = /* @__PURE__ */ defineComponent({
6204
6253
  };
6205
6254
  }
6206
6255
  });
6207
- const UiSlider = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-c27d9054"]]);
6256
+ const UiSlider = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["__scopeId", "data-v-db4748a0"]]);
6208
6257
  const _hoisted_1$r = {
6209
6258
  key: 0,
6210
6259
  class: "radio-group-label"
package/dist/vite.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";function n(n={}){const{styles:s=1,accentColor:r="#EA00A8",useSquircle:t=1,...i}=n;let c;return{name:"@strands.gg/accui:vite-plugin",enforce:"pre",config:(n,{command:s})=>(c={accentColor:r,useSquircle:t,...i},{define:{t:JSON.stringify(c)}}),transformIndexHtml:{order:"pre",handler(n){if(r&&"#EA00A8"!==r){const s=`<style data-strands-accent>\n :root {\n --strands-accent: ${r};\n --accui-strands-accent: ${r};\n --accui-strands-50: color-mix(in srgb, ${r} 10%, white);\n --accui-strands-100: color-mix(in srgb, ${r} 20%, white);\n --accui-strands-200: color-mix(in srgb, ${r} 30%, white);\n --accui-strands-300: color-mix(in srgb, ${r} 40%, white);\n --accui-strands-400: color-mix(in srgb, ${r} 70%, white);\n --accui-strands-500: ${r};\n --accui-strands-600: color-mix(in srgb, ${r} 85%, black);\n --accui-strands-700: color-mix(in srgb, ${r} 70%, black);\n --accui-strands-800: color-mix(in srgb, ${r} 55%, black);\n --accui-strands-900: color-mix(in srgb, ${r} 40%, black);\n --accui-strands-950: color-mix(in srgb, ${r} 25%, black);\n }</style>`;return n.replace("</head>",` ${s}\n </head>`)}return n}},transform:async(n,r)=>(s&&r.endsWith("main.ts")||r.endsWith("main.js"))&&!n.includes("@strands.gg/accui/style.css")?{code:`import '@strands.gg/accui/style.css'\n${n}`,map:null}:!r.endsWith("main.ts")&&!r.endsWith("main.js")||n.includes("setStrandsConfig")||n.includes("__STRANDS_INJECTED__")?null:{code:`\n// Auto-injected by @strands.gg/accui Vite plugin\nimport { setStrandsConfig } from '@strands.gg/accui'\n\nif (typeof window !== 'undefined') {\n const strandsConfig = ${JSON.stringify(c)}\n setStrandsConfig(strandsConfig)\n window.__STRANDS_CONFIG__ = strandsConfig\n window.__STRANDS_INJECTED__ = true\n}\n\n${n}`,map:null}}}Object.defineProperties(exports,{i:{value:1},[Symbol.toStringTag]:{value:"Module"}}),exports.StrandsAuth=n,exports.StrandsAuthVitePlugin=n,exports.createStrandsAuth=function(n={}){return{install(s){Promise.resolve().then(()=>require("./StrandsUIPlugin-DSCUXdBp.cjs.js")).then(n=>n.StrandsUIPlugin$1).then(n=>{const r=n.default;s.use(r)}),Promise.resolve().then(()=>require("./useStrandsConfig-Sr6NG90B.cjs.js")).then(n=>n.useStrandsConfig$1).then(s=>{const{setStrandsConfig:r}=s;r(n),"undefined"!=typeof window&&(window.t=n)})}}},exports.default=n,exports.strandsAuth=n;
1
+ "use strict";function n(n={}){const{styles:s=1,accentColor:r="#EA00A8",useSquircle:t=1,...i}=n;let c;return{name:"@strands.gg/accui:vite-plugin",enforce:"pre",config:(n,{command:s})=>(c={accentColor:r,useSquircle:t,...i},{define:{t:JSON.stringify(c)}}),transformIndexHtml:{order:"pre",handler(n){if(r&&"#EA00A8"!==r){const s=`<style data-strands-accent>\n :root {\n --strands-accent: ${r};\n --accui-strands-accent: ${r};\n --accui-strands-50: color-mix(in srgb, ${r} 10%, white);\n --accui-strands-100: color-mix(in srgb, ${r} 20%, white);\n --accui-strands-200: color-mix(in srgb, ${r} 30%, white);\n --accui-strands-300: color-mix(in srgb, ${r} 40%, white);\n --accui-strands-400: color-mix(in srgb, ${r} 70%, white);\n --accui-strands-500: ${r};\n --accui-strands-600: color-mix(in srgb, ${r} 85%, black);\n --accui-strands-700: color-mix(in srgb, ${r} 70%, black);\n --accui-strands-800: color-mix(in srgb, ${r} 55%, black);\n --accui-strands-900: color-mix(in srgb, ${r} 40%, black);\n --accui-strands-950: color-mix(in srgb, ${r} 25%, black);\n }</style>`;return n.replace("</head>",` ${s}\n </head>`)}return n}},transform:async(n,r)=>(s&&r.endsWith("main.ts")||r.endsWith("main.js"))&&!n.includes("@strands.gg/accui/style.css")?{code:`import '@strands.gg/accui/style.css'\n${n}`,map:null}:!r.endsWith("main.ts")&&!r.endsWith("main.js")||n.includes("setStrandsConfig")||n.includes("__STRANDS_INJECTED__")?null:{code:`\n// Auto-injected by @strands.gg/accui Vite plugin\nimport { setStrandsConfig } from '@strands.gg/accui'\n\nif (typeof window !== 'undefined') {\n const strandsConfig = ${JSON.stringify(c)}\n setStrandsConfig(strandsConfig)\n window.__STRANDS_CONFIG__ = strandsConfig\n window.__STRANDS_INJECTED__ = true\n}\n\n${n}`,map:null}}}Object.defineProperties(exports,{i:{value:1},[Symbol.toStringTag]:{value:"Module"}}),exports.StrandsAuth=n,exports.StrandsAuthVitePlugin=n,exports.createStrandsAuth=function(n={}){return{install(s){Promise.resolve().then(()=>require("./StrandsUIPlugin-D9RVai-I.cjs.js")).then(n=>n.StrandsUIPlugin$1).then(n=>{const r=n.default;s.use(r)}),Promise.resolve().then(()=>require("./useStrandsConfig-Sr6NG90B.cjs.js")).then(n=>n.useStrandsConfig$1).then(s=>{const{setStrandsConfig:r}=s;r(n),"undefined"!=typeof window&&(window.t=n)})}}},exports.default=n,exports.strandsAuth=n;
package/dist/vite.es.js CHANGED
@@ -86,7 +86,7 @@ ${code}`,
86
86
  function createStrandsAuth(config = {}) {
87
87
  return {
88
88
  install(app) {
89
- import("./StrandsUIPlugin-JP858JzQ.es.js").then((n) => n.n).then((module) => {
89
+ import("./StrandsUIPlugin-Dws5Nqi_.es.js").then((n) => n.n).then((module) => {
90
90
  const StrandsUIPlugin = module.default;
91
91
  app.use(StrandsUIPlugin);
92
92
  });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Utility for converting Vue components to Web Components
3
+ *
4
+ * This module provides helpers for registering Vue components as custom elements
5
+ * with proper style handling and Shadow DOM integration.
6
+ */
7
+ import { type Component } from 'vue';
8
+ export declare const baseStyles = "\n :host {\n /* Typography */\n --accui-font-sans: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif;\n --accui-font-mono: \"Courier New\", Courier, ui-monospace, SFMono-Regular, \"SF Mono\", Consolas, \"Liberation Mono\", Menlo, monospace;\n\n /* Brand Colors - inherit from document or use defaults */\n --strands-accent: var(--strands-custom-accent, #EA00A8);\n --accui-strands-accent: var(--strands-custom-accent, #EA00A8);\n --accui-strands-50: var(--strands-custom-50, color-mix(in srgb, var(--strands-accent) 10%, white));\n --accui-strands-100: var(--strands-custom-100, color-mix(in srgb, var(--strands-accent) 20%, white));\n --accui-strands-200: var(--strands-custom-200, color-mix(in srgb, var(--strands-accent) 30%, white));\n --accui-strands-300: var(--strands-custom-300, color-mix(in srgb, var(--strands-accent) 40%, white));\n --accui-strands-400: var(--strands-custom-400, color-mix(in srgb, var(--strands-accent) 70%, white));\n --accui-strands-500: var(--strands-custom-500, var(--strands-accent));\n --accui-strands-600: var(--strands-custom-600, color-mix(in srgb, var(--strands-accent) 85%, black));\n --accui-strands-700: var(--strands-custom-700, color-mix(in srgb, var(--strands-accent) 70%, black));\n --accui-strands-800: var(--strands-custom-800, color-mix(in srgb, var(--strands-accent) 55%, black));\n --accui-strands-900: var(--strands-custom-900, color-mix(in srgb, var(--strands-accent) 40%, black));\n --accui-strands-950: var(--strands-custom-950, color-mix(in srgb, var(--strands-accent) 25%, black));\n\n /* Neutral Colors */\n --accui-neutral-50: #fafafa;\n --accui-neutral-100: #f5f5f5;\n --accui-neutral-200: #e5e5e5;\n --accui-neutral-300: #d4d4d4;\n --accui-neutral-400: #a3a3a3;\n --accui-neutral-500: #737373;\n --accui-neutral-600: #525252;\n --accui-neutral-700: #404040;\n --accui-neutral-800: #262626;\n --accui-neutral-900: #171717;\n --accui-neutral-950: #0a0a0a;\n\n /* Gray Colors */\n --accui-gray-50: #f9fafb;\n --accui-gray-100: #f3f4f6;\n --accui-gray-200: #e5e7eb;\n --accui-gray-300: #d1d5db;\n --accui-gray-400: #9ca3af;\n --accui-gray-500: #6b7280;\n --accui-gray-600: #4b5563;\n --accui-gray-700: #374151;\n --accui-gray-800: #1f2937;\n --accui-gray-900: #111827;\n --accui-gray-950: #030712;\n\n /* Status Colors */\n --accui-red-500: #ef4444;\n --accui-red-600: #dc2626;\n --accui-green-500: #22c55e;\n --accui-green-600: #16a34a;\n --accui-yellow-500: #f97316;\n --accui-yellow-600: #ea580c;\n\n /* Spacing Scale */\n --accui-space-0: 0;\n --accui-space-1: 0.25rem;\n --accui-space-2: 0.5rem;\n --accui-space-3: 0.75rem;\n --accui-space-4: 1rem;\n --accui-space-5: 1.25rem;\n --accui-space-6: 1.5rem;\n --accui-space-8: 2rem;\n\n /* Border Radius */\n --accui-radius-none: 0;\n --accui-radius-sm: 0.125rem;\n --accui-radius-md: 0.375rem;\n --accui-radius-lg: 0.5rem;\n --accui-radius-xl: 0.75rem;\n --accui-radius-2xl: 1rem;\n --accui-radius-full: 9999px;\n\n /* Transition Timings */\n --accui-transition-fast: 0.15s;\n --accui-transition-duration: 0.25s;\n --animation-duration: 0.25s;\n\n /* Theme Colors (Light Mode Default) */\n --accui-bg-primary: #ffffff;\n --accui-bg-secondary: #f9fafb;\n --accui-bg-tertiary: #f3f4f6;\n --accui-text-primary: #111827;\n --accui-text-secondary: #6b7280;\n --accui-text-tertiary: #9ca3af;\n --accui-border-primary: #e5e7eb;\n --accui-border-secondary: #d1d5db;\n --accui-border-tertiary: #9ca3af;\n\n /* Button Variables */\n --accui-button-primary-background: var(--accui-strands-500);\n --accui-button-primary-background-hover: var(--accui-strands-600);\n --accui-button-primary-text: #ffffff;\n --accui-button-primary-border: transparent;\n\n --accui-button-secondary-background: #f0f0f0;\n --accui-button-secondary-background-hover: #e2e2e2;\n --accui-button-secondary-text: #000000;\n --accui-button-secondary-border: #f0f0f0;\n\n --accui-button-ghost-background: transparent;\n --accui-button-ghost-background-hover: var(--accui-bg-secondary);\n --accui-button-ghost-text: var(--accui-text-primary);\n --accui-button-ghost-border: transparent;\n\n --accui-button-outline-background: transparent;\n --accui-button-outline-background-hover: var(--accui-strands-50);\n --accui-button-outline-text: var(--accui-strands-500);\n --accui-button-outline-border: var(--accui-strands-500);\n\n /* Input Variables */\n --accui-input-background: var(--accui-bg-primary);\n --accui-input-background-focus: var(--accui-bg-primary);\n --accui-input-text: var(--accui-text-primary);\n --accui-input-placeholder: var(--accui-text-tertiary);\n --accui-input-border: var(--accui-border-primary);\n --accui-input-border-focus: var(--strands-accent, #EA00A8);\n --accui-input-shadow-focus: 0 0 0 3px color-mix(in srgb, var(--strands-accent, #EA00A8) 10%, transparent);\n\n /* Card Variables */\n --accui-card-background: var(--accui-bg-primary);\n --accui-card-border: var(--accui-border-primary);\n --accui-card-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);\n\n /* Alert Variables */\n --accui-alert-success-background: #f0fdf4;\n --accui-alert-success-text: #15803d;\n --accui-alert-success-border: #bbf7d0;\n\n --accui-alert-error-background: #fef2f2;\n --accui-alert-error-text: #dc2626;\n --accui-alert-error-border: #fecaca;\n\n --accui-alert-warning-background: #fefce8;\n --accui-alert-warning-text: #ca8a04;\n --accui-alert-warning-border: #fde047;\n\n --accui-alert-info-background: #eff6ff;\n --accui-alert-info-text: #2563eb;\n --accui-alert-info-border: #bfdbfe;\n\n /* Toggle Variables */\n --accui-toggle-background: var(--accui-border-secondary);\n --accui-toggle-background-active: var(--accui-strands-500);\n --accui-toggle-thumb: #ffffff;\n\n /* Tabs Variables */\n --accui-tabs-background: var(--accui-bg-secondary);\n --accui-tabs-border: var(--accui-border-primary);\n --accui-tabs-button-text: var(--accui-text-secondary);\n --accui-tabs-button-text-active: var(--accui-text-primary);\n --accui-tabs-button-background: var(--accui-bg-primary);\n --accui-tabs-button-background-hover: var(--accui-bg-secondary);\n --accui-tabs-indicator: var(--accui-strands-500);\n\n /* Divider Variables */\n --accui-divider-color: var(--accui-border-primary);\n --accui-divider-text: var(--accui-text-secondary);\n\n /* Display as inline-block by default */\n display: inline-block;\n }\n\n /* Dark mode support - detect from document */\n :host-context([data-theme=\"dark\"]) {\n --accui-bg-primary: #0f172a;\n --accui-bg-secondary: #1e293b;\n --accui-bg-tertiary: #334155;\n --accui-text-primary: #f8fafc;\n --accui-text-secondary: #cbd5e1;\n --accui-text-tertiary: #94a3b8;\n --accui-border-primary: #334155;\n --accui-border-secondary: #475569;\n --accui-border-tertiary: #64748b;\n\n --accui-button-secondary-background: var(--accui-bg-secondary);\n --accui-button-secondary-background-hover: var(--accui-bg-tertiary);\n --accui-button-secondary-text: var(--accui-text-primary);\n --accui-button-secondary-border: var(--accui-bg-secondary);\n\n --accui-button-ghost-background-hover: var(--accui-bg-tertiary);\n\n --accui-button-outline-background-hover: var(--accui-strands-950);\n --accui-button-outline-text: var(--accui-strands-400);\n --accui-button-outline-border: var(--accui-strands-400);\n\n --accui-alert-success-background: #0f2a1a;\n --accui-alert-success-text: #4ade80;\n --accui-alert-success-border: #16a34a;\n\n --accui-alert-error-background: #2a0f0f;\n --accui-alert-error-text: #f87171;\n --accui-alert-error-border: #dc2626;\n\n --accui-alert-warning-background: #2a2508;\n --accui-alert-warning-text: #fbbf24;\n --accui-alert-warning-border: #eab308;\n\n --accui-alert-info-background: #0f1a2a;\n --accui-alert-info-text: #60a5fa;\n --accui-alert-info-border: #3b82f6;\n\n --accui-toggle-background: var(--accui-border-tertiary);\n\n --accui-tabs-background: var(--accui-bg-tertiary);\n --accui-tabs-button-background: var(--accui-bg-secondary);\n --accui-tabs-button-background-hover: var(--accui-bg-primary);\n }\n\n /* Base reset for Shadow DOM content */\n *, *::before, *::after {\n box-sizing: border-box;\n }\n";
9
+ /**
10
+ * Creates and registers a custom element from a Vue component
11
+ *
12
+ * @param tagName - The custom element tag name (e.g., 'strands-button')
13
+ * @param component - The Vue component to convert
14
+ * @param dependencyStyles - Optional array of CSS strings from dependent components
15
+ * (injected by the Vite build plugin)
16
+ */
17
+ export declare function registerCustomElement(tagName: string, component: Component, dependencyStyles?: string[]): void;
18
+ /**
19
+ * Check if a custom element is already registered
20
+ */
21
+ export declare function isElementRegistered(tagName: string): boolean;
22
+ /**
23
+ * Wait for a custom element to be defined
24
+ */
25
+ export declare function whenDefined(tagName: string): Promise<CustomElementConstructor>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Alert Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-alert variant="success" title="Success!">
7
+ * Operation completed successfully.
8
+ * </strands-alert>
9
+ * ```
10
+ */
11
+ import UiAlert from '../../vue/ui/UiAlert.vue';
12
+ export { UiAlert };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Button Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-button variant="primary" size="md">
7
+ * Click Me
8
+ * </strands-button>
9
+ * ```
10
+ */
11
+ import UiButton from '../../vue/ui/UiButton.vue';
12
+ export { UiButton };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Card Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-card>
7
+ * Card content goes here
8
+ * </strands-card>
9
+ * ```
10
+ */
11
+ import UiCard from '../../vue/ui/UiCard.vue';
12
+ export { UiCard };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Strands Checkbox Group Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-checkbox-group name="choices" options='[{"value":"a","label":"Option A"},{"value":"b","label":"Option B"}]'>
7
+ * </strands-checkbox-group>
8
+ * ```
9
+ */
10
+ import UiCheckboxGroup from '../../vue/ui/UiCheckboxGroup.vue';
11
+ export { UiCheckboxGroup };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Divider Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-divider></strands-divider>
7
+ * <strands-divider orientation="vertical"></strands-divider>
8
+ * <strands-divider>Or</strands-divider>
9
+ * ```
10
+ */
11
+ import UiDivider from '../../vue/ui/UiDivider.vue';
12
+ export { UiDivider };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Strands Input Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-input
7
+ * type="email"
8
+ * label="Email"
9
+ * placeholder="Enter your email"
10
+ * ></strands-input>
11
+ * ```
12
+ */
13
+ import UiInput from '../../vue/ui/UiInput.vue';
14
+ export { UiInput };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Link Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-link href="https://example.com" external>
7
+ * Visit Example
8
+ * </strands-link>
9
+ * ```
10
+ */
11
+ import UiLink from '../../vue/ui/UiLink.vue';
12
+ export { UiLink };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strands Loader Spinner Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-loader-spinner size="md"></strands-loader-spinner>
7
+ * ```
8
+ */
9
+ import UiLoader from '../../vue/ui/UiLoader.vue';
10
+ export { UiLoader };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Strands Modal Web Component
3
+ *
4
+ * Note: Modals in web components have limitations due to Shadow DOM.
5
+ * The modal will render within its shadow root, which may affect
6
+ * positioning and overlay behaviour.
7
+ *
8
+ * Usage:
9
+ * ```html
10
+ * <strands-modal open title="Modal Title">
11
+ * Modal content here
12
+ * </strands-modal>
13
+ * ```
14
+ */
15
+ import UiModal from '../../vue/ui/UiModal.vue';
16
+ export { UiModal };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Strands Pill Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-pill variant="filled" color="primary">Badge</strands-pill>
7
+ * <strands-pill variant="dot" color="success">Active</strands-pill>
8
+ * ```
9
+ */
10
+ import UiPill from '../../vue/ui/UiPill.vue';
11
+ export { UiPill };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Strands Radio Group Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-radio-group name="choice" options='[{"value":"a","label":"Option A"},{"value":"b","label":"Option B"}]'>
7
+ * </strands-radio-group>
8
+ * ```
9
+ */
10
+ import UiRadioGroup from '../../vue/ui/UiRadioGroup.vue';
11
+ export { UiRadioGroup };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strands Slider Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-slider min="0" max="100" value="50"></strands-slider>
7
+ * ```
8
+ */
9
+ import UiSlider from '../../vue/ui/UiSlider.vue';
10
+ export { UiSlider };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Strands Table Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-table
7
+ * columns='[{"key":"name","label":"Name"},{"key":"email","label":"Email"}]'
8
+ * data='[{"name":"John","email":"john@example.com"}]'
9
+ * ></strands-table>
10
+ * ```
11
+ */
12
+ import UiTable from '../../vue/ui/UiTable.vue';
13
+ export { UiTable };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Tabs Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-tabs>
7
+ * <!-- Tab content via slots -->
8
+ * </strands-tabs>
9
+ * ```
10
+ */
11
+ import UiTabs from '../../vue/ui/UiTabs.vue';
12
+ export { UiTabs };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strands Theme Toggle Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-theme-toggle></strands-theme-toggle>
7
+ * ```
8
+ */
9
+ import UiThemeToggle from '../../vue/ui/UiThemeToggle.vue';
10
+ export { UiThemeToggle };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strands Toggle Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-toggle label="Enable notifications"></strands-toggle>
7
+ * ```
8
+ */
9
+ import UiToggle from '../../vue/ui/UiToggle.vue';
10
+ export { UiToggle };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Strands Tooltip Web Component
3
+ *
4
+ * Usage:
5
+ * ```html
6
+ * <strands-tooltip content="Helpful information" position="top">
7
+ * <button>Hover me</button>
8
+ * </strands-tooltip>
9
+ * ```
10
+ */
11
+ import UiTooltip from '../../vue/ui/UiTooltip.vue';
12
+ export { UiTooltip };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Strands UI Web Components
3
+ *
4
+ * This module exports all web component functionality for the Strands UI library.
5
+ */
6
+ export * from './loader';
7
+ export * from './registry';
8
+ export * from './define-element';
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Strands UI Web Components Loader
3
+ *
4
+ * A custom element that lazy-loads Strands UI components on demand.
5
+ *
6
+ * Usage:
7
+ * ```html
8
+ * <script src="https://use.strandsui.com/loader.js"></script>
9
+ * <strands-loader components="button,alert,input"></strands-loader>
10
+ * ```
11
+ *
12
+ * Events:
13
+ * - 'strands:ready' - Dispatched when all requested components are loaded
14
+ * - 'strands:error' - Dispatched if any component fails to load
15
+ * - 'strands:progress' - Dispatched as each component loads
16
+ */
17
+ import { type ComponentInfo } from './registry';
18
+ declare const loadedComponents: Set<string>;
19
+ /**
20
+ * Load a single component with deduplication
21
+ */
22
+ declare function loadComponent(shortName: string): Promise<void>;
23
+ /**
24
+ * Load multiple components in parallel
25
+ */
26
+ declare function loadComponents(shortNames: string[], onProgress?: (loaded: number, total: number, componentName: string) => void): Promise<{
27
+ loaded: string[];
28
+ failed: Array<{
29
+ name: string;
30
+ error: Error;
31
+ }>;
32
+ }>;
33
+ /**
34
+ * StrandsLoader Custom Element
35
+ *
36
+ * Attributes:
37
+ * - components: Comma-separated list of component names to load
38
+ * - base-url: Override the base URL for component files
39
+ * - show-loading: Show a loading indicator whilst components load
40
+ */
41
+ declare class StrandsLoader extends HTMLElement {
42
+ private _connected;
43
+ private _loadPromise;
44
+ static get observedAttributes(): string[];
45
+ constructor();
46
+ connectedCallback(): void;
47
+ disconnectedCallback(): void;
48
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
49
+ private _render;
50
+ private _updateStatus;
51
+ private _loadComponents;
52
+ private _dispatchEvent;
53
+ /**
54
+ * Programmatically load additional components
55
+ */
56
+ load(componentNames: string | string[]): Promise<{
57
+ loaded: string[];
58
+ failed: string[];
59
+ }>;
60
+ /**
61
+ * Check if a component is loaded
62
+ */
63
+ isLoaded(componentName: string): boolean;
64
+ /**
65
+ * Get list of all available components
66
+ */
67
+ static get availableComponents(): string[];
68
+ /**
69
+ * Get component info
70
+ */
71
+ static getComponentInfo(name: string): ComponentInfo | undefined;
72
+ }
73
+ export { StrandsLoader, loadComponent, loadComponents, loadedComponents };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Component Registry
3
+ *
4
+ * Maps component short names to their module paths for dynamic loading.
5
+ * This allows the loader to dynamically import only the requested components.
6
+ */
7
+ export interface ComponentInfo {
8
+ /** The custom element tag name */
9
+ tagName: string;
10
+ /** The short name used in the loader (e.g., 'button' for strands-button) */
11
+ shortName: string;
12
+ /** Description of the component */
13
+ description: string;
14
+ }
15
+ /**
16
+ * Registry of all available components
17
+ */
18
+ export declare const componentRegistry: Record<string, ComponentInfo>;
19
+ /**
20
+ * Get component info by short name
21
+ */
22
+ export declare function getComponentInfo(shortName: string): ComponentInfo | undefined;
23
+ /**
24
+ * Get all available component short names
25
+ */
26
+ export declare function getAvailableComponents(): string[];
27
+ /**
28
+ * Check if a component exists in the registry
29
+ */
30
+ export declare function isValidComponent(shortName: string): boolean;
31
+ /**
32
+ * Parse a comma-separated list of component names
33
+ */
34
+ export declare function parseComponentList(componentString: string): string[];
35
+ /**
36
+ * Validate a list of component names and return invalid ones
37
+ */
38
+ export declare function validateComponentList(components: string[]): {
39
+ valid: string[];
40
+ invalid: string[];
41
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strands.gg/accui",
3
- "version": "2.15.11",
3
+ "version": "2.15.14",
4
4
  "description": "Strands Authentication UI Components",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs.js",
@@ -65,8 +65,10 @@
65
65
  "scripts": {
66
66
  "build": "vite build && tsc --emitDeclarationOnly",
67
67
  "build-demo": "vite build --config vite.demo.config.ts",
68
+ "build-webcomponents": "vite build --config vite.webcomponents.config.ts",
68
69
  "serve": "vite",
69
70
  "serve-demo": "vite --config vite.demo.config.ts",
71
+ "serve-webcomponents": "serve -c serve.webcomponents.json -l 3002 dist-webcomponents",
70
72
  "dev": "vite build --watch",
71
73
  "preview": "vite preview",
72
74
  "preview-demo": "vite preview --config vite.demo.config.ts",