@waggylabs/yumekit 0.4.1 → 0.4.2-beta.27

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 (33) hide show
  1. package/CHANGELOG.md +23 -10
  2. package/README.md +32 -29
  3. package/dist/components/y-appbar/y-appbar.d.ts +6 -0
  4. package/dist/components/y-appbar/y-appbar.stories.d.ts +7 -2
  5. package/dist/components/y-appbar.js +123 -14
  6. package/dist/components/y-button/y-button.d.ts +10 -1
  7. package/dist/components/y-button/y-button.stories.d.ts +5 -0
  8. package/dist/components/y-button-group/y-button-group.d.ts +13 -0
  9. package/dist/components/y-button-group/y-button-group.stories.d.ts +57 -0
  10. package/dist/components/y-button-group/y-button-group.test.d.ts +1 -0
  11. package/dist/components/y-button-group.js +118 -0
  12. package/dist/components/y-button.js +73 -11
  13. package/dist/components/y-date/y-date.d.ts +69 -53
  14. package/dist/components/y-date/y-date.stories.d.ts +46 -10
  15. package/dist/components/y-date.js +754 -379
  16. package/dist/components/y-datepicker/y-datepicker.d.ts +46 -30
  17. package/dist/components/y-datepicker.js +244 -97
  18. package/dist/components/y-input.js +68 -22
  19. package/dist/components/y-menu.js +25 -2
  20. package/dist/components/y-panel.js +8 -0
  21. package/dist/components/y-panelbar/y-panelbar.stories.d.ts +7 -2
  22. package/dist/components/y-select.js +11 -7
  23. package/dist/components/y-switch/y-switch.d.ts +1 -51
  24. package/dist/components/y-switch.js +123 -54
  25. package/dist/components/y-textarea.js +70 -23
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +1228 -496
  28. package/dist/modules/helpers.d.ts +7 -0
  29. package/dist/modules/helpers.js +29 -0
  30. package/dist/react.d.ts +3 -0
  31. package/dist/yumekit.min.js +1 -1
  32. package/llm.txt +16 -1
  33. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -31,7 +31,20 @@ Delete any empty sections before publishing.
31
31
  <!-- ### Security -->
32
32
  <!-- Vulnerability patches or hardening changes -->
33
33
 
34
- ## [0.4.1] 2026-04-01
34
+ ## [0.4.2] - 2026-04-07
35
+
36
+ ### Added
37
+
38
+ - New `y-button-group` component — wraps `y-button` (and other elements such as `y-input` or `y-select`) into a visually connected toolbar. Automatically removes inner border-radius on middle children and collapses shared borders to avoid double-border artifacts. Supports `orientation` attribute (`"horizontal"` (default) | `"vertical"`). Works with any slotted child that respects the `--component-button-border-radius-outer` CSS custom property.
39
+ - `href`, `target`, and `rel` attributes on `y-button`. When `href` is set the internal element switches from `<button>` to `<a>`, preserving all visual styles and size/color/style-type variants. Disabled state is handled via `aria-disabled` and `pointer-events: none` since `<a>` has no native disabled.
40
+ - `navigate` custom event on `y-appbar`, `y-panel`, and `y-menu`. Fires before any navigation when an item with an `href` / `url` is clicked. The event is cancelable (`e.preventDefault()`) and carries `event.detail.href` — React Router and other SPA routers can intercept it without any framework-specific glue.
41
+ - `history` attribute on `y-appbar` and `y-menu` (already present on `y-panel`). When omitted (default), navigation uses `history.pushState` + a synthetic `popstate` event so all `popstate`-based routers (React Router `BrowserRouter`, Vue Router, etc.) respond automatically. Set `history="false"` to opt back in to full-page `window.location.href` navigation.
42
+
43
+ ### Changed
44
+
45
+ - Added responsive display to `y-date` and `y-datepicker` as well as the ability to set a `native-mobile` property to `y-date` which will allow the input to use the native mobile date and time picker instead of the `y-datepicker`.
46
+
47
+ ## [0.4.1] - 2026-04-01
35
48
 
