@haiyue/ui 0.1.2 → 0.2.2

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 (110) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +27 -0
  3. package/README.md +643 -2
  4. package/dist/adapters/web/controls.d.ts +19 -0
  5. package/dist/adapters/web/controls.js +307 -0
  6. package/dist/adapters/web/dom.d.ts +10 -0
  7. package/dist/adapters/web/dom.js +98 -0
  8. package/dist/adapters/web/index.d.ts +3 -0
  9. package/dist/adapters/web/index.js +3 -0
  10. package/dist/adapters/web/renderer.d.ts +18 -0
  11. package/dist/adapters/web/renderer.js +553 -0
  12. package/dist/adapters/web/styles.d.ts +3 -0
  13. package/dist/adapters/web/styles.js +83 -0
  14. package/dist/adapters/web/types.d.ts +46 -0
  15. package/dist/adapters/web/types.js +2 -0
  16. package/dist/affix.d.ts +35 -0
  17. package/dist/affix.js +137 -0
  18. package/dist/badge.d.ts +45 -0
  19. package/dist/badge.js +168 -0
  20. package/dist/breadcrumb.d.ts +37 -0
  21. package/dist/breadcrumb.js +210 -0
  22. package/dist/button-group.d.ts +12 -0
  23. package/dist/button-group.js +72 -0
  24. package/dist/button.d.ts +15 -1
  25. package/dist/button.js +101 -12
  26. package/dist/carousel.d.ts +92 -0
  27. package/dist/carousel.js +509 -0
  28. package/dist/cascader.d.ts +65 -0
  29. package/dist/cascader.js +479 -0
  30. package/dist/collapse.d.ts +68 -0
  31. package/dist/collapse.js +348 -0
  32. package/dist/core/actions.d.ts +32 -0
  33. package/dist/core/actions.js +145 -0
  34. package/dist/core/data.d.ts +4 -0
  35. package/dist/core/data.js +27 -0
  36. package/dist/core/index.d.ts +7 -0
  37. package/dist/core/index.js +6 -0
  38. package/dist/core/platform-view.d.ts +17 -0
  39. package/dist/core/platform-view.js +84 -0
  40. package/dist/core/selection.d.ts +14 -0
  41. package/dist/core/selection.js +93 -0
  42. package/dist/core/text.d.ts +31 -0
  43. package/dist/core/text.js +154 -0
  44. package/dist/core/types.d.ts +269 -0
  45. package/dist/core/types.js +2 -0
  46. package/dist/core/validation.d.ts +24 -0
  47. package/dist/core/validation.js +243 -0
  48. package/dist/date-picker.d.ts +60 -0
  49. package/dist/date-picker.js +355 -0
  50. package/dist/dialog.d.ts +4 -0
  51. package/dist/dialog.js +23 -5
  52. package/dist/divider.d.ts +33 -0
  53. package/dist/divider.js +113 -0
  54. package/dist/draggable.d.ts +78 -0
  55. package/dist/draggable.js +255 -0
  56. package/dist/index.d.ts +53 -1
  57. package/dist/index.js +78 -0
  58. package/dist/input.d.ts +30 -1
  59. package/dist/input.js +166 -54
  60. package/dist/internal/qrcodegen.d.ts +94 -0
  61. package/dist/internal/qrcodegen.js +856 -0
  62. package/dist/masonry.d.ts +36 -0
  63. package/dist/masonry.js +171 -0
  64. package/dist/modal.d.ts +73 -0
  65. package/dist/modal.js +361 -0
  66. package/dist/portable/icons.d.ts +5 -0
  67. package/dist/portable/icons.js +24 -0
  68. package/dist/portable/index.d.ts +7 -0
  69. package/dist/portable/index.js +5 -0
  70. package/dist/portable/page.d.ts +38 -0
  71. package/dist/portable/page.js +361 -0
  72. package/dist/portable/responsive.d.ts +20 -0
  73. package/dist/portable/responsive.js +15 -0
  74. package/dist/portable/theme.d.ts +24 -0
  75. package/dist/portable/theme.js +60 -0
  76. package/dist/portable/tree.d.ts +10 -0
  77. package/dist/portable/tree.js +96 -0
  78. package/dist/qr-code.d.ts +62 -0
  79. package/dist/qr-code.js +224 -0
  80. package/dist/range.d.ts +3 -0
  81. package/dist/range.js +16 -5
  82. package/dist/rate.d.ts +46 -0
  83. package/dist/rate.js +193 -0
  84. package/dist/resizable.d.ts +97 -0
  85. package/dist/resizable.js +426 -0
  86. package/dist/skeleton.d.ts +41 -0
  87. package/dist/skeleton.js +141 -0
  88. package/dist/steps.d.ts +45 -0
  89. package/dist/steps.js +203 -0
  90. package/dist/table.d.ts +106 -0
  91. package/dist/table.js +689 -0
  92. package/dist/tabs.d.ts +3 -0
  93. package/dist/tabs.js +11 -1
  94. package/dist/tag.d.ts +55 -0
  95. package/dist/tag.js +225 -0
  96. package/dist/time-picker.d.ts +62 -0
  97. package/dist/time-picker.js +298 -0
  98. package/dist/timeline.d.ts +48 -0
  99. package/dist/timeline.js +201 -0
  100. package/dist/toast.d.ts +55 -0
  101. package/dist/toast.js +224 -0
  102. package/dist/tour.d.ts +89 -0
  103. package/dist/tour.js +306 -0
  104. package/dist/virtual-keyboard.d.ts +95 -0
  105. package/dist/virtual-keyboard.js +432 -0
  106. package/dist/virtual-mouse.d.ts +82 -0
  107. package/dist/virtual-mouse.js +358 -0
  108. package/dist/watermark.d.ts +44 -0
  109. package/dist/watermark.js +148 -0
  110. package/package.json +132 -4
