@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,116 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-nyOcuVbF.js');
4
+
5
+ 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}`;
6
+
7
+ const DEFAULT_PLACEHOLDERS = {
8
+ ai: 'Ask Genie something...',
9
+ human: 'Message your support agent...',
10
+ };
11
+ // Static (non-animated) placeholder audio-level bar heights in px, sampled from the Figma
12
+ // "Audio Waveform" reference (60 bars, 2.5px wide, 3px gap) -- a real analyzer would drive these
13
+ // from actual audio input, this just reproduces the designed look.
14
+ const WAVEFORM_BAR_HEIGHTS = [
15
+ 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,
16
+ 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,
17
+ ];
18
+ const BsComposer = class {
19
+ constructor(hostRef) {
20
+ index.registerInstance(this, hostRef);
21
+ this.bsInput = index.createEvent(this, "bsInput");
22
+ this.bsSubmit = index.createEvent(this, "bsSubmit");
23
+ this.bsStop = index.createEvent(this, "bsStop");
24
+ this.bsVoiceConfirm = index.createEvent(this, "bsVoiceConfirm");
25
+ this.bsAttach = index.createEvent(this, "bsAttach");
26
+ this.bsMicToggle = index.createEvent(this, "bsMicToggle");
27
+ }
28
+ /**
29
+ * Which flavor of composer this is: changes the *default* placeholder text (set `placeholder`
30
+ * directly to override it) and, per the Figma design, renders the container border dashed
31
+ * instead of solid for `'human'` -- a deliberate visual cue distinguishing a human-support
32
+ * composer from the AI one, not a layout/token difference.
33
+ */
34
+ variant = 'ai';
35
+ /** Overrides the variant's default placeholder. */
36
+ placeholder;
37
+ /** Current text value. Native `input` events don't cross the Shadow DOM boundary, so this
38
+ * component re-dispatches them as a `bsInput` custom event instead. */
39
+ value = '';
40
+ /**
41
+ * Which of the four mutually-exclusive composer states to render: `idle` (send, enabled),
42
+ * `generating` (stop, while the AI is responding), `disabled` (send, but not interactive), or
43
+ * `recording` (voice input in progress -- shows a waveform and a confirm action).
44
+ */
45
+ state = 'idle';
46
+ /**
47
+ * Accessible name for the text field. This component has no visible `<label>` (chat composers
48
+ * don't show one in the design), so `ariaLabel` is the only way a consumer gives the textbox an
49
+ * accessible name -- set it in every real usage.
50
+ */
51
+ ariaLabel = null;
52
+ /** Fires on every keystroke in the text field, with the current value. */
53
+ bsInput;
54
+ /** Fires when the primary action button is clicked while `state="idle"`. */
55
+ bsSubmit;
56
+ /** Fires when the primary action button is clicked while `state="generating"`. */
57
+ bsStop;
58
+ /** Fires when the primary action button is clicked while `state="recording"`. */
59
+ bsVoiceConfirm;
60
+ /** Fires when the "+" attach button is clicked. */
61
+ bsAttach;
62
+ /** Fires when the mic/stop-recording button is clicked. The consumer decides what that means
63
+ * (e.g. start recording when idle/generating, or stop recording when `state="recording"`). */
64
+ bsMicToggle;
65
+ onInput = (ev) => {
66
+ const value = ev.target.value;
67
+ this.bsInput.emit(value);
68
+ };
69
+ onAttachClick = () => {
70
+ this.bsAttach.emit();
71
+ };
72
+ onMicClick = () => {
73
+ this.bsMicToggle.emit();
74
+ };
75
+ onActionClick = () => {
76
+ if (this.state === 'idle') {
77
+ this.bsSubmit.emit();
78
+ }
79
+ else if (this.state === 'generating') {
80
+ this.bsStop.emit();
81
+ }
82
+ else if (this.state === 'recording') {
83
+ this.bsVoiceConfirm.emit();
84
+ }
85
+ };
86
+ actionLabel() {
87
+ if (this.state === 'generating')
88
+ return 'Stop';
89
+ if (this.state === 'recording')
90
+ return 'Confirm';
91
+ return 'Send';
92
+ }
93
+ renderActionIcon() {
94
+ if (this.state === 'generating')
95
+ return index.h(StopIcon, null);
96
+ if (this.state === 'recording')
97
+ return index.h(CheckIcon, null);
98
+ return index.h(SendIcon, null);
99
+ }
100
+ render() {
101
+ const placeholder = this.placeholder ?? DEFAULT_PLACEHOLDERS[this.variant];
102
+ const disabled = this.state === 'disabled';
103
+ const recording = this.state === 'recording';
104
+ return (index.h("div", { key: '785b4da8ddb23f4762ac7ea379b3ecdaa9584f40', class: `bs-composer bs-composer--${this.state} bs-composer--${this.variant}` }, index.h("div", { key: '5b470cc47221f93ce9852ebaeaf9a35d740d5df1', class: "bs-composer__text-row" }, index.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 })), index.h("div", { key: '21103c8d6ac108e705487f670aeb4aaf89d45981', class: "bs-composer__controls-row" }, index.h("button", { key: '570ef86150f5b0072008fb0215ed1f0affac7af4', type: "button", part: "attach", class: "bs-composer__attach", "aria-label": "Attach", onClick: this.onAttachClick }, index.h(PlusIcon, { key: 'ea030569c8b5d2bafaae3ecfe29b956a54921f34' })), recording ? (index.h("span", { class: "bs-composer__waveform", "aria-hidden": "true" }, WAVEFORM_BAR_HEIGHTS.map(height => (index.h("span", { class: "bs-composer__waveform-bar", style: { '--bs-composer-bar-height': `${height}px` } }))))) : (index.h("span", { class: "bs-composer__spacer" })), index.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 ? index.h(StopIcon, null) : index.h(MicIcon, null)), index.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()))));
105
+ }
106
+ static get delegatesFocus() { return true; }
107
+ };
108
+ const PlusIcon = () => (index.h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, index.h("path", { d: "M8 2.5V13.5M2.5 8H13.5", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round" })));
109
+ const MicIcon = () => (index.h("svg", { viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, index.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" }), index.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" }), index.h("path", { d: "M8 12V14.5", stroke: "currentColor", "stroke-width": "1.4", "stroke-linecap": "round" })));
110
+ // Exact "PaperPlaneRight" path from the Figma design (node 45:95), not a hand-drawn approximation.
111
+ const SendIcon = () => (index.h("svg", { viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, index.h("path", { d: "M13.5 12H7.5", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round" }), index.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" })));
112
+ const StopIcon = () => (index.h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, index.h("rect", { x: "6", y: "6", width: "8", height: "8", rx: "1.5", fill: "currentColor" })));
113
+ const CheckIcon = () => (index.h("svg", { viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true" }, index.h("path", { d: "M4.5 10.5L8 14L15.5 6", stroke: "currentColor", "stroke-width": "1.75", "stroke-linecap": "round", "stroke-linejoin": "round" })));
114
+ BsComposer.style = bsComposerCss();
115
+
116
+ exports.bs_composer = BsComposer;
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-nyOcuVbF.js');
4
+
5
+ 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)}`;
6
+
7
+ const BsDataTable = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.bsSort = index.createEvent(this, "bsSort");
11
+ this.bsRowSelect = index.createEvent(this, "bsRowSelect");
12
+ }
13
+ /** Array prop -- must be set as a JS property (`el.columns = [...]`), not an HTML attribute,
14
+ * since attributes can only carry strings. See CONVENTIONS.md. */
15
+ columns = [];
16
+ /** Array prop -- same JS-property-only rule as `columns`. */
17
+ rows = [];
18
+ sortColumn;
19
+ sortDirection = 'asc';
20
+ selectable = false;
21
+ /** Optional custom cell renderer, e.g. for an actions column. Function props are JS-property-only,
22
+ * same as array props -- there is no attribute equivalent. Falls back to the raw cell value. */
23
+ cellRenderer;
24
+ bsSort;
25
+ bsRowSelect;
26
+ selectedIds = new Set();
27
+ onHeaderClick = (column) => {
28
+ if (!column.sortable)
29
+ return;
30
+ const direction = this.sortColumn === column.key && this.sortDirection === 'asc' ? 'desc' : 'asc';
31
+ this.bsSort.emit({ column: column.key, direction });
32
+ };
33
+ onRowCheckboxChange = (row, ev) => {
34
+ const selected = ev.target.checked;
35
+ const next = new Set(this.selectedIds);
36
+ if (selected) {
37
+ next.add(row.id);
38
+ }
39
+ else {
40
+ next.delete(row.id);
41
+ }
42
+ this.selectedIds = next;
43
+ this.bsRowSelect.emit({ id: row.id, selected });
44
+ };
45
+ render() {
46
+ return (index.h("table", { key: '9d51da1ed65a523ac8008fde2f77673a68e4e39e', part: "table", class: "bs-data-table" }, index.h("thead", { key: 'e1baef3845a07af164e2c91cd3979d1ff76eb767', part: "head" }, index.h("tr", { key: '930648d2ced662352ddfb7dfc9748501324e7bf3' }, this.selectable && index.h("th", { key: 'd61beed09258e8ba9c087d4d922eebb6591735e9', class: "bs-data-table__select-col" }), this.columns.map(column => {
47
+ const isSorted = this.sortColumn === column.key;
48
+ const ariaSort = column.sortable ? (isSorted ? (this.sortDirection === 'asc' ? 'ascending' : 'descending') : 'none') : undefined;
49
+ return (index.h("th", { part: "header-cell", class: "bs-data-table__header-cell", "aria-sort": ariaSort }, column.sortable ? (index.h("button", { type: "button", class: "bs-data-table__sort-button", onClick: () => this.onHeaderClick(column) }, column.label, isSorted && index.h("span", { class: "bs-data-table__sort-indicator" }, this.sortDirection === 'asc' ? ' ▲' : ' ▼'))) : (column.label)));
50
+ }))), index.h("tbody", { key: '2015f29ec50c9e99ce63366ea06a4d9082fc638d', part: "body" }, this.rows.map(row => (index.h("tr", { part: "row", class: "bs-data-table__row" }, this.selectable && (index.h("td", { class: "bs-data-table__select-col" }, index.h("input", { type: "checkbox", checked: this.selectedIds.has(row.id), onChange: ev => this.onRowCheckboxChange(row, ev) }))), this.columns.map(column => this.cellRenderer ? (
51
+ // cellRenderer is a developer-supplied, trusted function (JS-property-only, never
52
+ // derived from untrusted input) -- its HTML output is intentionally not escaped,
53
+ // same trust model as React's dangerouslySetInnerHTML.
54
+ index.h("td", { part: "cell", class: "bs-data-table__cell", innerHTML: this.cellRenderer(row, column) })) : (
55
+ // Default path renders raw cell values as plain text so untrusted row data
56
+ // (e.g. user-submitted names) can never be interpreted as HTML.
57
+ index.h("td", { part: "cell", class: "bs-data-table__cell" }, String(row[column.key] ?? ''))))))))));
58
+ }
59
+ };
60
+ BsDataTable.style = bsDataTableCss();
61
+
62
+ exports.bs_data_table = BsDataTable;
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-nyOcuVbF.js');
4
+
5
+ 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)}`;
6
+
7
+ const BsInput = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.bsInput = index.createEvent(this, "bsInput");
11
+ this.bsChange = index.createEvent(this, "bsChange");
12
+ }
13
+ /** Current value. Native `input`/`change` events don't cross the Shadow DOM boundary, so this
14
+ * component re-dispatches them as `bsInput`/`bsChange` custom events instead. */
15
+ value = '';
16
+ type = 'text';
17
+ label;
18
+ placeholder;
19
+ description;
20
+ error;
21
+ disabled = false;
22
+ bsInput;
23
+ bsChange;
24
+ onInput = (ev) => {
25
+ const value = ev.target.value;
26
+ this.bsInput.emit(value);
27
+ };
28
+ onChange = (ev) => {
29
+ const value = ev.target.value;
30
+ this.bsChange.emit(value);
31
+ };
32
+ render() {
33
+ return (index.h("div", { key: '94a90f72a348259c9e54b1eb61ca694baf7c0386', class: `bs-input ${this.error ? 'bs-input--error' : ''}` }, this.label && (
34
+ // "control" is a fixed id, not a generated one -- safe because Shadow DOM scopes ids
35
+ // to this instance's own shadow root, so it can never collide with another bs-input.
36
+ index.h("label", { key: '3760b135aaf4002b86e0552af5e3cad110b45afe', part: "label", class: "bs-input__label", htmlFor: "control" }, this.label)), index.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 ? (index.h("span", { id: "description-or-error", part: "error", class: "bs-input__error" }, this.error)) : this.description ? (index.h("span", { id: "description-or-error", part: "description", class: "bs-input__description" }, this.description)) : null));
37
+ }
38
+ static get delegatesFocus() { return true; }
39
+ };
40
+ BsInput.style = bsInputCss();
41
+
42
+ exports.bs_input = BsInput;
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-nyOcuVbF.js');
4
+
5
+ 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)}`;
6
+
7
+ const BsModal = class {
8
+ constructor(hostRef) {
9
+ index.registerInstance(this, hostRef);
10
+ this.bsClose = index.createEvent(this, "bsClose");
11
+ }
12
+ /** Mutable + reflected so the component can close itself (backdrop click, Escape, close button)
13
+ * the same way a native `<dialog>` does, while still emitting `bsClose` for the consumer to react to. */
14
+ open = false;
15
+ heading;
16
+ size = 'md';
17
+ bsClose;
18
+ /** Tracks whether the `footer` slot has assigned content, so the footer bar (border + padding)
19
+ * only renders when there's actually something to put in it. */
20
+ hasFooter = false;
21
+ onFooterSlotchange = (ev) => {
22
+ this.hasFooter = ev.target.assignedNodes().length > 0;
23
+ };
24
+ dialogRef;
25
+ previouslyFocused;
26
+ wasOpen = false;
27
+ close = () => {
28
+ this.open = false;
29
+ this.bsClose.emit();
30
+ };
31
+ onKeydown(ev) {
32
+ if (this.open && ev.key === 'Escape') {
33
+ this.close();
34
+ }
35
+ }
36
+ onBackdropClick = (ev) => {
37
+ if (ev.target === ev.currentTarget) {
38
+ this.close();
39
+ }
40
+ };
41
+ // Simple focus containment: rather than manually enumerating focusable elements (which can't
42
+ // reliably walk into slotted children's own Shadow DOM anyway), redirect any focus that lands
43
+ // outside the dialog back to it. composedPath() correctly reports elements across Shadow DOM
44
+ // boundaries, unlike a plain `.contains()` check.
45
+ onFocusIn(ev) {
46
+ if (this.open && this.dialogRef && !ev.composedPath().includes(this.dialogRef)) {
47
+ this.dialogRef.focus();
48
+ }
49
+ }
50
+ componentDidRender() {
51
+ if (this.open && !this.wasOpen) {
52
+ this.previouslyFocused = document.activeElement;
53
+ this.dialogRef?.focus();
54
+ }
55
+ else if (!this.open && this.wasOpen) {
56
+ this.previouslyFocused?.focus();
57
+ }
58
+ this.wasOpen = this.open;
59
+ }
60
+ render() {
61
+ if (!this.open) {
62
+ return null;
63
+ }
64
+ return (index.h("div", { part: "backdrop", class: "bs-modal__backdrop", onClick: this.onBackdropClick }, index.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 }, index.h("div", { part: "header", class: "bs-modal__header" }, index.h("span", { class: "bs-modal__heading" }, this.heading), index.h("button", { part: "close", class: "bs-modal__close", "aria-label": "Close", onClick: this.close }, "\u00D7")), index.h("div", { part: "body", class: "bs-modal__body" }, index.h("slot", null)), index.h("div", { part: "footer", class: `bs-modal__footer ${this.hasFooter ? 'bs-modal__footer--visible' : ''}` }, index.h("slot", { name: "footer", onSlotchange: this.onFooterSlotchange })))));
65
+ }
66
+ };
67
+ BsModal.style = bsModalCss();
68
+
69
+ exports.bs_modal = BsModal;