36
49
  ### Added
37
50
 
@@ -54,7 +67,7 @@ Delete any empty sections before publishing.
54
67
  - `y-icon` removed artifact from accessibility icon
55
68
  - Dark theme files corrected: `--help-background-component` now uses `var(--indigo-dark-0)` instead of `var(--indigo-light-0)`.
56
69
 
57
- ## [0.4.0] 2026-03-29
70
+ ## [0.4.0] - 2026-03-29
58
71
 
59
72
  ### Added
60
73
 
@@ -86,19 +99,19 @@ Delete any empty sections before publishing.
86
99
  - `gripDots(horizontal)` function removed from `src/icons/index.js`.
87
100
  - Stale `--base-background-border` and `--error-background-border` variable references cleaned up across all theme files (renamed to `--base-border` / `--error-border` in 0.3.9).
88
101
 
89
- ## [0.3.10] 2026-03-25
102
+ ## [0.3.10] - 2026-03-25
90
103
 
91
104
  ### Added
92
105
 
93
106
  - `y-card`: added `image` slot that displays over the `header` slot if included.
94
107
 
95
- ## [0.3.9] 2026-03-25
108
+ ## [0.3.9] - 2026-03-25
96
109
 
97
110
  ### Fixed
98
111
 
99
112
  - `y-card`, `y-switch`, `y-slider`, `y-progress`: restored missing borders after theme variable rename in 0.3.8 changed `--{scheme}-background-border` to `--{scheme}-border` without updating component references.
100
113
 
101
- ## [0.3.8] 2026-03-25
114
+ ## [0.3.8] - 2026-03-25
102
115
 
103
116
  ### Fixed
104
117
 
@@ -106,7 +119,7 @@ Delete any empty sections before publishing.
106
119
 
107
120
  - `y-tag`: reverted earlier change adding variables to tag backgrounds. Defaults to -background-app variables
108
121
 
109
- ## [0.3.6] 2026-03-23
122
+ ## [0.3.6] - 2026-03-23
110
123
 
111
124
  ### Added
112
125
 
@@ -128,25 +141,25 @@ Delete any empty sections before publishing.
128
141
 
129
142
  - Removed `features` icon (duplicate of `sun`)
130
143
 
131
- ## [0.3.5] 2026-03-20
144
+ ## [0.3.5] - 2026-03-20
132
145
 
133
146
  ### Fixed
134
147
 
135
148
  - Patch for 0.3.3 with bug fixes
136
149
 
137
- ## [0.3.4] 2026-03-20
150
+ ## [0.3.4] - 2026-03-20
138
151
 
139
152
  ### Fixed
140
153
 
141
154
  - Patch for 0.3.3 with bug fixes
142
155
 
143
- ## [0.3.3] 2026-03-20
156
+ ## [0.3.3] - 2026-03-20
144
157
 
145
158
  ### Fixed
146
159
 
147
160
  - Several bug fixes and test updates
148
161
 
149
- ## [0.3.2] 2026-03-18
162
+ ## [0.3.2] - 2026-03-18
150
163
 
151
164
  ### Added
152
165
 
package/README.md CHANGED
@@ -17,7 +17,7 @@
17
17
 
18
18
  ## Overview
19
19
 
20
- YumeKit is a collection of 26 production-ready custom elements built with native Web Components. It works with any framework — or none at all — and ships with a comprehensive design token system, built-in theming, an icon registry, and full TypeScript support.
20
+ YumeKit is a collection of 27 production-ready custom elements built with native Web Components. It works with any framework — or none at all — and ships with a comprehensive design token system, built-in theming, an icon registry, and full TypeScript support.
21
21
 
22
22
  - **Zero dependencies** — built entirely on web standards
23
23
  - **Framework-agnostic** — works with React, Vue, Svelte, or plain HTML
