@brandsync/wc 0.0.1

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 (134) hide show
  1. package/LICENSE +21 -0
  2. package/custom-elements.json +1138 -0
  3. package/dist/brandsync-wc/brandsync-wc.css +1730 -0
  4. package/dist/brandsync-wc/brandsync-wc.esm.js +1 -0
  5. package/dist/brandsync-wc/brandsync-wc.esm.js.map +1 -0
  6. package/dist/brandsync-wc/index-Cqxk7LcP.js.map +1 -0
  7. package/dist/brandsync-wc/index.esm.js +1 -0
  8. package/dist/brandsync-wc/index.esm.js.map +1 -0
  9. package/dist/brandsync-wc/p-042ad15a.entry.js +1 -0
  10. package/dist/brandsync-wc/p-2c4df28d.entry.js +1 -0
  11. package/dist/brandsync-wc/p-3134f5f5.entry.js +1 -0
  12. package/dist/brandsync-wc/p-5739acaf.entry.js +1 -0
  13. package/dist/brandsync-wc/p-BOj_41o9.js +3 -0
  14. package/dist/brandsync-wc/p-c2cc0d6f.entry.js +1 -0
  15. package/dist/brandsync-wc/p-da11e421.entry.js +1 -0
  16. package/dist/brandsync-wc/p-db3934d2.entry.js +1 -0
  17. package/dist/brandsync-wc/p-e38a9744.entry.js +1 -0
  18. package/dist/cjs/brandsync-wc.cjs.js +24 -0
  19. package/dist/cjs/bs-badge.cjs.entry.js +19 -0
  20. package/dist/cjs/bs-button-skeleton.cjs.entry.js +19 -0
  21. package/dist/cjs/bs-button.cjs.entry.js +88 -0
  22. package/dist/cjs/bs-card.cjs.entry.js +20 -0
  23. package/dist/cjs/bs-composer.cjs.entry.js +116 -0
  24. package/dist/cjs/bs-data-table.cjs.entry.js +62 -0
  25. package/dist/cjs/bs-input.cjs.entry.js +42 -0
  26. package/dist/cjs/bs-modal.cjs.entry.js +69 -0
  27. package/dist/cjs/index-nyOcuVbF.js +1710 -0
  28. package/dist/cjs/index.cjs.js +7 -0
  29. package/dist/cjs/loader.cjs.js +12 -0
  30. package/dist/collection/collection-manifest.json +20 -0
  31. package/dist/collection/components/bs-badge/bs-badge.cmp.test.js +30 -0
  32. package/dist/collection/components/bs-badge/bs-badge.css +55 -0
  33. package/dist/collection/components/bs-badge/bs-badge.js +64 -0
  34. package/dist/collection/components/bs-badge/bs-badge.stories.js +75 -0
  35. package/dist/collection/components/bs-button/bs-button.cmp.test.js +81 -0
  36. package/dist/collection/components/bs-button/bs-button.css +247 -0
  37. package/dist/collection/components/bs-button/bs-button.js +242 -0
  38. package/dist/collection/components/bs-button/bs-button.stories.js +145 -0
  39. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.cmp.test.js +18 -0
  40. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.css +46 -0
  41. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.js +73 -0
  42. package/dist/collection/components/bs-button-skeleton/bs-button-skeleton.stories.js +25 -0
  43. package/dist/collection/components/bs-card/bs-card.cmp.test.js +42 -0
  44. package/dist/collection/components/bs-card/bs-card.css +31 -0
  45. package/dist/collection/components/bs-card/bs-card.js +70 -0
  46. package/dist/collection/components/bs-card/bs-card.stories.js +27 -0
  47. package/dist/collection/components/bs-composer/bs-composer.cmp.test.js +132 -0
  48. package/dist/collection/components/bs-composer/bs-composer.css +185 -0
  49. package/dist/collection/components/bs-composer/bs-composer.js +353 -0
  50. package/dist/collection/components/bs-composer/bs-composer.stories.js +66 -0
  51. package/dist/collection/components/bs-data-table/bs-data-table.css +56 -0
  52. package/dist/collection/components/bs-data-table/bs-data-table.js +259 -0
  53. package/dist/collection/components/bs-data-table/bs-data-table.stories.js +55 -0
  54. package/dist/collection/components/bs-input/bs-input.cmp.test.js +101 -0
  55. package/dist/collection/components/bs-input/bs-input.css +64 -0
  56. package/dist/collection/components/bs-input/bs-input.js +230 -0
  57. package/dist/collection/components/bs-input/bs-input.stories.js +40 -0
  58. package/dist/collection/components/bs-modal/bs-modal.cmp.test.js +112 -0
  59. package/dist/collection/components/bs-modal/bs-modal.css +66 -0
  60. package/dist/collection/components/bs-modal/bs-modal.js +198 -0
  61. package/dist/collection/components/bs-modal/bs-modal.stories.js +38 -0
  62. package/dist/collection/index.js +10 -0
  63. package/dist/collection/stories-utils.js +25 -0
  64. package/dist/collection/utils/utils.js +3 -0
  65. package/dist/collection/utils/utils.unit.test.js +16 -0
  66. package/dist/components/bs-badge.d.ts +11 -0
  67. package/dist/components/bs-badge.js +1 -0
  68. package/dist/components/bs-button-skeleton.d.ts +11 -0
  69. package/dist/components/bs-button-skeleton.js +1 -0
  70. package/dist/components/bs-button.d.ts +11 -0
  71. package/dist/components/bs-button.js +1 -0
  72. package/dist/components/bs-card.d.ts +11 -0
  73. package/dist/components/bs-card.js +1 -0
  74. package/dist/components/bs-composer.d.ts +11 -0
  75. package/dist/components/bs-composer.js +1 -0
  76. package/dist/components/bs-data-table.d.ts +11 -0
  77. package/dist/components/bs-data-table.js +1 -0
  78. package/dist/components/bs-input.d.ts +11 -0
  79. package/dist/components/bs-input.js +1 -0
  80. package/dist/components/bs-modal.d.ts +11 -0
  81. package/dist/components/bs-modal.js +1 -0
  82. package/dist/components/index.d.ts +35 -0
  83. package/dist/components/index.js +1 -0
  84. package/dist/components/p-Cu4gTknX.js +1 -0
  85. package/dist/esm/brandsync-wc.js +20 -0
  86. package/dist/esm/bs-badge.entry.js +17 -0
  87. package/dist/esm/bs-button-skeleton.entry.js +17 -0
  88. package/dist/esm/bs-button.entry.js +86 -0
  89. package/dist/esm/bs-card.entry.js +18 -0
  90. package/dist/esm/bs-composer.entry.js +114 -0
  91. package/dist/esm/bs-data-table.entry.js +60 -0
  92. package/dist/esm/bs-input.entry.js +40 -0
  93. package/dist/esm/bs-modal.entry.js +67 -0
  94. package/dist/esm/index-BOj_41o9.js +1701 -0
  95. package/dist/esm/index.js +5 -0
  96. package/dist/esm/loader.js +10 -0
  97. package/dist/index.cjs.js +1 -0
  98. package/dist/index.js +1 -0
  99. package/dist/types/components/bs-badge/bs-badge.cmp.test.d.ts +1 -0
  100. package/dist/types/components/bs-badge/bs-badge.d.ts +20 -0
  101. package/dist/types/components/bs-badge/bs-badge.stories.d.ts +19 -0
  102. package/dist/types/components/bs-button/bs-button.cmp.test.d.ts +1 -0
  103. package/dist/types/components/bs-button/bs-button.d.ts +84 -0
  104. package/dist/types/components/bs-button/bs-button.stories.d.ts +29 -0
  105. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.cmp.test.d.ts +1 -0
  106. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.d.ts +28 -0
  107. package/dist/types/components/bs-button-skeleton/bs-button-skeleton.stories.d.ts +10 -0
  108. package/dist/types/components/bs-card/bs-card.cmp.test.d.ts +1 -0
  109. package/dist/types/components/bs-card/bs-card.d.ts +26 -0
  110. package/dist/types/components/bs-card/bs-card.stories.d.ts +10 -0
  111. package/dist/types/components/bs-composer/bs-composer.cmp.test.d.ts +1 -0
  112. package/dist/types/components/bs-composer/bs-composer.d.ts +83 -0
  113. package/dist/types/components/bs-composer/bs-composer.stories.d.ts +17 -0
  114. package/dist/types/components/bs-data-table/bs-data-table.d.ts +55 -0
  115. package/dist/types/components/bs-data-table/bs-data-table.stories.d.ts +7 -0
  116. package/dist/types/components/bs-input/bs-input.cmp.test.d.ts +1 -0
  117. package/dist/types/components/bs-input/bs-input.d.ts +33 -0
  118. package/dist/types/components/bs-input/bs-input.stories.d.ts +15 -0
  119. package/dist/types/components/bs-modal/bs-modal.cmp.test.d.ts +1 -0
  120. package/dist/types/components/bs-modal/bs-modal.d.ts +45 -0
  121. package/dist/types/components/bs-modal/bs-modal.stories.d.ts +9 -0
  122. package/dist/types/components.d.ts +962 -0
  123. package/dist/types/index.d.ts +11 -0
  124. package/dist/types/stencil-public-runtime.d.ts +1872 -0
  125. package/dist/types/stories-utils.d.ts +8 -0
  126. package/dist/types/utils/utils.d.ts +1 -0
  127. package/dist/types/utils/utils.unit.test.d.ts +1 -0
  128. package/loader/cdn.js +1 -0
  129. package/loader/index.cjs.js +1 -0
  130. package/loader/index.d.ts +24 -0
  131. package/loader/index.es2017.js +1 -0
  132. package/loader/index.js +2 -0
  133. package/package.json +67 -0
  134. package/readme.md +48 -0