@@ -0,0 +1,210 @@
1
+ function itemTitle(item) {
2
+ return String(item.title ?? item.label ?? '');
3
+ }
4
+ /** Accessible breadcrumb navigation with links, actions, and a configurable separator. */
5
+ export class HYBreadcrumb extends HTMLElement {
6
+ _nav = document.createElement('nav');
7
+ _list = document.createElement('ol');
8
+ _items = [];
9
+ _renderItem = null;
10
+ static get observedAttributes() {
11
+ return ['items', 'separator', 'aria-label'];
12
+ }
13
+ constructor() {
14
+ super();
15
+ const root = this.attachShadow({ mode: 'open' });
16
+ const style = document.createElement('style');
17
+ style.textContent = `
18
+ :host {
19
+ display: block;
20
+ min-width: 0;
21
+ color: var(--hy-secondary-text-color, #aebbd0);
22
+ font: 12px/1.4 system-ui, sans-serif;
23
+ }
24
+ nav { min-width: 0; }
25
+ ol {
26
+ display: flex;
27
+ align-items: center;
28
+ min-width: 0;
29
+ margin: 0;
30
+ padding: 0;
31
+ overflow-x: auto;
32
+ overflow-y: hidden;
33
+ list-style: none;
34
+ scrollbar-width: none;
35
+ }
36
+ ol::-webkit-scrollbar { display: none; }
37
+ li {
38
+ display: inline-flex;
39
+ flex: 0 0 auto;
40
+ align-items: center;
41
+ min-width: 0;
42
+ }
43
+ a, button, .current, .disabled {
44
+ display: inline-flex;
45
+ align-items: center;
46
+ min-width: 0;
47
+ max-width: var(--hy-breadcrumb-item-max-width, 240px);
48
+ box-sizing: border-box;
49
+ padding: var(--hy-breadcrumb-item-padding, 3px 5px);
50
+ overflow: hidden;
51
+ border: 0;
52
+ border-radius: var(--hy-breadcrumb-radius, 4px);
53
+ color: inherit;
54
+ background: transparent;
55
+ font: inherit;
56
+ text-decoration: none;
57
+ text-overflow: ellipsis;
58
+ white-space: nowrap;
59
+ }
60
+ a, button { cursor: pointer; }
61
+ a:hover, button:hover {
62
+ color: var(--hy-text-color, #eef3ff);
63
+ background: var(--hy-hover-bg-color, #273241);
64
+ }
65
+ a:focus-visible, button:focus-visible {
66
+ outline: 2px solid var(--hy-focus-border-color, #79a8ff);
67
+ outline-offset: 1px;
68
+ }
69
+ .current {
70
+ color: var(--hy-text-color, #eef3ff);
71
+ font-weight: 600;
72
+ }
73
+ .disabled { color: var(--hy-disabled-text-color, #657185); cursor: not-allowed; }
74
+ .separator {
75
+ display: inline-flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ min-width: 14px;
79
+ padding: 0 var(--hy-breadcrumb-separator-gap, 3px);
80
+ color: var(--hy-muted-color, #657185);
81
+ user-select: none;
82
+ }
83
+ `;
84
+ this._nav.part.add('nav');
85
+ this._list.part.add('list');
86
+ this._nav.append(this._list);
87
+ root.append(style, this._nav);
88
+ }
89
+ connectedCallback() {
90
+ if (this.hasAttribute('items'))
91
+ this._readItemsAttribute();
92
+ this._render();
93
+ }
94
+ attributeChangedCallback(name, oldValue, newValue) {
95
+ if (oldValue === newValue)
96
+ return;
97
+ if (name === 'items')
98
+ this._readItemsAttribute();
99
+ this._render();
100
+ }
101
+ get items() { return this._items; }
102
+ set items(value) {
103
+ this._items = Array.isArray(value) ? value.map(item => ({ ...item, title: itemTitle(item) })) : [];
104
+ this._render();
105
+ }
106
+ get separator() { return this.getAttribute('separator') ?? '/'; }
107
+ set separator(value) { this.setAttribute('separator', String(value)); }
108
+ get renderItem() { return this._renderItem; }
109
+ set renderItem(value) {
110
+ this._renderItem = typeof value === 'function' ? value : null;
111
+ this._render();
112
+ }
113
+ _readItemsAttribute() {
114
+ const raw = this.getAttribute('items');
115
+ if (!raw) {
116
+ this._items = [];
117
+ return;
118
+ }
119
+ try {
120
+ const parsed = JSON.parse(raw);
121
+ this._items = Array.isArray(parsed) ? parsed.map((item) => {
122
+ const record = item && typeof item === 'object' ? item : {};
123
+ return {
124
+ ...(record.key == null ? {} : { key: String(record.key) }),
125
+ title: String(record.title ?? record.label ?? ''),
126
+ ...(record.label == null ? {} : { label: String(record.label) }),
127
+ ...(record.href == null ? {} : { href: String(record.href) }),
128
+ ...(record.target == null ? {} : { target: String(record.target) }),
129
+ disabled: Boolean(record.disabled),
130
+ ...(record.ariaLabel == null ? {} : { ariaLabel: String(record.ariaLabel) }),
131
+ };
132
+ }) : [];
133
+ }
134
+ catch (error) {
135
+ console.warn('Invalid hy-breadcrumb items attribute.', error);
136
+ }
137
+ }
138
+ _render() {
139
+ this._nav.setAttribute('aria-label', this.getAttribute('aria-label') ?? 'Breadcrumb');
140
+ const lastIndex = this._items.length - 1;
141
+ const rows = this._items.map((item, index) => {
142
+ const row = document.createElement('li');
143
+ row.part.add('item');
144
+ if (index > 0) {
145
+ const separator = document.createElement('span');
146
+ separator.className = 'separator';
147
+ separator.part.add('separator');
148
+ separator.setAttribute('aria-hidden', 'true');
149
+ separator.textContent = this.separator;
150
+ row.append(separator);
151
+ }
152
+ const current = index === lastIndex;
153
+ const content = this._renderItem?.(item, index, current) ?? itemTitle(item);
154
+ let element;
155
+ if (current) {
156
+ element = document.createElement('span');
157
+ element.className = 'current';
158
+ element.part.add('current');
159
+ element.setAttribute('aria-current', 'page');
160
+ }
161
+ else if (item.disabled) {
162
+ element = document.createElement('span');
163
+ element.className = 'disabled';
164
+ element.part.add('disabled');
165
+ element.setAttribute('aria-disabled', 'true');
166
+ }
167
+ else if (item.href) {
168
+ const anchor = document.createElement('a');
169
+ anchor.href = item.href;
170
+ if (item.target)
171
+ anchor.target = item.target;
172
+ anchor.part.add('link');
173
+ anchor.addEventListener('click', event => {
174
+ if (!this._dispatchItemClick(item, index))
175
+ event.preventDefault();
176
+ });
177
+ element = anchor;
178
+ }
179
+ else {
180
+ const button = document.createElement('button');
181
+ button.type = 'button';
182
+ button.part.add('button');
183
+ button.addEventListener('click', () => this._dispatchItemClick(item, index));
184
+ element = button;
185
+ }
186
+ if (item.ariaLabel)
187
+ element.setAttribute('aria-label', item.ariaLabel);
188
+ if (content instanceof Node)
189
+ element.append(content);
190
+ else
191
+ element.textContent = content == null ? '' : String(content);
192
+ row.append(element);
193
+ return row;
194
+ });
195
+ this._list.replaceChildren(...rows);
196
+ }
197
+ _dispatchItemClick(item, index) {
198
+ return this.dispatchEvent(new CustomEvent('breadcrumb-click', {
199
+ bubbles: true,
200
+ cancelable: true,
201
+ composed: true,
202
+ detail: { item, index },
203
+ }));
204
+ }
205
+ }
206
+ export function defineBreadcrumbComponents() {
207
+ if (!customElements.get('hy-breadcrumb'))
208
+ customElements.define('hy-breadcrumb', HYBreadcrumb);
209
+ }
210
+ //# sourceMappingURL=breadcrumb.js.map
@@ -0,0 +1,12 @@
1
+ export type HYButtonGroupOrientation = 'horizontal' | 'vertical';
2
+ export declare class HYButtonGroup extends HTMLElement {
3
+ private readonly _group;
4
+ static get observedAttributes(): string[];
5
+ constructor();
6
+ connectedCallback(): void;
7
+ attributeChangedCallback(): void;
8
+ get orientation(): HYButtonGroupOrientation;
9
+ set orientation(value: HYButtonGroupOrientation);
10
+ private _sync;
11
+ }
12
+ export declare function defineButtonGroupComponents(): void;
@@ -0,0 +1,72 @@
1
+ export class HYButtonGroup extends HTMLElement {
2
+ _group = document.createElement('div');
3
+ static get observedAttributes() {
4
+ return ['orientation', 'aria-label'];
5
+ }
6
+ constructor() {
7
+ super();
8
+ const root = this.attachShadow({ mode: 'open' });
9
+ const style = document.createElement('style');
10
+ style.textContent = `
11
+ :host { display: inline-flex; max-width: 100%; }
12
+ .group { display: inline-flex; align-items: stretch; max-width: 100%; }
13
+ :host([orientation="vertical"]) .group { flex-direction: column; }
14
+ ::slotted(hy-button) {
15
+ position: relative;
16
+ display: block;
17
+ --hy-button-radius: 0;
18
+ }
19
+ :host(:not([orientation="vertical"])) ::slotted(hy-button:not(:first-child)) { margin-left: -1px; }
20
+ :host(:not([orientation="vertical"])) ::slotted(hy-button:first-child) {
21
+ --hy-button-radius-top-left: var(--hy-button-group-radius, 4px);
22
+ --hy-button-radius-bottom-left: var(--hy-button-group-radius, 4px);
23
+ }
24
+ :host(:not([orientation="vertical"])) ::slotted(hy-button:last-child) {
25
+ --hy-button-radius-top-right: var(--hy-button-group-radius, 4px);
26
+ --hy-button-radius-bottom-right: var(--hy-button-group-radius, 4px);
27
+ }
28
+ :host([orientation="vertical"]) ::slotted(hy-button:not(:first-child)) { margin-top: -1px; }
29
+ :host([orientation="vertical"]) ::slotted(hy-button:first-child) {
30
+ --hy-button-radius-top-left: var(--hy-button-group-radius, 4px);
31
+ --hy-button-radius-top-right: var(--hy-button-group-radius, 4px);
32
+ }
33
+ :host([orientation="vertical"]) ::slotted(hy-button:last-child) {
34
+ --hy-button-radius-bottom-left: var(--hy-button-group-radius, 4px);
35
+ --hy-button-radius-bottom-right: var(--hy-button-group-radius, 4px);
36
+ }
37
+ ::slotted(hy-button:hover), ::slotted(hy-button:focus-within) { z-index: 1; }
38
+ `;
39
+ this._group.className = 'group';
40
+ this._group.part.add('group');
41
+ this._group.setAttribute('role', 'group');
42
+ this._group.append(document.createElement('slot'));
43
+ root.append(style, this._group);
44
+ }
45
+ connectedCallback() {
46
+ if (!this.hasAttribute('orientation'))
47
+ this.setAttribute('orientation', 'horizontal');
48
+ this._sync();
49
+ }
50
+ attributeChangedCallback() {
51
+ this._sync();
52
+ }
53
+ get orientation() {
54
+ return this.getAttribute('orientation') === 'vertical' ? 'vertical' : 'horizontal';
55
+ }
56
+ set orientation(value) {
57
+ this.setAttribute('orientation', value === 'vertical' ? 'vertical' : 'horizontal');
58
+ }
59
+ _sync() {
60
+ const label = this.getAttribute('aria-label');
61
+ if (label)
62
+ this._group.setAttribute('aria-label', label);
63
+ else
64
+ this._group.removeAttribute('aria-label');
65
+ }
66
+ }
67
+ export function defineButtonGroupComponents() {
68
+ if (!customElements.get('hy-button-group')) {
69
+ customElements.define('hy-button-group', HYButtonGroup);
70
+ }
71
+ }
72
+ //# sourceMappingURL=button-group.js.map
package/dist/button.d.ts CHANGED
@@ -1,10 +1,24 @@
1
+ export type HYButtonIconPosition = 'start' | 'end';
1
2
  export declare class HYButton extends HTMLElement {
2
3
  private readonly _button;
3
- private readonly _slot;
4
+ private readonly _content;
5
+ private readonly _contentSlot;
6
+ private readonly _icon;
7
+ private readonly _iconSlot;
8
+ private readonly _iconFallback;
9
+ private readonly _spinner;
4
10
  static get observedAttributes(): string[];
5
11
  constructor();
6
12
  connectedCallback(): void;
7
13
  attributeChangedCallback(): void;
14
+ get loading(): boolean;
15
+ set loading(value: boolean);
16
+ get icon(): string;
17
+ set icon(value: string);
18
+ get iconPosition(): HYButtonIconPosition;
19
+ set iconPosition(value: HYButtonIconPosition);
20
+ click(): void;
8
21
  private _sync;
22
+ private _syncIcon;
9
23
  }