@@ -73,34 +73,37 @@ Then use the `<y-theme>` component to apply a theme:
73
73
 
74
74
  ## Components
75
75
 
76
- | Component | Element | Description |
77
- | --------- | -------------- | ------------------------------------------ |
78
- | App Bar | `<y-appbar>` | Top or side navigation bar |
79
- | Avatar | `<y-avatar>` | User avatar with shape and color variants |
80
- | Badge | `<y-badge>` | Status badge or label |
81
- | Button | `<y-button>` | Button with icon, size, and style variants |
82
- | Card | `<y-card>` | Content card container |
83
- | Checkbox | `<y-checkbox>` | Form checkbox input |
84
- | Dialog | `<y-dialog>` | Modal dialog |
85
- | Drawer | `<y-drawer>` | Side drawer / sidebar |
86
- | Icon | `<y-icon>` | SVG icon display |
87
- | Input | `<y-input>` | Text input field |
88
- | Menu | `<y-menu>` | Dropdown navigation menu |
89
- | Panel | `<y-panel>` | Accordion panel |
90
- | Panel Bar | `<y-panelbar>` | Accordion panel group |
91
- | Progress | `<y-progress>` | Progress bar |
92
- | Radio | `<y-radio>` | Radio button input |
93
- | Rating | `<y-rating>` | Star / icon rating input |
94
- | Select | `<y-select>` | Select / dropdown input |
95
- | Slider | `<y-slider>` | Range slider input |
96
- | Switch | `<y-switch>` | Toggle switch |
97
- | Table | `<y-table>` | Sortable data table |
98
- | Textarea | `<y-textarea>` | Multi-line text input |
99
- | Tabs | `<y-tabs>` | Tabbed interface |
100
- | Tag | `<y-tag>` | Tag / chip label |
101
- | Theme | `<y-theme>` | Theme provider |
102
- | Toast | `<y-toast>` | Notification toast |
103
- | Tooltip | `<y-tooltip>` | Tooltip / popover |
76
+ | Component | Element | Description |
77
+ | ------------ | ------------------ | --------------------------------------------------- |
78
+ | App Bar | `<y-appbar>` | Top or side navigation bar |
79
+ | Avatar | `<y-avatar>` | User avatar with shape and color variants |
80
+ | Badge | `<y-badge>` | Status badge or label |
81
+ | Button | `<y-button>` | Button with icon, size, and style variants |
82
+ | Button Group | `<y-button-group>` | Groups buttons (or inputs) into a connected toolbar |
83
+ | Card | `<y-card>` | Content card container |
84
+ | Checkbox | `<y-checkbox>` | Form checkbox input |
85
+ | Date | `<y-date>` | Date input |
86
+ | DatePicker | `<y-datepicker>` | A date and time picker |
87
+ | Dialog | `<y-dialog>` | Modal dialog |
88
+ | Drawer | `<y-drawer>` | Side drawer / sidebar |
89
+ | Icon | `<y-icon>` | SVG icon display |
90
+ | Input | `<y-input>` | Text input field |
91
+ | Menu | `<y-menu>` | Dropdown navigation menu |
92
+ | Panel | `<y-panel>` | Accordion panel |
93
+ | Panel Bar | `<y-panelbar>` | Accordion panel group |
94
+ | Progress | `<y-progress>` | Progress bar |
95
+ | Radio | `<y-radio>` | Radio button input |
96
+ | Rating | `<y-rating>` | Star / icon rating input |
97
+ | Select | `<y-select>` | Select / dropdown input |
98
+ | Slider | `<y-slider>` | Range slider input |
99
+ | Switch | `<y-switch>` | Toggle switch |
100
+ | Table | `<y-table>` | Sortable data table |
101
+ | Textarea | `<y-textarea>` | Multi-line text input |
102
+ | Tabs | `<y-tabs>` | Tabbed interface |
103
+ | Tag | `<y-tag>` | Tag / chip label |
104
+ | Theme | `<y-theme>` | Theme provider |
105
+ | Toast | `<y-toast>` | Notification toast |
106
+ | Tooltip | `<y-tooltip>` | Tooltip / popover |
104
107
 
