@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,7 @@
1
+ 'use strict';
2
+
3
+ function format(first, middle, last) {
4
+ return (first || '') + (middle ? ` ${middle}` : '') + (last ? ` ${last}` : '');
5
+ }
6
+
7
+ exports.format = format;
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var index = require('./index-nyOcuVbF.js');
4
+
5
+ const defineCustomElements = async (win, options) => {
6
+ if (typeof window === 'undefined') return undefined;
7
+ await index.globalScripts();
8
+ return index.bootstrapLazy([["bs-badge.cjs",[[769,"bs-badge",{"variant":[1]}]]],["bs-button.cjs",[[785,"bs-button",{"variant":[1],"size":[1],"disabled":[4],"type":[1],"ariaLabel":[1,"aria-label"],"hasIcon":[32],"hasEndIcon":[32],"hasLabel":[32]}]]],["bs-button-skeleton.cjs",[[513,"bs-button-skeleton",{"size":[1]}]]],["bs-card.cjs",[[769,"bs-card",{"surface":[1]}]]],["bs-composer.cjs",[[529,"bs-composer",{"variant":[1],"placeholder":[1],"value":[1],"state":[1],"ariaLabel":[1,"aria-label"]}]]],["bs-data-table.cjs",[[513,"bs-data-table",{"columns":[16],"rows":[16],"sortColumn":[1,"sort-column"],"sortDirection":[1,"sort-direction"],"selectable":[4],"cellRenderer":[16],"selectedIds":[32]}]]],["bs-input.cjs",[[529,"bs-input",{"value":[1],"type":[1],"label":[1],"placeholder":[1],"description":[1],"error":[1],"disabled":[4]}]]],["bs-modal.cjs",[[769,"bs-modal",{"open":[1540],"heading":[1],"size":[1],"hasFooter":[32]},[[4,"keydown","onKeydown"],[4,"focusin","onFocusIn"]]]]]], options);
9
+ };
10
+
11
+ exports.setNonce = index.setNonce;
12
+ exports.defineCustomElements = defineCustomElements;
@@ -0,0 +1,20 @@
1
+ {
2
+ "entries": [
3
+ "components/bs-badge/bs-badge.js",
4
+ "components/bs-button/bs-button.js",
5
+ "components/bs-card/bs-card.js",
6
+ "components/bs-composer/bs-composer.js",
7
+ "components/bs-data-table/bs-data-table.js",
8
+ "components/bs-modal/bs-modal.js",
9
+ "components/bs-button-skeleton/bs-button-skeleton.js",
10
+ "components/bs-input/bs-input.js"
11
+ ],
12
+ "mixins": [],
13
+ "compiler": {
14
+ "name": "@stencil/core",
15
+ "version": "4.44.0",
16
+ "typescriptVersion": "5.8.3"
17
+ },
18
+ "collections": [],
19
+ "bundles": []
20
+ }
@@ -0,0 +1,30 @@
1
+ import { render, h, describe, it, expect } from "@stencil/vitest";
2
+ describe('bs-badge', () => {
3
+ it('renders the default slot content and default variant class', async () => {
4
+ const { root } = await render(h("bs-badge", null, "Active"));
5
+ expect(root).toHaveTextContent('Active');
6
+ const container = root.shadowRoot.querySelector('.bs-badge');
7
+ expect(container).toHaveClass('bs-badge--default');
8
+ });
9
+ it('exposes the container part on the pill element', async () => {
10
+ const { root } = await render(h("bs-badge", null, "Active"));
11
+ const container = root.shadowRoot.querySelector('.bs-badge');
12
+ expect(container).toEqualAttribute('part', 'container');
13
+ });
14
+ const variants = ['default', 'primary', 'success', 'warning', 'info', 'error', 'neutral', 'inverse'];
15
+ variants.forEach(variant => {
16
+ it(`applies the "${variant}" variant class`, async () => {
17
+ const { root } = await render(h("bs-badge", { variant: variant }, "Status"));
18
+ const container = root.shadowRoot.querySelector('.bs-badge');
19
+ expect(container).toHaveClass(`bs-badge--${variant}`);
20
+ });
21
+ });
22
+ it('reflects a changed variant prop to the internal class', async () => {
23
+ const { root, setProps } = await render(h("bs-badge", { variant: "primary" }, "Status"));
24
+ expect(root.shadowRoot.querySelector('.bs-badge')).toHaveClass('bs-badge--primary');
25
+ await setProps({ variant: 'error' });
26
+ const container = root.shadowRoot.querySelector('.bs-badge');
27
+ expect(container).toHaveClass('bs-badge--error');
28
+ expect(container).not.toHaveClass('bs-badge--primary');
29
+ });
30
+ });
@@ -0,0 +1,55 @@
1
+ :host {
2
+ display: inline-block;
3
+ }
4
+
5
+ .bs-badge {
6
+ display: inline-flex;
7
+ align-items: center;
8
+ height: var(--bs-spacing-400);
9
+ padding: 0 var(--bs-spacing-200);
10
+ border-radius: var(--bs-border-radius-full);
11
+ font-size: var(--bs-font-size-xs);
12
+ font-weight: var(--bs-font-weight-medium);
13
+ font-family: inherit;
14
+ white-space: nowrap;
15
+ }
16
+
17
+ .bs-badge--default {
18
+ background: var(--bs-badge-bg-default);
19
+ color: var(--bs-badge-text-default);
20
+ }
21
+
22
+ .bs-badge--primary {
23
+ background: var(--bs-badge-bg-primary-container);
24
+ color: var(--bs-badge-text-primary);
25
+ }
26
+
27
+ .bs-badge--success {
28
+ background: var(--bs-badge-bg-success-container);
29
+ color: var(--bs-badge-text-success);
30
+ }
31
+
32
+ .bs-badge--warning {
33
+ background: var(--bs-badge-bg-warning-container);
34
+ color: var(--bs-badge-text-warning);
35
+ }
36
+
37
+ .bs-badge--info {
38
+ background: var(--bs-badge-bg-info-container);
39
+ color: var(--bs-badge-text-info);
40
+ }
41
+
42
+ .bs-badge--error {
43
+ background: var(--bs-badge-bg-error-container);
44
+ color: var(--bs-badge-text-error);
45
+ }
46
+
47
+ .bs-badge--neutral {
48
+ background: var(--bs-badge-bg-neutral-container);
49
+ color: var(--bs-badge-text-neutral);
50
+ }
51
+
52
+ .bs-badge--inverse {
53
+ background: var(--bs-badge-bg-inverse);
54
+ color: var(--bs-badge-text-inverse);
55
+ }
@@ -0,0 +1,64 @@
1
+ import { h } from "@stencil/core";
2
+ /**
3
+ * A small status or category pill, usually paired with a label or list item.
4
+ *
5
+ * ## When to use
6
+ * - Communicating a short, fixed status (e.g. "Active", "On leave") or category label.
7
+ *
8
+ * ## When not to use
9
+ * - As an interactive/clickable element — a badge is a label, not a control. Use a button
10
+ * or chip component if it needs to be clickable.
11
+ * - For long text — badges are sized for one or two words.
12
+ *
13
+ * @slot - Default slot: the badge's label text.
14
+ * @part container - The pill element.
15
+ */
16
+ export class BsBadge {
17
+ /** Maps directly to the brandsync-tokens `--bs-badge-bg-*` / `--bs-badge-text-*` sets. */
18
+ variant = 'default';
19
+ render() {
20
+ return (h("span", { key: '9cc06bddba11f57edf97209456e25141a3b80bea', part: "container", class: `bs-badge bs-badge--${this.variant}` }, h("slot", { key: '7c0e4054e99a3dedc94f2a7250075fcb76c115b6' })));
21
+ }
22
+ static get is() { return "bs-badge"; }
23
+ static get encapsulation() { return "shadow"; }
24
+ static get originalStyleUrls() {
25
+ return {
26
+ "$": ["bs-badge.css"]
27
+ };
28
+ }
29
+ static get styleUrls() {
30
+ return {
31
+ "$": ["bs-badge.css"]
32
+ };
33
+ }
34
+ static get properties() {
35
+ return {
36
+ "variant": {
37
+ "type": "string",
38
+ "mutable": false,
39
+ "complexType": {
40
+ "original": "BsBadgeVariant",
41
+ "resolved": "\"default\" | \"error\" | \"info\" | \"inverse\" | \"neutral\" | \"primary\" | \"success\" | \"warning\"",
42
+ "references": {
43
+ "BsBadgeVariant": {
44
+ "location": "local",
45
+ "path": "/Users/vivka/brandsync-web-components/src/components/bs-badge/bs-badge.tsx",
46
+ "id": "src/components/bs-badge/bs-badge.tsx::BsBadgeVariant"
47
+ }
48
+ }
49
+ },
50
+ "required": false,
51
+ "optional": false,
52
+ "docs": {
53
+ "tags": [],
54
+ "text": "Maps directly to the brandsync-tokens `--bs-badge-bg-*` / `--bs-badge-text-*` sets."
55
+ },
56
+ "getter": false,
57
+ "setter": false,
58
+ "reflect": false,
59
+ "attribute": "variant",
60
+ "defaultValue": "'default'"
61
+ }
62
+ };
63
+ }
64
+ }
@@ -0,0 +1,75 @@
1
+ import { html } from "lit";
2
+ import { componentDescription, propDescription } from "../../stories-utils";
3
+ const variants = ['default', 'primary', 'success', 'warning', 'info', 'error', 'neutral', 'inverse'];
4
+ const meta = {
5
+ title: 'Components/bs-badge',
6
+ parameters: { docs: { description: { component: componentDescription('bs-badge') } } },
7
+ render: args => html `<bs-badge variant=${args.variant}>${args.label}</bs-badge>`,
8
+ argTypes: {
9
+ variant: {
10
+ control: 'select',
11
+ options: variants,
12
+ description: propDescription('bs-badge', 'variant'),
13
+ },
14
+ label: { control: 'text', description: 'Slotted label content (not a real attribute -- see the default slot).' },
15
+ },
16
+ args: {
17
+ variant: 'primary',
18
+ label: 'New',
19
+ },
20
+ };
21
+ export default meta;
22
+ export const Primary = {};
23
+ export const DefaultVariant = {
24
+ args: { variant: 'default', label: 'Default' },
25
+ };
26
+ export const Success = {
27
+ args: { variant: 'success', label: 'Active' },
28
+ };
29
+ export const Warning = {
30
+ args: { variant: 'warning', label: 'Pending' },
31
+ };
32
+ export const Info = {
33
+ args: { variant: 'info', label: 'Info' },
34
+ };
35
+ export const Error = {
36
+ args: { variant: 'error', label: 'Failed' },
37
+ };
38
+ export const Neutral = {
39
+ args: { variant: 'neutral', label: 'Archived' },
40
+ };
41
+ export const Inverse = {
42
+ args: { variant: 'inverse', label: 'Inverse' },
43
+ parameters: {
44
+ // Inverse pairs a light label with a dark background -- render it on a dark surface so it's
45
+ // legible in the docs canvas instead of looking like an accessibility bug against the default
46
+ // (light) Storybook canvas background.
47
+ backgrounds: { default: 'dark' },
48
+ },
49
+ };
50
+ export const AllVariants = {
51
+ render: () => html `
52
+ <div style="display:flex; gap:8px; flex-wrap:wrap;">
53
+ <bs-badge variant="default">Default</bs-badge>
54
+ <bs-badge variant="primary">Primary</bs-badge>
55
+ <bs-badge variant="success">Success</bs-badge>
56
+ <bs-badge variant="warning">Warning</bs-badge>
57
+ <bs-badge variant="info">Info</bs-badge>
58
+ <bs-badge variant="error">Error</bs-badge>
59
+ <bs-badge variant="neutral">Neutral</bs-badge>
60
+ <bs-badge variant="inverse">Inverse</bs-badge>
61
+ </div>
62
+ `,
63
+ };
64
+ export const LongText = {
65
+ name: 'Long text (edge case)',
66
+ args: {
67
+ variant: 'primary',
68
+ label: 'This is a much longer status label than a badge is designed to hold',
69
+ },
70
+ render: args => html `
71
+ <div style="max-width: 160px;">
72
+ <bs-badge variant=${args.variant}>${args.label}</bs-badge>
73
+ </div>
74
+ `,
75
+ };
@@ -0,0 +1,81 @@
1
+ import { render, h, describe, it, expect } from "@stencil/vitest";
2
+ describe('bs-button', () => {
3
+ it('renders the default label slot and variant/size classes', async () => {
4
+ const { root } = await render(h("bs-button", null, "Click me"));
5
+ expect(root).toHaveTextContent('Click me');
6
+ const button = root.shadowRoot.querySelector('button');
7
+ expect(button).toHaveClass('bs-button--primary');
8
+ expect(button).toHaveClass('bs-button--md');
9
+ });
10
+ it('applies the disabled attribute to the native button', async () => {
11
+ const { root } = await render(h("bs-button", { disabled: true }, "Click me"));
12
+ const button = root.shadowRoot.querySelector('button');
13
+ expect(button).toHaveAttribute('disabled');
14
+ });
15
+ it('reflects the variant prop to the internal class', async () => {
16
+ const { root, setProps } = await render(h("bs-button", { variant: "neutral" }, "Click me"));
17
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--neutral');
18
+ await setProps({ variant: 'primary' });
19
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--primary');
20
+ });
21
+ it('applies the error variant class and reflects on prop change', async () => {
22
+ const { root, setProps } = await render(h("bs-button", { variant: "error" }, "Delete"));
23
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--error');
24
+ await setProps({ variant: 'primary' });
25
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--primary');
26
+ expect(root.shadowRoot.querySelector('button')).not.toHaveClass('bs-button--error');
27
+ });
28
+ it('applies the subtle variant class', async () => {
29
+ const { root } = await render(h("bs-button", { variant: "subtle" }, "Click me"));
30
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--subtle');
31
+ });
32
+ it('applies the outlined variant class', async () => {
33
+ const { root } = await render(h("bs-button", { variant: "outlined" }, "Click me"));
34
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--outlined');
35
+ });
36
+ it('applies the success variant class and reflects on prop change', async () => {
37
+ const { root, setProps } = await render(h("bs-button", { variant: "success" }, "Approve"));
38
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--success');
39
+ await setProps({ variant: 'primary' });
40
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--primary');
41
+ expect(root.shadowRoot.querySelector('button')).not.toHaveClass('bs-button--success');
42
+ });
43
+ it('applies the warning variant class', async () => {
44
+ const { root } = await render(h("bs-button", { variant: "warning" }, "Proceed anyway"));
45
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--warning');
46
+ });
47
+ it('applies the info variant class', async () => {
48
+ const { root } = await render(h("bs-button", { variant: "info" }, "View details"));
49
+ expect(root.shadowRoot.querySelector('button')).toHaveClass('bs-button--info');
50
+ });
51
+ it('sets aria-label on the inner button from the ariaLabel prop', async () => {
52
+ const { root } = await render(h("bs-button", { ariaLabel: "Delete" }, "Click me"));
53
+ const button = root.shadowRoot.querySelector('button');
54
+ expect(button).toEqualAttribute('aria-label', 'Delete');
55
+ });
56
+ it('applies bs-button--icon-only when the icon slot has content and the default slot does not', async () => {
57
+ const { root } = await render(h("bs-button", { ariaLabel: "Delete" }, h("svg", { slot: "icon", viewBox: "0 0 16 16" })));
58
+ const button = root.shadowRoot.querySelector('button');
59
+ expect(button).toHaveClass('bs-button--icon-only');
60
+ });
61
+ it('does not apply bs-button--icon-only when a label is present alongside the icon', async () => {
62
+ const { root } = await render(h("bs-button", null, h("svg", { slot: "icon", viewBox: "0 0 16 16" }), "Click me"));
63
+ const button = root.shadowRoot.querySelector('button');
64
+ expect(button).not.toHaveClass('bs-button--icon-only');
65
+ });
66
+ it('applies bs-button__end-icon--visible when the end-icon slot has assigned content', async () => {
67
+ const { root } = await render(h("bs-button", null, "Next", h("svg", { slot: "end-icon", viewBox: "0 0 16 16" })));
68
+ const endIcon = root.shadowRoot.querySelector('[part="end-icon"]');
69
+ expect(endIcon).toHaveClass('bs-button__end-icon--visible');
70
+ });
71
+ it('does not apply bs-button__end-icon--visible when the end-icon slot is empty', async () => {
72
+ const { root } = await render(h("bs-button", null, "Next"));
73
+ const endIcon = root.shadowRoot.querySelector('[part="end-icon"]');
74
+ expect(endIcon).not.toHaveClass('bs-button__end-icon--visible');
75
+ });
76
+ it('applies bs-button--icon-only when only the end-icon slot has content and the default slot does not', async () => {
77
+ const { root } = await render(h("bs-button", { ariaLabel: "Next" }, h("svg", { slot: "end-icon", viewBox: "0 0 16 16" })));
78
+ const button = root.shadowRoot.querySelector('button');
79
+ expect(button).toHaveClass('bs-button--icon-only');
80
+ });
81
+ });
@@ -0,0 +1,247 @@
1
+ :host {
2
+ display: inline-block;
3
+ --bs-button-height-sm: var(--bs-spacing-500);
4
+ --bs-button-height-md: var(--bs-spacing-600);
5
+ --bs-button-height-lg: var(--bs-spacing-700);
6
+ --bs-button-radius: var(--bs-border-radius-100);
7
+
8
+ --bs-button-error-default: var(--bs-color-error-default);
9
+ --bs-button-error-hover: var(--bs-color-error-hover);
10
+ --bs-button-error-focus: var(--bs-border-error-focus);
11
+ --bs-button-error-pressed: var(--bs-color-error-pressed);
12
+ --bs-button-error-disabled: var(--bs-surface-action-disabled);
13
+ /* Same situation as error above: subtle/outlined/success/warning/info don't have a pre-built
14
+ * brandsync-tokens --bs-button-<variant>-* component layer either, so alias one locally. */
15
+ --bs-button-success-default: var(--bs-color-success-default);
16
+ --bs-button-success-hover: var(--bs-color-success-hover);
17
+ --bs-button-success-focus: var(--bs-border-success-focus);
18
+ --bs-button-success-pressed: var(--bs-color-success-pressed);
19
+ --bs-button-success-disabled: var(--bs-surface-action-disabled);
20
+ --bs-button-warning-default: var(--bs-color-warning-default);
21
+ --bs-button-warning-hover: var(--bs-color-warning-hover);
22
+ --bs-button-warning-focus: var(--bs-border-warning-focus);
23
+ --bs-button-warning-pressed: var(--bs-color-warning-pressed);
24
+ --bs-button-warning-disabled: var(--bs-surface-action-disabled);
25
+ --bs-button-info-default: var(--bs-color-info-default);
26
+ --bs-button-info-hover: var(--bs-color-info-hover);
27
+ --bs-button-info-focus: var(--bs-border-info-focus);
28
+ --bs-button-info-pressed: var(--bs-color-info-pressed);
29
+ --bs-button-info-disabled: var(--bs-surface-action-disabled);
30
+ --bs-button-subtle-hover: var(--bs-color-neutral-container);
31
+ --bs-button-subtle-pressed: var(--bs-color-neutral-container-pressed);
32
+ --bs-button-subtle-focus: var(--bs-border-primary-focus);
33
+ --bs-button-outlined-border: var(--bs-border-primary);
34
+ --bs-button-outlined-border-hover: var(--bs-border-primary-hover);
35
+ --bs-button-outlined-focus: var(--bs-border-primary-focus);
36
+ --bs-button-outlined-container: var(--bs-color-primary-container);
37
+ }
38
+
39
+ .bs-button {
40
+ display: inline-flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ box-sizing: border-box;
44
+ border: none;
45
+ border-radius: var(--bs-button-radius);
46
+ font-family: inherit;
47
+ font-weight: var(--bs-font-weight-semibold);
48
+ cursor: pointer;
49
+ transition: background-color var(--bs-duration-fast, 120ms) var(--bs-easing-standard, ease);
50
+ }
51
+
52
+ .bs-button:focus-visible {
53
+ outline: 2px solid var(--bs-border-neutral-focus);
54
+ outline-offset: 2px;
55
+ }
56
+
57
+ .bs-button:disabled {
58
+ cursor: not-allowed;
59
+ }
60
+
61
+ .bs-button--sm {
62
+ height: var(--bs-button-height-sm);
63
+ padding: 0 var(--bs-spacing-300);
64
+ font-size: var(--bs-font-size-sm);
65
+ }
66
+
67
+ .bs-button--md {
68
+ height: var(--bs-button-height-md);
69
+ padding: 0 var(--bs-spacing-400);
70
+ font-size: var(--bs-font-size-md);
71
+ }
72
+
73
+ .bs-button--lg {
74
+ height: var(--bs-button-height-lg);
75
+ padding: 0 var(--bs-spacing-500);
76
+ font-size: var(--bs-font-size-lg);
77
+ }
78
+
79
+ .bs-button--primary {
80
+ background: var(--bs-button-primary-default);
81
+ color: var(--bs-text-on-action);
82
+ }
83
+ .bs-button--primary:hover:not(:disabled) {
84
+ background: var(--bs-button-primary-hover);
85
+ }
86
+ .bs-button--primary:active:not(:disabled) {
87
+ background: var(--bs-button-primary-pressed);
88
+ }
89
+ .bs-button--primary:disabled {
90
+ background: var(--bs-button-primary-disabled);
91
+ color: var(--bs-text-on-disabled);
92
+ }
93
+
94
+ .bs-button--neutral {
95
+ background: var(--bs-button-neutral-container);
96
+ color: var(--bs-text-default);
97
+ }
98
+ .bs-button--neutral:hover:not(:disabled) {
99
+ background: var(--bs-button-neutral-hover);
100
+ }
101
+ .bs-button--neutral:active:not(:disabled) {
102
+ background: var(--bs-button-neutral-pressed);
103
+ }
104
+ .bs-button--neutral:disabled {
105
+ background: var(--bs-button-neutral-disabled);
106
+ color: var(--bs-text-on-disabled);
107
+ }
108
+
109
+ .bs-button--error {
110
+ background: var(--bs-button-error-default);
111
+ color: var(--bs-text-on-action);
112
+ }
113
+ .bs-button--error:hover:not(:disabled) {
114
+ background: var(--bs-button-error-hover);
115
+ }
116
+ .bs-button--error:active:not(:disabled) {
117
+ background: var(--bs-button-error-pressed);
118
+ }
119
+ .bs-button--error:disabled {
120
+ background: var(--bs-button-error-disabled);
121
+ color: var(--bs-text-on-disabled);
122
+ }
123
+ .bs-button--error:focus-visible {
124
+ outline-color: var(--bs-button-error-focus);
125
+ }
126
+
127
+ .bs-button--success {
128
+ background: var(--bs-button-success-default);
129
+ color: var(--bs-text-on-action);
130
+ }
131
+ .bs-button--success:hover:not(:disabled) {
132
+ background: var(--bs-button-success-hover);
133
+ }
134
+ .bs-button--success:active:not(:disabled) {
135
+ background: var(--bs-button-success-pressed);
136
+ }
137
+ .bs-button--success:disabled {
138
+ background: var(--bs-button-success-disabled);
139
+ color: var(--bs-text-on-disabled);
140
+ }
141
+ .bs-button--success:focus-visible {
142
+ outline-color: var(--bs-button-success-focus);
143
+ }
144
+
145
+
146
+ .bs-button--warning {
147
+ background: var(--bs-button-warning-default);
148
+ color: var(--bs-text-default);
149
+ }
150
+ .bs-button--warning:hover:not(:disabled) {
151
+ background: var(--bs-button-warning-hover);
152
+ }
153
+ .bs-button--warning:active:not(:disabled) {
154
+ background: var(--bs-button-warning-pressed);
155
+ }
156
+ .bs-button--warning:disabled {
157
+ background: var(--bs-button-warning-disabled);
158
+ color: var(--bs-text-on-disabled);
159
+ }
160
+ .bs-button--warning:focus-visible {
161
+ outline-color: var(--bs-button-warning-focus);
162
+ }
163
+
164
+ .bs-button--info {
165
+ background: var(--bs-button-info-default);
166
+ color: var(--bs-text-on-action);
167
+ }
168
+ .bs-button--info:hover:not(:disabled) {
169
+ background: var(--bs-button-info-hover);
170
+ }
171
+ .bs-button--info:active:not(:disabled) {
172
+ background: var(--bs-button-info-pressed);
173
+ }
174
+ .bs-button--info:disabled {
175
+ background: var(--bs-button-info-disabled);
176
+ color: var(--bs-text-on-disabled);
177
+ }
178
+ .bs-button--info:focus-visible {
179
+ outline-color: var(--bs-button-info-focus);
180
+ }
181
+
182
+ .bs-button--subtle {
183
+ background: transparent;
184
+ color: var(--bs-color-neutral-default);
185
+ }
186
+ .bs-button--subtle:hover:not(:disabled) {
187
+ background: var(--bs-button-subtle-hover);
188
+ }
189
+ .bs-button--subtle:active:not(:disabled) {
190
+ background: var(--bs-button-subtle-pressed);
191
+ }
192
+ .bs-button--subtle:disabled {
193
+ background: transparent;
194
+ color: var(--bs-text-on-disabled);
195
+ }
196
+ .bs-button--subtle:focus-visible {
197
+ outline-color: var(--bs-button-subtle-focus);
198
+ background: var(--bs-button-subtle-hover);
199
+ }
200
+
201
+ .bs-button--outlined {
202
+ background: transparent;
203
+ color: var(--bs-color-primary-default);
204
+ border: 1.5px solid var(--bs-button-outlined-border);
205
+ }
206
+ .bs-button--outlined:hover:not(:disabled) {
207
+ background: var(--bs-button-outlined-container);
208
+ border-color: var(--bs-button-outlined-border-hover);
209
+ }
210
+ .bs-button--outlined:active:not(:disabled) {
211
+ background: var(--bs-button-outlined-container);
212
+ color: var(--bs-color-primary-pressed);
213
+ border-color: var(--bs-button-outlined-border-hover);
214
+ }
215
+ .bs-button--outlined:disabled {
216
+ opacity: var(--bs-opacity-disabled);
217
+ cursor: not-allowed;
218
+ }
219
+ .bs-button--outlined:focus-visible {
220
+ outline-color: var(--bs-button-outlined-focus);
221
+ }
222
+
223
+ .bs-button__icon--visible {
224
+ margin-right: var(--bs-spacing-100);
225
+ }
226
+
227
+ .bs-button__end-icon--visible {
228
+ margin-left: var(--bs-spacing-100);
229
+ }
230
+
231
+ .bs-button__icon ::slotted(*),
232
+ .bs-button__end-icon ::slotted(*) {
233
+ display: block;
234
+ width: 1em;
235
+ height: 1em;
236
+ }
237
+
238
+ .bs-button--icon-only {
239
+ padding: 0;
240
+ aspect-ratio: 1 / 1;
241
+ }
242
+ .bs-button--icon-only .bs-button__icon--visible {
243
+ margin-right: 0;
244
+ }
245
+ .bs-button--icon-only .bs-button__end-icon--visible {
246
+ margin-left: 0;
247
+ }