@@ -0,0 +1,17 @@
1
+ import { r as registerInstance, h } from './index-BOj_41o9.js';
2
+
3
+ const bsBadgeCss = () => `:host{display:inline-block}.bs-badge{display:inline-flex;align-items:center;height:var(--bs-spacing-400);padding:0 var(--bs-spacing-200);border-radius:var(--bs-border-radius-full);font-size:var(--bs-font-size-xs);font-weight:var(--bs-font-weight-medium);font-family:inherit;white-space:nowrap}.bs-badge--default{background:var(--bs-badge-bg-default);color:var(--bs-badge-text-default)}.bs-badge--primary{background:var(--bs-badge-bg-primary-container);color:var(--bs-badge-text-primary)}.bs-badge--success{background:var(--bs-badge-bg-success-container);color:var(--bs-badge-text-success)}.bs-badge--warning{background:var(--bs-badge-bg-warning-container);color:var(--bs-badge-text-warning)}.bs-badge--info{background:var(--bs-badge-bg-info-container);color:var(--bs-badge-text-info)}.bs-badge--error{background:var(--bs-badge-bg-error-container);color:var(--bs-badge-text-error)}.bs-badge--neutral{background:var(--bs-badge-bg-neutral-container);color:var(--bs-badge-text-neutral)}.bs-badge--inverse{background:var(--bs-badge-bg-inverse);color:var(--bs-badge-text-inverse)}`;
4
+
5
+ const BsBadge = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ }
9
+ /** Maps directly to the brandsync-tokens `--bs-badge-bg-*` / `--bs-badge-text-*` sets. */
10
+ variant = 'default';
11
+ render() {
12
+ return (h("span", { key: '9cc06bddba11f57edf97209456e25141a3b80bea', part: "container", class: `bs-badge bs-badge--${this.variant}` }, h("slot", { key: '7c0e4054e99a3dedc94f2a7250075fcb76c115b6' })));
13
+ }
14
+ };
15
+ BsBadge.style = bsBadgeCss();
16
+
17
+ export { BsBadge as bs_badge };
@@ -0,0 +1,17 @@
1
+ import { r as registerInstance, h } from './index-BOj_41o9.js';
2
+
3
+ const bsButtonSkeletonCss = () => `:host{display:inline-block;--bs-button-skeleton-height-sm:var(--bs-spacing-500);--bs-button-skeleton-height-md:var(--bs-spacing-600);--bs-button-skeleton-height-lg:var(--bs-spacing-700);--bs-button-skeleton-width:96px}.bs-button-skeleton{display:inline-block;border-radius:var(--bs-border-radius-100);width:var(--bs-button-skeleton-width);background:var(--bs-color-neutral-container);animation:bs-button-skeleton-pulse 1.5s ease-in-out infinite}.bs-button-skeleton--sm{height:var(--bs-button-skeleton-height-sm)}.bs-button-skeleton--md{height:var(--bs-button-skeleton-height-md)}.bs-button-skeleton--lg{height:var(--bs-button-skeleton-height-lg)}@keyframes bs-button-skeleton-pulse{0%,100%{opacity:1}50%{opacity:0.5}}@media (prefers-reduced-motion: reduce){.bs-button-skeleton{animation:none}}`;
4
+
5
+ const BsButtonSkeleton = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ }
9
+ /** Sizing scale, matching the `bs-button` size it stands in for. */
10
+ size = 'md';
11
+ render() {
12
+ return h("span", { key: 'c54e42fcf6eb065a1a33f2dee8518d12c5797cf3', part: "container", class: `bs-button-skeleton bs-button-skeleton--${this.size}`, role: "status", "aria-label": "Loading" });
13
+ }
14
+ };
15
+ BsButtonSkeleton.style = bsButtonSkeletonCss();
16
+
17
+ export { BsButtonSkeleton as bs_button_skeleton };
@@ -0,0 +1,86 @@
1
+ import { r as registerInstance, a as getElement, h } from './index-BOj_41o9.js';
2
+
3
+ const bsButtonCss = () => `:host{display:inline-block;--bs-button-height-sm:var(--bs-spacing-500);--bs-button-height-md:var(--bs-spacing-600);--bs-button-height-lg:var(--bs-spacing-700);--bs-button-radius:var(--bs-border-radius-100);--bs-button-error-default:var(--bs-color-error-default);--bs-button-error-hover:var(--bs-color-error-hover);--bs-button-error-focus:var(--bs-border-error-focus);--bs-button-error-pressed:var(--bs-color-error-pressed);--bs-button-error-disabled:var(--bs-surface-action-disabled);--bs-button-success-default:var(--bs-color-success-default);--bs-button-success-hover:var(--bs-color-success-hover);--bs-button-success-focus:var(--bs-border-success-focus);--bs-button-success-pressed:var(--bs-color-success-pressed);--bs-button-success-disabled:var(--bs-surface-action-disabled);--bs-button-warning-default:var(--bs-color-warning-default);--bs-button-warning-hover:var(--bs-color-warning-hover);--bs-button-warning-focus:var(--bs-border-warning-focus);--bs-button-warning-pressed:var(--bs-color-warning-pressed);--bs-button-warning-disabled:var(--bs-surface-action-disabled);--bs-button-info-default:var(--bs-color-info-default);--bs-button-info-hover:var(--bs-color-info-hover);--bs-button-info-focus:var(--bs-border-info-focus);--bs-button-info-pressed:var(--bs-color-info-pressed);--bs-button-info-disabled:var(--bs-surface-action-disabled);--bs-button-subtle-hover:var(--bs-color-neutral-container);--bs-button-subtle-pressed:var(--bs-color-neutral-container-pressed);--bs-button-subtle-focus:var(--bs-border-primary-focus);--bs-button-outlined-border:var(--bs-border-primary);--bs-button-outlined-border-hover:var(--bs-border-primary-hover);--bs-button-outlined-focus:var(--bs-border-primary-focus);--bs-button-outlined-container:var(--bs-color-primary-container)}.bs-button{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:none;border-radius:var(--bs-button-radius);font-family:inherit;font-weight:var(--bs-font-weight-semibold);cursor:pointer;transition:background-color var(--bs-duration-fast, 120ms) var(--bs-easing-standard, ease)}.bs-button:focus-visible{outline:2px solid var(--bs-border-neutral-focus);outline-offset:2px}.bs-button:disabled{cursor:not-allowed}.bs-button--sm{height:var(--bs-button-height-sm);padding:0 var(--bs-spacing-300);font-size:var(--bs-font-size-sm)}.bs-button--md{height:var(--bs-button-height-md);padding:0 var(--bs-spacing-400);font-size:var(--bs-font-size-md)}.bs-button--lg{height:var(--bs-button-height-lg);padding:0 var(--bs-spacing-500);font-size:var(--bs-font-size-lg)}.bs-button--primary{background:var(--bs-button-primary-default);color:var(--bs-text-on-action)}.bs-button--primary:hover:not(:disabled){background:var(--bs-button-primary-hover)}.bs-button--primary:active:not(:disabled){background:var(--bs-button-primary-pressed)}.bs-button--primary:disabled{background:var(--bs-button-primary-disabled);color:var(--bs-text-on-disabled)}.bs-button--neutral{background:var(--bs-button-neutral-container);color:var(--bs-text-default)}.bs-button--neutral:hover:not(:disabled){background:var(--bs-button-neutral-hover)}.bs-button--neutral:active:not(:disabled){background:var(--bs-button-neutral-pressed)}.bs-button--neutral:disabled{background:var(--bs-button-neutral-disabled);color:var(--bs-text-on-disabled)}.bs-button--error{background:var(--bs-button-error-default);color:var(--bs-text-on-action)}.bs-button--error:hover:not(:disabled){background:var(--bs-button-error-hover)}.bs-button--error:active:not(:disabled){background:var(--bs-button-error-pressed)}.bs-button--error:disabled{background:var(--bs-button-error-disabled);color:var(--bs-text-on-disabled)}.bs-button--error:focus-visible{outline-color:var(--bs-button-error-focus)}.bs-button--success{background:var(--bs-button-success-default);color:var(--bs-text-on-action)}.bs-button--success:hover:not(:disabled){background:var(--bs-button-success-hover)}.bs-button--success:active:not(:disabled){background:var(--bs-button-success-pressed)}.bs-button--success:disabled{background:var(--bs-button-success-disabled);color:var(--bs-text-on-disabled)}.bs-button--success:focus-visible{outline-color:var(--bs-button-success-focus)}.bs-button--warning{background:var(--bs-button-warning-default);color:var(--bs-text-default)}.bs-button--warning:hover:not(:disabled){background:var(--bs-button-warning-hover)}.bs-button--warning:active:not(:disabled){background:var(--bs-button-warning-pressed)}.bs-button--warning:disabled{background:var(--bs-button-warning-disabled);color:var(--bs-text-on-disabled)}.bs-button--warning:focus-visible{outline-color:var(--bs-button-warning-focus)}.bs-button--info{background:var(--bs-button-info-default);color:var(--bs-text-on-action)}.bs-button--info:hover:not(:disabled){background:var(--bs-button-info-hover)}.bs-button--info:active:not(:disabled){background:var(--bs-button-info-pressed)}.bs-button--info:disabled{background:var(--bs-button-info-disabled);color:var(--bs-text-on-disabled)}.bs-button--info:focus-visible{outline-color:var(--bs-button-info-focus)}.bs-button--subtle{background:transparent;color:var(--bs-color-neutral-default)}.bs-button--subtle:hover:not(:disabled){background:var(--bs-button-subtle-hover)}.bs-button--subtle:active:not(:disabled){background:var(--bs-button-subtle-pressed)}.bs-button--subtle:disabled{background:transparent;color:var(--bs-text-on-disabled)}.bs-button--subtle:focus-visible{outline-color:var(--bs-button-subtle-focus);background:var(--bs-button-subtle-hover)}.bs-button--outlined{background:transparent;color:var(--bs-color-primary-default);border:1.5px solid var(--bs-button-outlined-border)}.bs-button--outlined:hover:not(:disabled){background:var(--bs-button-outlined-container);border-color:var(--bs-button-outlined-border-hover)}.bs-button--outlined:active:not(:disabled){background:var(--bs-button-outlined-container);color:var(--bs-color-primary-pressed);border-color:var(--bs-button-outlined-border-hover)}.bs-button--outlined:disabled{opacity:var(--bs-opacity-disabled);cursor:not-allowed}.bs-button--outlined:focus-visible{outline-color:var(--bs-button-outlined-focus)}.bs-button__icon--visible{margin-right:var(--bs-spacing-100)}.bs-button__end-icon--visible{margin-left:var(--bs-spacing-100)}.bs-button__icon ::slotted(*),.bs-button__end-icon ::slotted(*){display:block;width:1em;height:1em}.bs-button--icon-only{padding:0;aspect-ratio:1 / 1}.bs-button--icon-only .bs-button__icon--visible{margin-right:0}.bs-button--icon-only .bs-button__end-icon--visible{margin-left:0}`;
4
+
5
+ const BsButton = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ }
9
+ get el() { return getElement(this); }
10
+ /**
11
+ * Visual style. Maps directly to the brandsync-tokens `--bs-button-*` semantic set.
12
+ * `error` is for destructive/irreversible actions per BrandSync guidance, not a stronger
13
+ * emphasis alternative to `primary`.
14
+ */
15
+ variant = 'primary';
16
+ /** Sizing scale. */
17
+ size = 'md';
18
+ /** Disables the button and applies the disabled token set. */
19
+ disabled = false;
20
+ /** Native `<button>` type. */
21
+ type = 'button';
22
+ /**
23
+ * Accessible name for the button. Required for icon-only usage (no visible label text via the
24
+ * default slot) so screen readers still announce what the button does. Stencil reflects this
25
+ * camelCase prop to the `aria-label` HTML attribute automatically.
26
+ */
27
+ ariaLabel = null;
28
+ /** Tracks whether the `icon` slot has assigned content, so the icon/label gap only
29
+ * applies when there's actually an icon. */
30
+ hasIcon = false;
31
+ /** Tracks whether the `end-icon` slot has assigned content, so the icon/label gap only
32
+ * applies when there's actually a trailing icon. */
33
+ hasEndIcon = false;
34
+ /**
35
+ * Tracks whether the default (label) slot has assigned content, so an icon-only button can be
36
+ * styled/sized differently (see `bs-button--icon-only`).
37
+ *
38
+ * Known edge case (not fixed, same simplification `hasIcon`/similar flags elsewhere in this
39
+ * codebase already make): a default slot containing only whitespace (e.g. a lone space text
40
+ * node) still counts as `hasLabel = true`, since checking for assigned nodes doesn't
41
+ * distinguish whitespace-only text nodes from real content.
42
+ */
43
+ hasLabel = false;
44
+ /**
45
+ * Computes the initial `hasIcon`/`hasEndIcon`/`hasLabel` state directly from the host's light
46
+ * DOM children, before first render.
47
+ *
48
+ * This can't be left to the `slotchange` handlers below alone: `slotchange` only fires when a
49
+ * slot's *assigned nodes* change, and a slot that starts out with zero assigned nodes and stays
50
+ * that way never fires it (nothing changed). Relying on `slotchange` alone left an icon-only
51
+ * button (default slot empty from the start) permanently stuck on its initial `hasLabel`
52
+ * default, so `bs-button--icon-only` never applied.
53
+ */
54
+ componentWillLoad() {
55
+ this.hasIcon = this.hasSlottedContent('icon');
56
+ this.hasEndIcon = this.hasSlottedContent('end-icon');
57
+ this.hasLabel = this.hasSlottedContent(null);
58
+ }
59
+ hasSlottedContent(slotName) {
60
+ return Array.from(this.el.childNodes).some(node => {
61
+ if (node.nodeType === Node.ELEMENT_NODE) {
62
+ return node.getAttribute('slot') === slotName;
63
+ }
64
+ // Only elements can carry a `slot` attribute -- any other node type (text, comments) can
65
+ // only ever be assigned to the default slot.
66
+ return slotName === null;
67
+ });
68
+ }
69
+ onIconSlotchange = (ev) => {
70
+ this.hasIcon = ev.target.assignedNodes().length > 0;
71
+ };
72
+ onEndIconSlotchange = (ev) => {
73
+ this.hasEndIcon = ev.target.assignedNodes().length > 0;
74
+ };
75
+ onLabelSlotchange = (ev) => {
76
+ this.hasLabel = ev.target.assignedNodes().length > 0;
77
+ };
78
+ render() {
79
+ const iconOnly = (this.hasIcon || this.hasEndIcon) && !this.hasLabel;
80
+ return (h("button", { key: 'eae5915f036d18b43b9b1ff94272fe27aa119d0e', class: `bs-button bs-button--${this.variant} bs-button--${this.size} ${iconOnly ? 'bs-button--icon-only' : ''}`, type: this.type, disabled: this.disabled, "aria-label": this.ariaLabel }, h("span", { key: 'ee58ccc6f8390663e67a7d7a03fe6113782805e7', part: "icon", class: `bs-button__icon ${this.hasIcon ? 'bs-button__icon--visible' : ''}` }, h("slot", { key: '526ec7b4fd274bbdb6dc1edb38c33917c26337ee', name: "icon", onSlotchange: this.onIconSlotchange })), h("span", { key: '3e0121dc4dc975b449b03e5ac5f55d1f6001e806', part: "label", class: "bs-button__label" }, h("slot", { key: '4ab00b8b91f0513af74faac4ae7b39f9a975dde5', onSlotchange: this.onLabelSlotchange })), h("span", { key: '3f64f1122c5ed1da1bb9cb869490395f1e11b3fb', part: "end-icon", class: `bs-button__end-icon ${this.hasEndIcon ? 'bs-button__end-icon--visible' : ''}` }, h("slot", { key: 'ca79d7ed3cd80c6abc3f17c4f9d215ed69c13059', name: "end-icon", onSlotchange: this.onEndIconSlotchange }))));
81
+ }
82
+ static get delegatesFocus() { return true; }
83
+ };
84
+ BsButton.style = bsButtonCss();
85
+
86
+ export { BsButton as bs_button };
@@ -0,0 +1,18 @@
1
+ import { r as registerInstance, h } from './index-BOj_41o9.js';
2
+
3
+ const bsCardCss = () => `:host{display:block}.bs-card{border:1px solid var(--bs-paper-border-surface);border-radius:var(--bs-border-radius-150);padding:var(--bs-spacing-400);font-family:inherit}.bs-card--base{background:var(--bs-paper-bg-base)}.bs-card--raised{background:var(--bs-paper-bg-raised);box-shadow:var(--bs-shadow-sm)}.bs-card--container{background:var(--bs-paper-bg-container)}.bs-card__header ::slotted(*){margin:0 0 var(--bs-spacing-300) 0}.bs-card__footer ::slotted(*){margin:var(--bs-spacing-300) 0 0 0}`;
4
+
5
+ const BsCard = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ }
9
+ /** Maps to the brandsync-tokens `--bs-paper-bg-*` set — Brandsync's tokens don't have a
10
+ * dedicated "card" component yet, so this reuses the existing Paper surface tokens. */
11
+ surface = 'raised';
12
+ render() {
13
+ return (h("div", { key: '6c74e846c97f02a39ce1f2b215c87fbb9cd42055', part: "container", class: `bs-card bs-card--${this.surface}` }, h("div", { key: 'ef89eb6ea19be13daf403b010a93e1f5a82691d4', part: "header", class: "bs-card__header" }, h("slot", { key: '4627d1f598def9298e0b7d251a523892bb0b97cf', name: "header" })), h("div", { key: 'a599746c11f92d2a535985abdcadbc9cc3036fdd', part: "body", class: "bs-card__body" }, h("slot", { key: 'f8d46c5f6aefeb870796c4efa37663e698fdd5c7' })), h("div", { key: '7f928a259fb159b6eb7d742cbfe6c1aacbef6e36', part: "footer", class: "bs-card__footer" }, h("slot", { key: 'fddc69aedbc10f4397bb1db62265c657ec2642ab', name: "footer" }))));
14
+ }
15
+ };
16
+ BsCard.style = bsCardCss();
17
+
18
+ export { BsCard as bs_card };
@@ -0,0 +1,114 @@
1
+ import { r as registerInstance, c as createEvent, h } from './index-BOj_41o9.js';
2
+
3
+ const bsComposerCss = () => `:host{display:block;--bs-composer-radius:var(--bs-border-radius-150);--bs-composer-button-radius:var(--bs-border-radius-100);--bs-composer-button-size:var(--bs-spacing-600);--bs-composer-bg:var(--bs-input-bg-default);--bs-composer-border:var(--bs-input-border-default);--bs-composer-border-focus:var(--bs-input-border-focus);--bs-composer-action-bg:var(--bs-color-primary-default);--bs-composer-action-bg-hover:var(--bs-color-primary-hover);--bs-composer-action-bg-pressed:var(--bs-color-primary-pressed);--bs-composer-action-bg-disabled:var(--bs-surface-action-disabled);--bs-composer-action-icon:var(--bs-text-on-action);--bs-composer-action-icon-disabled:var(--bs-text-on-disabled);--bs-composer-attach-icon:var(--bs-icon-default);--bs-composer-mic-icon:var(--bs-icon-default);--bs-composer-mic-icon-disabled:var(--bs-icon-disabled);--bs-composer-mic-recording-icon:var(--bs-icon-default);--bs-composer-subtle-hover:var(--bs-color-neutral-container);--bs-composer-subtle-pressed:var(--bs-color-neutral-container-pressed);--bs-composer-waveform-color:var(--bs-border-default)}.bs-composer{box-sizing:border-box;display:flex;flex-direction:column;border:1px solid var(--bs-composer-border);border-radius:var(--bs-composer-radius);background:var(--bs-composer-bg);font-family:inherit}.bs-composer--human{border-style:dashed}.bs-composer:focus-within{border-color:var(--bs-composer-border-focus)}.bs-composer__text-row{display:flex;align-items:center;gap:var(--bs-spacing-150);padding:var(--bs-spacing-150)}.bs-composer__input{flex:1;min-width:0;border:none;outline:none;background:transparent;color:var(--bs-input-text);font-family:inherit;font-size:var(--bs-font-size-md)}.bs-composer__input::placeholder{color:var(--bs-input-placeholder)}.bs-composer__input:disabled{color:var(--bs-input-text-disabled);cursor:not-allowed}.bs-composer__waveform{display:inline-flex;flex:1;min-width:0;align-items:center;justify-content:center;gap:3px;overflow:hidden}.bs-composer__waveform-bar{display:inline-block;flex-shrink:0;width:2.5px;border-radius:1.5px;background:var(--bs-composer-waveform-color);height:var(--bs-composer-bar-height, 6px)}.bs-composer__controls-row{display:flex;align-items:center;gap:var(--bs-spacing-200);padding:var(--bs-spacing-150)}.bs-composer__spacer{flex:1}.bs-composer__attach,.bs-composer__mic,.bs-composer__action{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:none;padding:0;cursor:pointer;font-family:inherit;border-radius:var(--bs-composer-button-radius);width:var(--bs-composer-button-size);height:var(--bs-composer-button-size);flex-shrink:0;transition:background-color var(--bs-duration-fast) var(--bs-easing-standard)}.bs-composer__attach:focus-visible,.bs-composer__mic:focus-visible,.bs-composer__action:focus-visible{outline:2px solid var(--bs-border-neutral-focus);outline-offset:2px}.bs-composer__attach svg,.bs-composer__mic svg,.bs-composer__action svg{width:24px;height:24px}.bs-composer__attach,.bs-composer__mic{background:transparent}.bs-composer__attach:hover:not(:disabled),.bs-composer__mic:hover:not(:disabled){background:var(--bs-composer-subtle-hover)}.bs-composer__attach:active:not(:disabled),.bs-composer__mic:active:not(:disabled){background:var(--bs-composer-subtle-pressed)}.bs-composer__attach{color:var(--bs-composer-attach-icon)}.bs-composer__mic{color:var(--bs-composer-mic-icon)}.bs-composer__mic--recording{color:var(--bs-composer-mic-recording-icon)}.bs-composer__mic:disabled{color:var(--bs-composer-mic-icon-disabled);cursor:not-allowed}.bs-composer__action{background:var(--bs-composer-action-bg);color:var(--bs-composer-action-icon)}.bs-composer__action:hover:not(:disabled){background:var(--bs-composer-action-bg-hover)}.bs-composer__action:active:not(:disabled){background:var(--bs-composer-action-bg-pressed)}.bs-composer__action:disabled{background:var(--bs-composer-action-bg-disabled);color:var(--bs-composer-action-icon-disabled);cursor:not-allowed}`;
4
+
5
+ const DEFAULT_PLACEHOLDERS = {
6
+ ai: 'Ask Genie something...',
7
+ human: 'Message your support agent...',
8
+ };
9
+ // Static (non-animated) placeholder audio-level bar heights in px, sampled from the Figma
10
+ // "Audio Waveform" reference (60 bars, 2.5px wide, 3px gap) -- a real analyzer would drive these
11
+ // from actual audio input, this just reproduces the designed look.
12
+ const WAVEFORM_BAR_HEIGHTS = [
13
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 18, 14, 34, 22, 22, 10, 28, 18, 12, 24, 6, 20, 30, 14, 8, 26, 16,
14
+ 32, 10, 22, 18, 12, 28, 8, 20, 14, 24, 10, 16, 30, 12, 22, 6, 18, 26, 8, 14, 32, 20, 10, 24, 6,
15
+ ];
16
+ const BsComposer = class {
17
+ constructor(hostRef) {
18
+ registerInstance(this, hostRef);
19
+ this.bsInput = createEvent(this, "bsInput");
20
+ this.bsSubmit = createEvent(this, "bsSubmit");
21
+ this.bsStop = createEvent(this, "bsStop");
22
+ this.bsVoiceConfirm = createEvent(this, "bsVoiceConfirm");
23
+ this.bsAttach = createEvent(this, "bsAttach");
24
+ this.bsMicToggle = createEvent(this, "bsMicToggle");
25
+ }
26
+ /**
27
+ * Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
28
+ * directly to override it) and, per the Figma design, renders the container border dashed
29
+ * instead of solid for `'human'` -- a deliberate visual cue distinguishing a human-support
30
+ * composer from the AI one, not a layout/token difference.
31
+ */
32
+ variant = 'ai';
33
+ /** Overrides the variant's default placeholder. */
34
+ placeholder;
35
+ /** Current text value. Native `input` events don't cross the Shadow DOM boundary, so this
36
+ * component re-dispatches them as a `bsInput` custom event instead. */
37
+ value = '';
38
+ /**
39
+ * Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),
40
+ * `generating` (stop, while the AI is responding), `disabled` (send, but not interactive), or
41
+ * `recording` (voice input in progress -- shows a waveform and a confirm action).
42
+ */
43
+ state = 'idle';
44
+ /**
45
+ * Accessible name for the text field. This component has no visible `<label>` (chat composers
46
+ * don't show one in the design), so `ariaLabel` is the only way a consumer gives the textbox an
47
+ * accessible name -- set it in every real usage.
48
+ */
49
+ ariaLabel = null;
50
+ /** Fires on every keystroke in the text field, with the current value. */
51
+ bsInput;
52
+ /** Fires when the primary action button is clicked while `state="idle"`. */
53
+ bsSubmit;
54
+ /** Fires when the primary action button is clicked while `state="generating"`. */
55
+ bsStop;
56
+ /** Fires when the primary action button is clicked while `state="recording"`. */
57
+ bsVoiceConfirm;
58
+ /** Fires when the "+" attach button is clicked. */
59
+ bsAttach;
60
+ /** Fires when the mic/stop-recording button is clicked. The consumer decides what that means
61
+ * (e.g. start recording when idle/generating, or stop recording when `state="recording"`). */
62
+ bsMicToggle;
63
+ onInput = (ev) => {
64
+ const value = ev.target.value;
65
+ this.bsInput.emit(value);
66
+ };
67
+ onAttachClick = () => {
68
+ this.bsAttach.emit();
69
+ };
70
+ onMicClick = () => {
71
+ this.bsMicToggle.emit();
72
+ };
73
+ onActionClick = () => {
74
+ if (this.state === 'idle') {
75
+ this.bsSubmit.emit();
76
+ }
77
+ else if (this.state === 'generating') {
78
+ this.bsStop.emit();
79
+ }
80
+ else if (this.state === 'recording') {
81
+ this.bsVoiceConfirm.emit();
82
+ }
83
+ };
84
+ actionLabel() {
85
+ if (this.state === 'generating')
86
+ return 'Stop';
87
+ if (this.state === 'recording')
88
+ return 'Confirm';
89
+ return 'Send';
90
+ }
91
+ renderActionIcon() {
92
+ if (this.state === 'generating')
93
+ return h(StopIcon, null);
94
+ if (this.state === 'recording')
95
+ return h(CheckIcon, null);
96
+ return h(SendIcon, null);
97
+ }
98
+ render() {
99
+ const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
100
+ const disabled = this.state === 'disabled';
101
+ const recording = this.state === 'recording';
102
+ return (h("div", { key: '785b4da8ddb23f4762ac7ea379b3ecdaa9584f40', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, h("div", { key: '5b470cc47221f93ce9852ebaeaf9a35d740d5df1', class: "bs-composer__text-row" }, h("input", { key: '3f4093d98bc0a0ba8440da9fec1d5cb2e302b746', part: "input", class: "bs-composer__input", type: "text", value: this.value, placeholder: placeholder, disabled: disabled, "aria-label": this.ariaLabel, onInput: this.onInput })), h("div", { key: '21103c8d6ac108e705487f670aeb4aaf89d45981', class: "bs-composer__controls-row" }, h("button", { key: '570ef86150f5b0072008fb0215ed1f0affac7af4', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, h(PlusIcon, { key: 'ea030569c8b5d2bafaae3ecfe29b956a54921f34' })), recording ? (h("span", { class: "bs-composer__waveform", "aria-hidden": "true" }, WAVEFORM_BAR_HEIGHTS.map(height => (h("span", { class: "bs-composer__waveform-bar", style: { '--bs-composer-bar-height': `${height}px` } }))))) : (h("span", { class: "bs-composer__spacer" })), h("button", { key: '1906485b13395c9c730f7091176dab4e81ecbcb9', type: "button", part: "mic", class: `bs-composer__mic ${recording ? 'bs-composer__mic--recording' : ''}`, "aria-label": recording ? 'Stop recording' : 'Start voice input', disabled: disabled, onClick: this.onMicClick }, recording ? h(StopIcon, null) : h(MicIcon, null)), h("button", { key: '3486957673a3bbf7c3dbac41fd5c19e8dbb6258a', type: "button", part: "action", class: `bs-composer__action bs-composer__action--${this.state}`, "aria-label": this.actionLabel(), disabled: disabled, onClick: this.onActionClick }, this.renderActionIcon()))));
103
+ }
104
+ static get delegatesFocus() { return true; }
105
+ };
106
+ const PlusIcon = () => (h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M8 2.5V13.5M2.5 8H13.5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" })));
107
+ const MicIcon = () => (h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M8 9.5C9.10457 9.5 10 8.60457 10 7.5V3.5C10 2.39543 9.10457 1.5 8 1.5C6.89543 1.5 6 2.39543 6 3.5V7.5C6 8.60457 6.89543 9.5 8 9.5Z", stroke: "currentColor", "stroke-width": "1.4" }), h("path", { d: "M3.5 7V7.5C3.5 9.98528 5.51472 12 8 12C10.4853 12 12.5 9.98528 12.5 7.5V7", stroke: "currentColor", "stroke-width": "1.4", "stroke-linecap": "round" }), h("path", { d: "M8 12V14.5", stroke: "currentColor", "stroke-width": "1.4", "stroke-linecap": "round" })));
108
+ // Exact "PaperPlaneRight" path from the Figma design (node 45:95), not a hand-drawn approximation.
109
+ const SendIcon = () => (h("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M13.5 12H7.5", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), h("path", { d: "M4.54594 20.745C4.4932 20.889 4.48589 21.0457 4.52499 21.1941C4.56409 21.3424 4.64771 21.4751 4.76459 21.5744C4.88147 21.6737 5.02599 21.7348 5.17866 21.7494C5.33133 21.7641 5.48482 21.7315 5.61844 21.6562L21.3684 12.6478C21.4857 12.583 21.5834 12.4879 21.6514 12.3725C21.7195 12.2571 21.7553 12.1255 21.7553 11.9916C21.7553 11.8576 21.7195 11.7261 21.6514 11.6107C21.5834 11.4952 21.4857 11.4002 21.3684 11.3353L5.61844 2.34937C5.48523 2.27487 5.33245 2.24278 5.18052 2.2574C5.02859 2.27201 4.88474 2.33264 4.76817 2.43117C4.65161 2.5297 4.56788 2.66145 4.52817 2.80882C4.48846 2.9562 4.49466 3.11218 4.54594 3.25594L7.5 12L4.54594 20.745Z", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" })));
110
+ const StopIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("rect", { x: "6", y: "6", width: "8", height: "8", rx: "1.5", fill: "currentColor" })));
111
+ const CheckIcon = () => (h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, h("path", { d: "M4.5 10.5L8 14L15.5 6", stroke: "currentColor", "stroke-width": "1.75", "stroke-linecap": "round", "stroke-linejoin": "round" })));
112
+ BsComposer.style = bsComposerCss();
113
+
114
+ export { BsComposer as bs_composer };
@@ -0,0 +1,60 @@
1
+ import { r as registerInstance, c as createEvent, h } from './index-BOj_41o9.js';
2
+
3
+ const bsDataTableCss = () => `:host{display:block}.bs-data-table{width:100%;border-collapse:collapse;font-family:inherit;font-size:var(--bs-font-size-sm);color:var(--bs-text-default)}.bs-data-table__header-cell{text-align:left;padding:var(--bs-spacing-200) var(--bs-spacing-300);border-bottom:1px solid var(--bs-border-default);font-weight:var(--bs-font-weight-semibold);color:var(--bs-text-secondary);white-space:nowrap}.bs-data-table__sort-button{display:inline-flex;align-items:center;border:none;background:none;padding:0;font:inherit;color:inherit;cursor:pointer;user-select:none}.bs-data-table__sort-button:focus-visible{outline:2px solid var(--bs-border-neutral-focus);outline-offset:2px}.bs-data-table__sort-indicator{color:var(--bs-text-action)}.bs-data-table__row:hover{background:var(--bs-surface-hover)}.bs-data-table__cell{padding:var(--bs-spacing-200) var(--bs-spacing-300);border-bottom:1px solid var(--bs-border-default)}.bs-data-table__select-col{width:var(--bs-spacing-500);padding:var(--bs-spacing-200) var(--bs-spacing-300);border-bottom:1px solid var(--bs-border-default)}`;
4
+
5
+ const BsDataTable = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ this.bsSort = createEvent(this, "bsSort");
9
+ this.bsRowSelect = createEvent(this, "bsRowSelect");
10
+ }
11
+ /** Array prop -- must be set as a JS property (`el.columns = [...]`), not an HTML attribute,
12
+ * since attributes can only carry strings. See CONVENTIONS.md. */
13
+ columns = [];
14
+ /** Array prop -- same JS-property-only rule as `columns`. */
15
+ rows = [];
16
+ sortColumn;
17
+ sortDirection = 'asc';
18
+ selectable = false;
19
+ /** Optional custom cell renderer, e.g. for an actions column. Function props are JS-property-only,
20
+ * same as array props -- there is no attribute equivalent. Falls back to the raw cell value. */
21
+ cellRenderer;
22
+ bsSort;
23
+ bsRowSelect;
24
+ selectedIds = new Set();
25
+ onHeaderClick = (column) => {
26
+ if (!column.sortable)
27
+ return;
28
+ const direction = this.sortColumn === column.key && this.sortDirection === 'asc' ? 'desc' : 'asc';
29
+ this.bsSort.emit({ column: column.key, direction });
30
+ };
31
+ onRowCheckboxChange = (row, ev) => {
32
+ const selected = ev.target.checked;
33
+ const next = new Set(this.selectedIds);
34
+ if (selected) {
35
+ next.add(row.id);
36
+ }
37
+ else {
38
+ next.delete(row.id);
39
+ }
40
+ this.selectedIds = next;
41
+ this.bsRowSelect.emit({ id: row.id, selected });
42
+ };
43
+ render() {
44
+ return (h("table", { key: '9d51da1ed65a523ac8008fde2f77673a68e4e39e', part: "table", class: "bs-data-table" }, h("thead", { key: 'e1baef3845a07af164e2c91cd3979d1ff76eb767', part: "head" }, h("tr", { key: '930648d2ced662352ddfb7dfc9748501324e7bf3' }, this.selectable && h("th", { key: 'd61beed09258e8ba9c087d4d922eebb6591735e9', class: "bs-data-table__select-col" }), this.columns.map(column => {
45
+ const isSorted = this.sortColumn === column.key;
46
+ const ariaSort = column.sortable ? (isSorted ? (this.sortDirection === 'asc' ? 'ascending' : 'descending') : 'none') : undefined;
47
+ return (h("th", { part: "header-cell", class: "bs-data-table__header-cell", "aria-sort": ariaSort }, column.sortable ? (h("button", { type: "button", class: "bs-data-table__sort-button", onClick: () => this.onHeaderClick(column) }, column.label, isSorted && h("span", { class: "bs-data-table__sort-indicator" }, this.sortDirection === 'asc' ? ' ▲' : ' ▼'))) : (column.label)));
48
+ }))), h("tbody", { key: '2015f29ec50c9e99ce63366ea06a4d9082fc638d', part: "body" }, this.rows.map(row => (h("tr", { part: "row", class: "bs-data-table__row" }, this.selectable && (h("td", { class: "bs-data-table__select-col" }, h("input", { type: "checkbox", checked: this.selectedIds.has(row.id), onChange: ev => this.onRowCheckboxChange(row, ev) }))), this.columns.map(column => this.cellRenderer ? (
49
+ // cellRenderer is a developer-supplied, trusted function (JS-property-only, never
50
+ // derived from untrusted input) -- its HTML output is intentionally not escaped,
51
+ // same trust model as React's dangerouslySetInnerHTML.
52
+ h("td", { part: "cell", class: "bs-data-table__cell", innerHTML: this.cellRenderer(row, column) })) : (
53
+ // Default path renders raw cell values as plain text so untrusted row data
54
+ // (e.g. user-submitted names) can never be interpreted as HTML.
55
+ h("td", { part: "cell", class: "bs-data-table__cell" }, String(row[column.key] ?? ''))))))))));
56
+ }
57
+ };
58
+ BsDataTable.style = bsDataTableCss();
59
+
60
+ export { BsDataTable as bs_data_table };
@@ -0,0 +1,40 @@
1
+ import { r as registerInstance, c as createEvent, h } from './index-BOj_41o9.js';
2
+
3
+ const bsInputCss = () => `:host{display:block}.bs-input{display:flex;flex-direction:column;gap:var(--bs-spacing-100);font-family:inherit}.bs-input__label{font-size:var(--bs-font-size-sm);font-weight:var(--bs-font-weight-medium);color:var(--bs-input-label)}.bs-input__control{height:var(--bs-spacing-600);padding:0 var(--bs-spacing-300);border:1px solid var(--bs-input-border-default);border-radius:var(--bs-border-radius-100);background:var(--bs-input-bg-default);color:var(--bs-input-text);font-size:var(--bs-font-size-md);font-family:inherit}.bs-input__control::placeholder{color:var(--bs-input-placeholder)}.bs-input__control:hover:not(:disabled){border-color:var(--bs-input-border-hover)}.bs-input__control:focus-visible{outline:none;border-color:var(--bs-input-border-focus)}.bs-input__control:disabled{background:var(--bs-input-bg-disabled);color:var(--bs-input-text-disabled);cursor:not-allowed}.bs-input--error .bs-input__control{border-color:var(--bs-input-border-error)}.bs-input--error .bs-input__label{color:var(--bs-input-label)}.bs-input__description{font-size:var(--bs-font-size-xs);color:var(--bs-input-description)}.bs-input__error{font-size:var(--bs-font-size-xs);color:var(--bs-input-error)}`;
4
+
5
+ const BsInput = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ this.bsInput = createEvent(this, "bsInput");
9
+ this.bsChange = createEvent(this, "bsChange");
10
+ }
11
+ /** Current value. Native `input`/`change` events don't cross the Shadow DOM boundary, so this
12
+ * component re-dispatches them as `bsInput`/`bsChange` custom events instead. */
13
+ value = '';
14
+ type = 'text';
15
+ label;
16
+ placeholder;
17
+ description;
18
+ error;
19
+ disabled = false;
20
+ bsInput;
21
+ bsChange;
22
+ onInput = (ev) => {
23
+ const value = ev.target.value;
24
+ this.bsInput.emit(value);
25
+ };
26
+ onChange = (ev) => {
27
+ const value = ev.target.value;
28
+ this.bsChange.emit(value);
29
+ };
30
+ render() {
31
+ return (h("div", { key: '94a90f72a348259c9e54b1eb61ca694baf7c0386', class: `bs-input ${this.error ? 'bs-input--error' : ''}` }, this.label && (
32
+ // "control" is a fixed id, not a generated one -- safe because Shadow DOM scopes ids
33
+ // to this instance's own shadow root, so it can never collide with another bs-input.
34
+ h("label", { key: '3760b135aaf4002b86e0552af5e3cad110b45afe', part: "label", class: "bs-input__label", htmlFor: "control" }, this.label)), h("input", { key: '761d594818ee8ad917562b9dbe945e5ea8d9210c', id: "control", part: "control", class: "bs-input__control", type: this.type, value: this.value, placeholder: this.placeholder, disabled: this.disabled, "aria-describedby": this.error || this.description ? 'description-or-error' : undefined, "aria-invalid": this.error ? 'true' : undefined, onInput: this.onInput, onChange: this.onChange }), this.error ? (h("span", { id: "description-or-error", part: "error", class: "bs-input__error" }, this.error)) : this.description ? (h("span", { id: "description-or-error", part: "description", class: "bs-input__description" }, this.description)) : null));
35
+ }
36
+ static get delegatesFocus() { return true; }
37
+ };
38
+ BsInput.style = bsInputCss();
39
+
40
+ export { BsInput as bs_input };
@@ -0,0 +1,67 @@
1
+ import { r as registerInstance, c as createEvent, h } from './index-BOj_41o9.js';
2
+
3
+ const bsModalCss = () => `.bs-modal__backdrop{position:fixed;inset:0;z-index:var(--bs-z-index-modal);display:flex;align-items:center;justify-content:center;background:rgba(0, 0, 0, 0.4)}.bs-modal__dialog{display:flex;flex-direction:column;max-height:calc(100vh - var(--bs-spacing-800));background:var(--bs-surface-raised);border-radius:var(--bs-border-radius-200);box-shadow:var(--bs-shadow-xl);font-family:inherit}.bs-modal__dialog--sm{width:360px}.bs-modal__dialog--md{width:560px}.bs-modal__dialog--lg{width:800px}.bs-modal__header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-spacing-400);border-bottom:1px solid var(--bs-border-default)}.bs-modal__heading{font-size:var(--bs-font-size-lg);font-weight:var(--bs-font-weight-semibold);color:var(--bs-text-default)}.bs-modal__close{border:none;background:none;font-size:var(--bs-font-size-xl);line-height:1;color:var(--bs-icon-muted, var(--bs-text-secondary));cursor:pointer;padding:var(--bs-spacing-100)}.bs-modal__body{padding:var(--bs-spacing-400);overflow-y:auto}.bs-modal__footer--visible{display:flex;justify-content:flex-end;gap:var(--bs-spacing-200);padding:var(--bs-spacing-400);border-top:1px solid var(--bs-border-default)}`;
4
+
5
+ const BsModal = class {
6
+ constructor(hostRef) {
7
+ registerInstance(this, hostRef);
8
+ this.bsClose = createEvent(this, "bsClose");
9
+ }
10
+ /** Mutable + reflected so the component can close itself (backdrop click, Escape, close button)
11
+ * the same way a native `<dialog>` does, while still emitting `bsClose` for the consumer to react to. */
12
+ open = false;
13
+ heading;
14
+ size = 'md';
15
+ bsClose;
16
+ /** Tracks whether the `footer` slot has assigned content, so the footer bar (border + padding)
17
+ * only renders when there's actually something to put in it. */
18
+ hasFooter = false;
19
+ onFooterSlotchange = (ev) => {
20
+ this.hasFooter = ev.target.assignedNodes().length > 0;
21
+ };
22
+ dialogRef;
23
+ previouslyFocused;
24
+ wasOpen = false;
25
+ close = () => {
26
+ this.open = false;
27
+ this.bsClose.emit();
28
+ };
29
+ onKeydown(ev) {
30
+ if (this.open && ev.key === 'Escape') {
31
+ this.close();
32
+ }
33
+ }
34
+ onBackdropClick = (ev) => {
35
+ if (ev.target === ev.currentTarget) {
36
+ this.close();
37
+ }
38
+ };
39
+ // Simple focus containment: rather than manually enumerating focusable elements (which can't
40
+ // reliably walk into slotted children's own Shadow DOM anyway), redirect any focus that lands
41
+ // outside the dialog back to it. composedPath() correctly reports elements across Shadow DOM
42
+ // boundaries, unlike a plain `.contains()` check.
43
+ onFocusIn(ev) {
44
+ if (this.open && this.dialogRef && !ev.composedPath().includes(this.dialogRef)) {
45
+ this.dialogRef.focus();
46
+ }
47
+ }
48
+ componentDidRender() {
49
+ if (this.open && !this.wasOpen) {
50
+ this.previouslyFocused = document.activeElement;
51
+ this.dialogRef?.focus();
52
+ }
53
+ else if (!this.open && this.wasOpen) {
54
+ this.previouslyFocused?.focus();
55
+ }
56
+ this.wasOpen = this.open;
57
+ }
58
+ render() {
59
+ if (!this.open) {
60
+ return null;
61
+ }
62
+ return (h("div", { part: "backdrop", class: "bs-modal__backdrop", onClick: this.onBackdropClick }, h("div", { ref: el => (this.dialogRef = el), tabIndex: -1, part: "dialog", class: `bs-modal__dialog bs-modal__dialog--${this.size}`, role: "dialog", "aria-modal": "true", "aria-label": this.heading }, h("div", { part: "header", class: "bs-modal__header" }, h("span", { class: "bs-modal__heading" }, this.heading), h("button", { part: "close", class: "bs-modal__close", "aria-label": "Close", onClick: this.close }, "\u00D7")), h("div", { part: "body", class: "bs-modal__body" }, h("slot", null)), h("div", { part: "footer", class: `bs-modal__footer ${this.hasFooter ? 'bs-modal__footer--visible' : ''}` }, h("slot", { name: "footer", onSlotchange: this.onFooterSlotchange })))));
63
+ }
64
+ };
65
+ BsModal.style = bsModalCss();
66
+
67
+ export { BsModal as bs_modal };