105
108
  ---
106
109
 
@@ -34,6 +34,12 @@ export class YumeAppbar extends HTMLElement {
34
34
  set size(val: string);
35
35
  /** Size variant: "small" | "medium" | "large" (default "medium"). */
36
36
  get size(): string;
37
+ set history(val: string);
38
+ /**
39
+ * Navigation mode: omit for pushState (SPA-friendly), set to "false" for full-page navigation.
40
+ * Regardless of this setting, a cancelable "navigate" event is always dispatched first.
41
+ */
42
+ get history(): string;
37
43
  set sticky(val: string | false);
38
44
  /** Sticky position: "start" | "end" | false. */
39
45
  get sticky(): string | false;
@@ -79,7 +79,12 @@ export namespace Sizes {
79
79
  export function render_2(): string;
80
80
  export { render_2 as render };
81
81
  }
82
- export namespace WithFooter {
83
- export function render_3(): string;
82
+ export namespace NavigateEvent {
83
+ export let name: string;
84
+ export function render_3(): HTMLDivElement;
84
85
  export { render_3 as render };
85
86
  }
87
+ export namespace WithFooter {
88
+ export function render_4(): string;
89
+ export { render_4 as render };
90
+ }
@@ -8,6 +8,7 @@ class YumeButton extends HTMLElement {
8
8
  "disabled", "name", "value", "autofocus", "form", "formaction",
9
9
  "formenctype", "formmethod", "formnovalidate", "formtarget",
10
10
  "aria-label", "aria-pressed", "aria-hidden",
11
+ "href", "target", "rel",
11
12
  ];
12
13
  }
13
14
 
@@ -49,6 +50,27 @@ class YumeButton extends HTMLElement {
49
50
  // Getters / Setters
50
51
  // -------------------------------------------------------------------------
51
52
 
53
+ /** URL to navigate to. When set, the internal element renders as an <a> instead of <button>. */
54
+ get href() { return this.getAttribute("href"); }
55
+ set href(val) {
56
+ if (val != null) this.setAttribute("href", val);
57
+ else this.removeAttribute("href");
58
+ }
59
+
60
+ /** Anchor target (e.g. "_blank"). Only applies when href is set. */
61
+ get target() { return this.getAttribute("target"); }
62
+ set target(val) {
63
+ if (val != null) this.setAttribute("target", val);
64
+ else this.removeAttribute("target");
65
+ }
66
+
67
+ /** Anchor rel attribute (e.g. "noopener noreferrer"). Only applies when href is set. */
68
+ get rel() { return this.getAttribute("rel"); }
69
+ set rel(val) {
70
+ if (val != null) this.setAttribute("rel", val);
71
+ else this.removeAttribute("rel");
72
+ }
73
+
52
74
  /** Color theme for the button (default "base"). */
53
75
  get color() { return this.getAttribute("color") || "base"; }
54
76
  set color(val) { this.setAttribute("color", val); }
@@ -287,9 +309,15 @@ class YumeButton extends HTMLElement {
287
309
  line-height: 1;
288
310
  }
289
311
 
290
- .button:disabled {
312
+ .button {
313
+ text-decoration: none;
314
+ }
315
+
316
+ .button:disabled,
317
+ .button[aria-disabled="true"] {
291
318
  opacity: 0.5;
292
319
  cursor: not-allowed;
320
+ pointer-events: none;
293
321
  }
294
322
 
295
323
  .button:hover:not(:disabled),
@@ -419,23 +447,49 @@ class YumeButton extends HTMLElement {
419
447
  }
420
448
 
421
449
  _render() {
450
+ const needsAnchor = this.hasAttribute("href");
451
+ const isAnchor = this.button?.tagName === "A";
452
+
453
+ if (this.button && needsAnchor !== isAnchor) {
454
+ this.button.remove();
455
+ this.button = null;
456
+ }
457
+
422
458
  if (!this.button) {
423
- this.button = document.createElement("button");
459
+ this.button = needsAnchor
460
+ ? document.createElement("a")
461
+ : document.createElement("button");
424
462
  this.button.classList.add("button");
425
- this.button.setAttribute("role", "button");
426
- this.button.setAttribute("tabindex", "0");
427
463
  this.button.setAttribute("part", "button");
464
+ if (!needsAnchor) {
465
+ this.button.setAttribute("role", "button");
466
+ this.button.setAttribute("tabindex", "0");
467
+ }
428
468
  this.shadowRoot.appendChild(this.button);
429
469
  }
430
470
 
431
471
  this._updateButtonAttributes();
432
472
 
433
- if (this.hasAttribute("disabled")) {
434
- this.button.setAttribute("disabled", "");
435
- this.button.setAttribute("aria-disabled", "true");
473
+ const disabled = this.hasAttribute("disabled");
474
+ if (needsAnchor) {
475
+ // <a> has no native disabled — manage via aria and href removal
476
+ if (disabled) {
477
+ this.button.removeAttribute("href");
478
+ this.button.setAttribute("aria-disabled", "true");
479
+ this.button.setAttribute("tabindex", "-1");
480
+ } else {
481
+ this.button.setAttribute("href", this.getAttribute("href"));
482
+ this.button.setAttribute("aria-disabled", "false");
483
+ this.button.removeAttribute("tabindex");
484
+ }
436
485
  } else {
437
- this.button.removeAttribute("disabled");
438
- this.button.setAttribute("aria-disabled", "false");
486
+ if (disabled) {
487
+ this.button.setAttribute("disabled", "");
488
+ this.button.setAttribute("aria-disabled", "true");
489
+ } else {
490
+ this.button.removeAttribute("disabled");
491
+ this.button.setAttribute("aria-disabled", "false");
492
+ }
439
493
  }
440
494
 
441
495
  this.button.innerHTML = `
@@ -450,9 +504,17 @@ class YumeButton extends HTMLElement {
450
504
  }
451
505
 
452
506
  _updateButtonAttributes() {
453
- const attributes = YumeButton.observedAttributes;
507
+ const isAnchor = this.button?.tagName === "A";
508
+ // These are only meaningful on <button>
509
+ const buttonOnlyAttrs = new Set(["type", "disabled", "name", "value", "autofocus", "form", "formaction", "formenctype", "formmethod", "formnovalidate", "formtarget"]);
510
+ // These are only meaningful on <a>; href is managed separately in _render
511
+ const anchorOnlyAttrs = new Set(["href", "target", "rel"]);
512
+
513
+ YumeButton.observedAttributes.forEach((attr) => {
514
+ if (isAnchor && buttonOnlyAttrs.has(attr)) return;
515
+ if (isAnchor && attr === "href") return; // handled in _render (disabled-aware)
516
+ if (!isAnchor && anchorOnlyAttrs.has(attr)) return;
454
517
 
455
- attributes.forEach((attr) => {
456
518
  if (this.hasAttribute(attr)) {
457
519
  this.button.setAttribute(attr, this.getAttribute(attr));
458
520
  } else {
@@ -732,7 +794,7 @@ var menu = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill
732
794
 
733
795
  class YumeMenu extends HTMLElement {
734
796
  static get observedAttributes() {
735
- return ["items", "anchor", "visible", "direction", "size"];
797
+ return ["items", "anchor", "visible", "direction", "size", "history"];
736
798
  }
737
799
 
738
800
  // -------------------------------------------------------------------------
@@ -810,6 +872,16 @@ class YumeMenu extends HTMLElement {
810
872
  this.setAttribute("items", Array.isArray(val) ? JSON.stringify(val) : (val ?? "[]"));
811
873
  }
812
874
 
875
+ /**
876
+ * Navigation mode: omit for pushState (SPA-friendly), set to "false" for full-page navigation.
877
+ * Regardless of this setting, a cancelable "navigate" event is always dispatched first.
878
+ */
879
+ get history() { return this.getAttribute("history"); }
880
+ set history(val) {
881
+ if (val != null) this.setAttribute("history", val);
882
+ else this.removeAttribute("history");
883
+ }
884
+
813
885
  /** Size: "small" | "medium" | "large" (default "medium"). */
814
886
  get size() {
815
887
  const sz = this.getAttribute("size");
@@ -962,7 +1034,20 @@ class YumeMenu extends HTMLElement {
962
1034
 
963
1035
  if (item.url) {
964
1036
  li.addEventListener("click", () => {
965
- window.location.href = item.url;
1037
+ const event = new CustomEvent("navigate", {
1038
+ bubbles: true,
1039
+ composed: true,
1040
+ cancelable: true,
1041
+ detail: { href: item.url },
1042
+ });
1043
+ const cancelled = !this.dispatchEvent(event);
1044
+ if (cancelled) return;
1045
+ if (this.getAttribute("history") !== "false") {
1046
+ history.pushState({}, "", item.url);
1047
+ window.dispatchEvent(new PopStateEvent("popstate", { state: {} }));
1048
+ } else {
1049
+ window.location.href = item.url;
1050
+ }
966
1051
  });
967
1052
  }
968
1053
 
@@ -1143,6 +1228,7 @@ class YumeAppbar extends HTMLElement {
1143
1228
  "menu-direction",
1144
1229
  "sticky",
1145
1230
  "mobile-breakpoint",
1231
+ "history",
1146
1232
  ];
1147
1233
  }
1148
1234
 
@@ -1229,6 +1315,16 @@ class YumeAppbar extends HTMLElement {
1229
1315
  get size() { return this.getAttribute("size") || "medium"; }
1230
1316
  set size(val) { this.setAttribute("size", val); }
1231
1317
 
1318
+ /**
1319
+ * Navigation mode: omit for pushState (SPA-friendly), set to "false" for full-page navigation.
1320
+ * Regardless of this setting, a cancelable "navigate" event is always dispatched first.
1321
+ */
1322
+ get history() { return this.getAttribute("history"); }
1323
+ set history(val) {
1324
+ if (val != null) this.setAttribute("history", val);
1325
+ else this.removeAttribute("history");
1326
+ }
1327
+
1232
1328
  /** Sticky position: "start" | "end" | false. */
1233
1329
  get sticky() {
1234
1330
  const val = this.getAttribute("sticky");
@@ -1346,7 +1442,20 @@ class YumeAppbar extends HTMLElement {
1346
1442
 
1347
1443
  if (item.href && !hasChildren) {
1348
1444
  btn.addEventListener("click", () => {
1349
- window.location.href = item.href;
1445
+ const event = new CustomEvent("navigate", {
1446
+ bubbles: true,
1447
+ composed: true,
1448
+ cancelable: true,
1449
+ detail: { href: item.href },
1450
+ });
1451
+ const cancelled = !this.dispatchEvent(event);
1452
+ if (cancelled) return;
1453
+ if (this.getAttribute("history") !== "false") {
1454
+ history.pushState({}, "", item.href);
1455
+ window.dispatchEvent(new PopStateEvent("popstate", { state: {} }));
1456
+ } else {
1457
+ window.location.href = item.href;
1458
+ }
1350
1459
  });
1351
1460
  }
1352
1461
 
@@ -3,6 +3,15 @@ export class YumeButton extends HTMLElement {
3
3
  selectedValues: Set<any>;
4
4
  connectedCallback(): void;
5
5
  attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
6
+ set href(val: string);
7
+ /** URL to navigate to. When set, the internal element renders as an <a> instead of <button>. */
8
+ get href(): string;
9
+ set target(val: string);
10
+ /** Anchor target (e.g. "_blank"). Only applies when href is set. */
11
+ get target(): string;
12
+ set rel(val: string);
13
+ /** Anchor rel attribute (e.g. "noopener noreferrer"). Only applies when href is set. */
14
+ get rel(): string;
6
15
  set color(val: string);
7
16
  /** Color theme for the button (default "base"). */
8
17
  get color(): string;
@@ -50,7 +59,7 @@ export class YumeButton extends HTMLElement {
50
59
  _manageSlotVisibility(slotName: any, selector: any): void;
51
60
  _proxyNativeOnClick(): void;
52
61
  _render(): void;
53
- button: HTMLButtonElement;
62
+ button: any;
54
63
  _updateButtonAttributes(): void;
55
64
  _updateStyles(): void;
56
65
  }
@@ -129,3 +129,8 @@ export namespace Disabled {
129
129
  }
130
130
  export { args_1 as args };
131
131
  }
132
+ export namespace AsLink {
133
+ export let name: string;
134
+ export function render_5(): string;
135
+ export { render_5 as render };
136
+ }
@@ -0,0 +1,13 @@
1
+ export class YumeButtonGroup extends HTMLElement {
2
+ static get observedAttributes(): string[];
3
+ connectedCallback(): void;
4
+ attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
5
+ set orientation(val: string);
6
+ /** Layout direction: "horizontal" | "vertical" (default "horizontal"). */
7
+ get orientation(): string;
8
+ _applyStyles(): void;
9
+ _styleEl: HTMLStyleElement;
10
+ _getRadius(): string;
11
+ _render(): void;
12
+ _updateChildren(): void;
13
+ }
@@ -0,0 +1,57 @@
1
+ declare namespace _default {
2
+ let title: string;
3
+ let tags: string[];
4
+ namespace argTypes {
5
+ namespace orientation {
6
+ let control: string;
7
+ let options: string[];
8
+ let description: string;
9
+ namespace table {
10
+ namespace defaultValue {
11
+ let summary: string;
12
+ }
13
+ }
14
+ }
15
+ }
16
+ namespace args {
17
+ let orientation_1: string;
18
+ export { orientation_1 as orientation };
19
+ }
20
+ function render({ orientation }: {
21
+ orientation: any;
22
+ }): string;
23
+ }
24
+ export default _default;
25
+ export const Default: {};
26
+ export namespace StyleTypes {
27
+ export function render_1(): string;
28
+ export { render_1 as render };
29
+ }
30
+ export namespace Colors {
31
+ export function render_2(): string;
32
+ export { render_2 as render };
33
+ }
34
+ export namespace Sizes {
35
+ export function render_3(): string;
36
+ export { render_3 as render };
37
+ }
38
+ export namespace Vertical {
39
+ export function render_4(): string;
40
+ export { render_4 as render };
41
+ }
42
+ export namespace WithIcons {
43
+ export function render_5(): string;
44
+ export { render_5 as render };
45
+ }
46
+ export namespace SingleItem {
47
+ export function render_6(): string;
48
+ export { render_6 as render };
49
+ }
50
+ export namespace InputAndButton {
51
+ export function render_7(): string;
52
+ export { render_7 as render };
53
+ }
54
+ export namespace MixedContent {
55
+ export function render_8(): string;
56
+ export { render_8 as render };
57
+ }
@@ -0,0 +1,118 @@
1
+ class YumeButtonGroup extends HTMLElement {
2
+ static get observedAttributes() {
3
+ return ["orientation"];
4
+ }
5
+
6
+ // -------------------------------------------------------------------------
7
+ // Lifecycle
8
+ // -------------------------------------------------------------------------
9
+
10
+ constructor() {
11
+ super();
12
+ this.attachShadow({ mode: "open" });
13
+ }
14
+
15
+ connectedCallback() {
16
+ this._render();
17
+ this._updateChildren();
18
+ }
19
+
20
+ attributeChangedCallback(name, oldValue, newValue) {
21
+ if (oldValue !== newValue) {
22
+ this._applyStyles();
23
+ this._updateChildren();
24
+ }
25
+ }
26
+
27
+ // -------------------------------------------------------------------------
28
+ // Getters / Setters
29
+ // -------------------------------------------------------------------------
30
+
31
+ /** Layout direction: "horizontal" | "vertical" (default "horizontal"). */
32
+ get orientation() { return this.getAttribute("orientation") || "horizontal"; }
33
+ set orientation(val) { this.setAttribute("orientation", val); }
34
+
35
+ // -------------------------------------------------------------------------
36
+ // Private
37
+ // -------------------------------------------------------------------------
38
+
39
+ _applyStyles() {
40
+ if (!this._styleEl) {
41
+ this._styleEl = document.createElement("style");
42
+ this.shadowRoot.appendChild(this._styleEl);
43
+ }
44
+ const isVertical = this.orientation === "vertical";
45
+ this._styleEl.textContent = `
46
+ :host {
47
+ display: inline-flex;
48
+ flex-direction: ${isVertical ? "column" : "row"};
49
+ align-items: stretch;
50
+ }
51
+ ::slotted(*) {
52
+ flex-shrink: 0;
53
+ position: relative;
54
+ }
55
+ `;
56
+ }
57
+
58
+ _getRadius() {
59
+ const val = getComputedStyle(this).getPropertyValue("--component-button-border-radius-outer").trim();
60
+ return val || "4px";
61
+ }
62
+
63
+ _render() {
64
+ this._applyStyles();
65
+ if (!this.shadowRoot.querySelector("slot")) {
66
+ const slot = document.createElement("slot");
67
+ slot.addEventListener("slotchange", () => this._updateChildren());
68
+ this.shadowRoot.appendChild(slot);
69
+ }
70
+ }
71
+
72
+ _updateChildren() {
73
+ const slot = this.shadowRoot.querySelector("slot");
74
+ if (!slot) return;
75
+
76
+ const children = slot.assignedElements({ flatten: true });
77
+ const isVertical = this.orientation === "vertical";
78
+ const radius = this._getRadius();
79
+ const total = children.length;
80
+
81
+ children.forEach((child, index) => {
82
+ const isFirst = index === 0;
83
+ const isLast = index === total - 1;
84
+
85
+ // Collapse the shared border between adjacent items
86
+ if (isVertical) {
87
+ child.style.marginLeft = "";
88
+ child.style.marginTop = isFirst ? "" : "-1px";
89
+ } else {
90
+ child.style.marginTop = "";
91
+ child.style.marginLeft = isFirst ? "" : "-1px";
92
+ }
93
+
94
+ // Override border-radius on all child types via their respective CSS custom properties
95
+ if (total === 1) {
96
+ child.style.removeProperty("--component-button-border-radius-outer");
97
+ child.style.removeProperty("--component-inputs-border-radius-outer");
98
+ } else if (isFirst) {
99
+ const value = isVertical ? `${radius} ${radius} 0 0` : `${radius} 0 0 ${radius}`;
100
+ child.style.setProperty("--component-button-border-radius-outer", value);
101
+ child.style.setProperty("--component-inputs-border-radius-outer", value);
102
+ } else if (isLast) {
103
+ const value = isVertical ? `0 0 ${radius} ${radius}` : `0 ${radius} ${radius} 0`;
104
+ child.style.setProperty("--component-button-border-radius-outer", value);
105
+ child.style.setProperty("--component-inputs-border-radius-outer", value);
106
+ } else {
107
+ child.style.setProperty("--component-button-border-radius-outer", "0");
108
+ child.style.setProperty("--component-inputs-border-radius-outer", "0");
109
+ }
110
+ });
111
+ }
112
+ }
113
+
114
+ if (!customElements.get("y-button-group")) {
115
+ customElements.define("y-button-group", YumeButtonGroup);
116
+ }
117
+
118
+ export { YumeButtonGroup };