10
24
  export declare function defineButtonComponents(): void;
package/dist/button.js CHANGED
@@ -1,20 +1,34 @@
1
1
  export class HYButton extends HTMLElement {
2
2
  _button = document.createElement('button');
3
- _slot = document.createElement('slot');
3
+ _content = document.createElement('span');
4
+ _contentSlot = document.createElement('slot');
5
+ _icon = document.createElement('span');
6
+ _iconSlot = document.createElement('slot');
7
+ _iconFallback = document.createElement('span');
8
+ _spinner = document.createElement('span');
4
9
  static get observedAttributes() {
5
- return ['label', 'disabled', 'aria-label', 'title', 'icon-only'];
10
+ return ['label', 'disabled', 'aria-label', 'aria-pressed', 'title', 'icon-only', 'icon', 'icon-position', 'loading'];
6
11
  }
7
12
  constructor() {
8
13
  super();
9
14
  const root = this.attachShadow({ mode: 'open' });
10
15
  const style = document.createElement('style');
11
16
  style.textContent = `
12
- :host { display: inline-block; }
17
+ :host { display: inline-block; min-width: 0; }
13
18
  button {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ gap: var(--hy-button-icon-gap, 7px);
23
+ width: 100%;
14
24
  min-height: 28px;
15
25
  padding: 0 10px;
16
26
  border: 1px solid var(--hy-border-color, #3d4654);
17
- border-radius: 4px;
27
+ border-radius:
28
+ var(--hy-button-radius-top-left, var(--hy-button-radius, 4px))
29
+ var(--hy-button-radius-top-right, var(--hy-button-radius, 4px))
30
+ var(--hy-button-radius-bottom-right, var(--hy-button-radius, 4px))
31
+ var(--hy-button-radius-bottom-left, var(--hy-button-radius, 4px));
18
32
  background: var(--hy-surface-elevated-color, #202733);
19
33
  color: var(--hy-text-color, #eef3ff);
20
34
  font: 12px system-ui, sans-serif;
@@ -31,9 +45,21 @@ export class HYButton extends HTMLElement {
31
45
  button.icon-only {
32
46
  width: 28px;
33
47
  padding: 0;
34
- display: inline-grid;
35
- place-items: center;
48
+ gap: 0;
36
49
  }
50
+ .icon { display: inline-grid; flex: 0 0 auto; place-items: center; line-height: 1; }
51
+ button.icon-end .icon { order: 2; }
52
+ .icon[hidden], .spinner[hidden] { display: none; }
53
+ .spinner {
54
+ width: var(--hy-button-loading-size, 14px);
55
+ height: var(--hy-button-loading-size, 14px);
56
+ box-sizing: border-box;
57
+ border: var(--hy-button-loading-stroke, 2px) solid color-mix(in srgb, currentColor 28%, transparent);
58
+ border-top-color: currentColor;
59
+ border-radius: 50%;
60
+ animation: hy-button-spin var(--hy-button-loading-duration, 0.72s) linear infinite;
61
+ }
62
+ @keyframes hy-button-spin { to { transform: rotate(360deg); } }
37
63
  ::slotted(svg) {
38
64
  width: 16px;
39
65
  height: 16px;
@@ -48,7 +74,26 @@ export class HYButton extends HTMLElement {
48
74
  opacity: 0.5;
49
75
  cursor: default;
50
76
  }
77
+ @media (prefers-reduced-motion: reduce) {
78
+ .spinner { animation-duration: 1.5s; }
79
+ }
51
80
  `;
81
+ this._button.type = 'button';
82
+ this._button.part.add('button');
83
+ this._content.className = 'content';
84
+ this._content.part.add('content');
85
+ this._icon.className = 'icon';
86
+ this._icon.part.add('icon');
87
+ this._iconSlot.name = 'icon';
88
+ this._iconFallback.className = 'icon-fallback';
89
+ this._spinner.className = 'spinner';
90
+ this._spinner.part.add('spinner');
91
+ this._spinner.setAttribute('aria-hidden', 'true');
92
+ this._iconSlot.append(this._iconFallback);
93
+ this._icon.append(this._iconSlot, this._spinner);
94
+ this._content.append(this._contentSlot);
95
+ this._button.append(this._icon, this._content);
96
+ this._iconSlot.addEventListener('slotchange', () => this._syncIcon());
52
97
  root.append(style, this._button);
53
98
  }
54
99
  connectedCallback() {
@@ -57,24 +102,68 @@ export class HYButton extends HTMLElement {
57
102
  attributeChangedCallback() {
58
103
  this._sync();
59
104
  }
105
+ get loading() {
106
+ return this.hasAttribute('loading');
107
+ }
108
+ set loading(value) {
109
+ this.toggleAttribute('loading', Boolean(value));
110
+ }
111
+ get icon() {
112
+ return this.getAttribute('icon') ?? '';
113
+ }
114
+ set icon(value) {
115
+ if (value)
116
+ this.setAttribute('icon', value);
117
+ else
118
+ this.removeAttribute('icon');
119
+ }
120
+ get iconPosition() {
121
+ return this.getAttribute('icon-position') === 'end' ? 'end' : 'start';
122
+ }
123
+ set iconPosition(value) {
124
+ this.setAttribute('icon-position', value === 'end' ? 'end' : 'start');
125
+ }
126
+ click() {
127
+ this._button.click();
128
+ }
60
129
  _sync() {
61
130
  const label = this.getAttribute('label');
62
131
  if (label !== null) {
63
- this._button.textContent = label;
64
- this._button.classList.remove('icon-only');
132
+ if (this._content.textContent !== label || this._content.firstChild === this._contentSlot)
133
+ this._content.textContent = label;
65
134
  this._button.removeAttribute('aria-label');
66
135
  }
67
136
  else {
68
- if (this._button.firstChild !== this._slot)
69
- this._button.replaceChildren(this._slot);
70
- this._button.classList.toggle('icon-only', this.hasAttribute('icon-only'));
137
+ if (this._content.firstChild !== this._contentSlot)
138
+ this._content.replaceChildren(this._contentSlot);
71
139
  const accessibleLabel = this.getAttribute('aria-label') ?? this.getAttribute('title') ?? '';
72
140
  if (accessibleLabel)
73
141
  this._button.setAttribute('aria-label', accessibleLabel);
74
142
  else
75
143
  this._button.removeAttribute('aria-label');
76
144
  }
77
- this._button.disabled = this.hasAttribute('disabled');
145
+ const loading = this.loading;
146
+ this._button.classList.toggle('icon-only', label === null && this.hasAttribute('icon-only'));
147
+ this._button.classList.toggle('icon-end', this.iconPosition === 'end');
148
+ this._button.disabled = this.hasAttribute('disabled') || loading;
149
+ if (loading)
150
+ this._button.setAttribute('aria-busy', 'true');
151
+ else
152
+ this._button.removeAttribute('aria-busy');
153
+ const pressed = this.getAttribute('aria-pressed');
154
+ if (pressed === 'true' || pressed === 'false' || pressed === 'mixed')
155
+ this._button.setAttribute('aria-pressed', pressed);
156
+ else
157
+ this._button.removeAttribute('aria-pressed');
158
+ this._syncIcon();
159
+ }
160
+ _syncIcon() {
161
+ const loading = this.loading;
162
+ const assignedIcon = this._iconSlot.assignedNodes({ flatten: true }).some(node => node.nodeType !== Node.TEXT_NODE || Boolean(node.textContent?.trim()));
163
+ this._iconFallback.textContent = this.icon;
164
+ this._iconSlot.hidden = loading;
165
+ this._spinner.hidden = !loading;
166
+ this._icon.hidden = !loading && !this.icon && !assignedIcon;
78
167
  }
79
168
  }
80
169
  export function defineButtonComponents() {
@@ -0,0 +1,92 @@
1
+ export type HYCarouselDirection = 'horizontal' | 'vertical';
2
+ export type HYCarouselIndicatorPosition = 'top' | 'right' | 'bottom' | 'left';
3
+ export type HYCarouselIndicatorStyle = 'dot' | 'line' | 'number';
4
+ export type HYCarouselChangeSource = 'api' | 'indicator' | 'arrow' | 'keyboard' | 'drag' | 'autoplay' | 'content';
5
+ export interface HYCarouselChangeDetail {
6
+ index: number;
7
+ previousIndex: number;
8
+ source: HYCarouselChangeSource;
9
+ }
10
+ export type HYCarouselIndicatorRenderer = (index: number, active: boolean) => Node | string | null;
11
+ /** A slotted, accessible carousel. Panels stay mounted and inactive panels are inert. */
12
+ export declare class HYCarousel extends HTMLElement {
13
+ private readonly _viewport;
14
+ private readonly _slot;
15
+ private readonly _indicators;
16
+ private readonly _previous;
17
+ private readonly _next;
18
+ private readonly _playback;
19
+ private readonly _motion;
20
+ private readonly _saved;
21
+ private readonly _animations;
22
+ private readonly _hostAttributes;
23
+ private _slides;
24
+ private _index;
25
+ private _reflecting;
26
+ private _connected;
27
+ private _timer;
28
+ private _paused;
29
+ private _hovered;
30
+ private _motionOverride;
31
+ private _drag;
32
+ private _blockClickUntil;
33
+ private _playbackPointerAction;
34
+ private _indicatorRenderer;
35
+ static get observedAttributes(): string[];
36
+ constructor();
37
+ connectedCallback(): void;
38
+ disconnectedCallback(): void;
39
+ attributeChangedCallback(name: string, oldValue: string | null, value: string | null): void;
40
+ get index(): number;
41
+ set index(value: number);
42
+ get direction(): HYCarouselDirection;
43
+ set direction(value: HYCarouselDirection);
44
+ get indicatorPosition(): HYCarouselIndicatorPosition;
45
+ set indicatorPosition(value: HYCarouselIndicatorPosition);
46
+ get indicatorStyle(): HYCarouselIndicatorStyle;
47
+ set indicatorStyle(value: HYCarouselIndicatorStyle);
48
+ get indicatorRenderer(): HYCarouselIndicatorRenderer | null;
49
+ set indicatorRenderer(value: HYCarouselIndicatorRenderer | null);
50
+ get showIndicators(): boolean;
51
+ set showIndicators(value: boolean);
52
+ get showArrows(): boolean;
53
+ set showArrows(value: boolean);
54
+ get autoplay(): boolean;
55
+ set autoplay(value: boolean);
56
+ get interval(): number;
57
+ set interval(value: number);
58
+ get draggable(): boolean;
59
+ set draggable(value: boolean);
60
+ get loop(): boolean;
61
+ set loop(value: boolean);
62
+ next(): void;
63
+ previous(): void;
64
+ goTo(index: number): void;
65
+ play(): void;
66
+ pause(): void;
67
+ private _syncSlides;
68
+ private _releaseSlide;
69
+ private _resolve;
70
+ private _select;
71
+ private _transform;
72
+ private _position;
73
+ private _paint;
74
+ private _render;
75
+ private _animate;
76
+ private _cancelAnimations;
77
+ private _clearTimer;
78
+ private _schedule;
79
+ private _onEnter;
80
+ private _onLeave;
81
+ private _onMotionChange;
82
+ private _onFocus;
83
+ private _onKeyDown;
84
+ private _onNativeDrag;
85
+ private _onClick;
86
+ private _onPointerDown;
87
+ private _onPointerMove;
88
+ private _onPointerUp;
89
+ private _onPointerCancel;
90
+ private _cancelDrag;
91
+ }
92
+ export declare function defineCarouselComponents(): void;