@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
package/dist/tabs.d.ts CHANGED
@@ -22,6 +22,9 @@ export declare class HYTabs extends HTMLElement {
22
22
  set options(value: HYTabOption[]);
23
23
  get value(): string;
24
24
  set value(value: string);
25
+ /** Opt-in application ownership, including a disabled authoritative selection. */
26
+ get controlled(): boolean;
27
+ set controlled(value: boolean);
25
28
  private _syncFromAttributes;
26
29
  private _readOptionsAttribute;
27
30
  private _render;
package/dist/tabs.js CHANGED
@@ -6,7 +6,7 @@ export class HYTabs extends HTMLElement {
6
6
  _options = [];
7
7
  _pendingFocusValue = null;
8
8
  static get observedAttributes() {
9
- return ['options', 'value', 'aria-label'];
9
+ return ['options', 'value', 'aria-label', 'controlled'];
10
10
  }
11
11
  constructor() {
12
12
  super();
@@ -68,6 +68,11 @@ export class HYTabs extends HTMLElement {
68
68
  min-height: 0;
69
69
  overflow: auto;
70
70
  }
71
+ .panels > [role="tabpanel"] {
72
+ height: 100%;
73
+ min-width: 0;
74
+ min-height: 0;
75
+ }
71
76
  ::slotted(*) {
72
77
  box-sizing: border-box;
73
78
  }
@@ -111,6 +116,9 @@ export class HYTabs extends HTMLElement {
111
116
  set value(value) {
112
117
  this.setAttribute('value', value);
113
118
  }
119
+ /** Opt-in application ownership, including a disabled authoritative selection. */
120
+ get controlled() { return this.hasAttribute('controlled'); }
121
+ set controlled(value) { this.toggleAttribute('controlled', value); }
114
122
  _syncFromAttributes() {
115
123
  if (this.hasAttribute('options'))
116
124
  this._readOptionsAttribute();
@@ -197,6 +205,8 @@ export class HYTabs extends HTMLElement {
197
205
  [...this._tabs.querySelectorAll('button')].find(button => button.dataset.value === value)?.focus();
198
206
  }
199
207
  _resolveValue(enabled = this._options.filter(option => !option.disabled)) {
208
+ if (this.controlled && this._options.some(option => option.value === this.value))
209
+ return this.value;
200
210
  if (enabled.some(option => option.value === this.value))
201
211
  return this.value;
202
212
  if (enabled[0])
package/dist/tag.d.ts ADDED
@@ -0,0 +1,55 @@
1
+ export type HYTagVariant = 'default' | 'primary' | 'success' | 'warning' | 'error';
2
+ export type HYTagSize = 'small' | 'medium' | 'large';
3
+ export interface HYTagCloseDetail {
4
+ readonly value: string;
5
+ }
6
+ export interface HYTagCheckedChangeDetail {
7
+ readonly checked: boolean;
8
+ readonly value: string;
9
+ }
10
+ /** Compact semantic label with optional close and checked interactions. */
11
+ export declare class HYTag extends HTMLElement {
12
+ private readonly _tag;
13
+ private readonly _icon;
14
+ private readonly _iconSlot;
15
+ private readonly _iconText;
16
+ private readonly _labelSlot;
17
+ private readonly _labelText;
18
+ private readonly _label;
19
+ private readonly _close;
20
+ static get observedAttributes(): string[];
21
+ constructor();
22
+ connectedCallback(): void;
23
+ disconnectedCallback(): void;
24
+ attributeChangedCallback(): void;
25
+ get variant(): HYTagVariant;
26
+ set variant(value: HYTagVariant);
27
+ get color(): string;
28
+ set color(value: string);
29
+ get size(): HYTagSize;
30
+ set size(value: HYTagSize);
31
+ get label(): string;
32
+ set label(value: string);
33
+ get icon(): string;
34
+ set icon(value: string);
35
+ get value(): string;
36
+ set value(value: string);
37
+ get closable(): boolean;
38
+ set closable(value: boolean);
39
+ get checkable(): boolean;
40
+ set checkable(value: boolean);
41
+ get checked(): boolean;
42
+ set checked(value: boolean);
43
+ get disabled(): boolean;
44
+ set disabled(value: boolean);
45
+ close(): boolean;
46
+ private _toggleChecked;
47
+ private _sync;
48
+ private _syncIcon;
49
+ private _syncLabel;
50
+ private _setOptionalAttribute;
51
+ private _onTagClick;
52
+ private _onCloseClick;
53
+ private _onKeydown;
54
+ }
55
+ export declare function defineTagComponents(): void;
package/dist/tag.js ADDED
@@ -0,0 +1,225 @@
1
+ const VARIANTS = ['default', 'primary', 'success', 'warning', 'error'];
2
+ const SIZES = ['small', 'medium', 'large'];
3
+ function isVariant(value) {
4
+ return typeof value === 'string' && VARIANTS.includes(value);
5
+ }
6
+ function isSize(value) {
7
+ return typeof value === 'string' && SIZES.includes(value);
8
+ }
9
+ /** Compact semantic label with optional close and checked interactions. */
10
+ export class HYTag extends HTMLElement {
11
+ _tag = document.createElement('span');
12
+ _icon = document.createElement('span');
13
+ _iconSlot = document.createElement('slot');
14
+ _iconText = document.createElement('span');
15
+ _labelSlot = document.createElement('slot');
16
+ _labelText = document.createElement('span');
17
+ _label = document.createElement('span');
18
+ _close = document.createElement('button');
19
+ static get observedAttributes() {
20
+ return ['variant', 'color', 'size', 'label', 'icon', 'closable', 'checkable', 'checked', 'disabled', 'value'];
21
+ }
22
+ constructor() {
23
+ super();
24
+ const root = this.attachShadow({ mode: 'open' });
25
+ const style = document.createElement('style');
26
+ style.textContent = `
27
+ :host { display: inline-flex; max-width: 100%; vertical-align: middle; }
28
+ :host([hidden]) { display: none !important; }
29
+ .tag {
30
+ --_tone: var(--hy-secondary-text-color, #9aa8ba);
31
+ --_surface: color-mix(in srgb, var(--_tone) 12%, var(--hy-surface-color, #121822));
32
+ display: inline-flex;
33
+ max-width: 100%;
34
+ min-height: var(--hy-tag-height, 24px);
35
+ box-sizing: border-box;
36
+ align-items: center;
37
+ gap: var(--hy-tag-gap, 5px);
38
+ padding: 2px var(--hy-tag-padding-inline, 8px);
39
+ border: 1px solid color-mix(in srgb, var(--_tone) 42%, var(--hy-border-color, #303746));
40
+ border-radius: var(--hy-tag-radius, 5px);
41
+ color: var(--_tone);
42
+ background: var(--_surface);
43
+ font: 600 var(--hy-tag-font-size, 11px)/1.35 system-ui, sans-serif;
44
+ transition: border-color 120ms ease, box-shadow 120ms ease, color 120ms ease, background 120ms ease;
45
+ }
46
+ .tag[data-variant="primary"] { --_tone: var(--hy-accent-color, #79a8ff); }
47
+ .tag[data-variant="success"] { --_tone: var(--hy-success-color, #55c98a); }
48
+ .tag[data-variant="warning"] { --_tone: var(--hy-warning-color, #e7b75a); }
49
+ .tag[data-variant="error"] { --_tone: var(--hy-error-color, #ef6b78); }
50
+ :host([checkable]) .tag { cursor: pointer; user-select: none; }
51
+ :host([checkable][checked]) .tag {
52
+ color: var(--hy-selected-text-color, #fff);
53
+ background: var(--_tone);
54
+ border-color: var(--_tone);
55
+ }
56
+ :host(:focus-visible) { outline: none; }
57
+ :host(:focus-visible) .tag { box-shadow: 0 0 0 2px var(--hy-focus-ring-color, rgba(61, 111, 168, .24)); }
58
+ :host([disabled]) { pointer-events: none; opacity: .5; }
59
+ :host([size="small"]) .tag { --hy-tag-height: 20px; --hy-tag-padding-inline: 6px; --hy-tag-font-size: 10px; }
60
+ :host([size="large"]) .tag { --hy-tag-height: 30px; --hy-tag-padding-inline: 11px; --hy-tag-font-size: 12px; }
61
+ .icon { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; }
62
+ .icon[hidden] { display: none; }
63
+ .label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
64
+ .close {
65
+ display: none;
66
+ width: 16px;
67
+ height: 16px;
68
+ margin-inline-end: -3px;
69
+ padding: 0;
70
+ border: 0;
71
+ border-radius: 50%;
72
+ place-items: center;
73
+ color: currentColor;
74
+ background: transparent;
75
+ cursor: pointer;
76
+ font: 15px/1 system-ui, sans-serif;
77
+ }
78
+ :host([closable]) .close { display: grid; }
79
+ .close:hover { background: color-mix(in srgb, currentColor 16%, transparent); }
80
+ .close:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
81
+ ::slotted([slot="icon"]) { width: 1em; height: 1em; }
82
+ @media (prefers-reduced-motion: reduce) { .tag { transition: none; } }
83
+ `;
84
+ this._tag.className = 'tag';
85
+ this._tag.part.add('tag');
86
+ this._icon.className = 'icon';
87
+ this._icon.part.add('icon');
88
+ this._iconSlot.name = 'icon';
89
+ this._iconText.className = 'icon-text';
90
+ this._icon.append(this._iconSlot, this._iconText);
91
+ this._label.className = 'label';
92
+ this._label.part.add('label');
93
+ this._labelText.className = 'label-text';
94
+ this._label.append(this._labelSlot, this._labelText);
95
+ this._close.className = 'close';
96
+ this._close.part.add('close-button');
97
+ this._close.type = 'button';
98
+ this._close.textContent = '×';
99
+ this._close.setAttribute('aria-label', 'Close tag');
100
+ this._tag.append(this._icon, this._label, this._close);
101
+ root.append(style, this._tag);
102
+ }
103
+ connectedCallback() {
104
+ this._tag.addEventListener('click', this._onTagClick);
105
+ this._close.addEventListener('click', this._onCloseClick);
106
+ this.addEventListener('keydown', this._onKeydown);
107
+ this._iconSlot.addEventListener('slotchange', this._syncIcon);
108
+ this._labelSlot.addEventListener('slotchange', this._syncLabel);
109
+ this._sync();
110
+ }
111
+ disconnectedCallback() {
112
+ this._tag.removeEventListener('click', this._onTagClick);
113
+ this._close.removeEventListener('click', this._onCloseClick);
114
+ this.removeEventListener('keydown', this._onKeydown);
115
+ this._iconSlot.removeEventListener('slotchange', this._syncIcon);
116
+ this._labelSlot.removeEventListener('slotchange', this._syncLabel);
117
+ }
118
+ attributeChangedCallback() { this._sync(); }
119
+ get variant() { return isVariant(this.getAttribute('variant')) ? this.getAttribute('variant') : 'default'; }
120
+ set variant(value) { this.setAttribute('variant', isVariant(value) ? value : 'default'); }
121
+ get color() { return this.getAttribute('color')?.trim() ?? ''; }
122
+ set color(value) { this._setOptionalAttribute('color', value); }
123
+ get size() { return isSize(this.getAttribute('size')) ? this.getAttribute('size') : 'medium'; }
124
+ set size(value) { this.setAttribute('size', isSize(value) ? value : 'medium'); }
125
+ get label() { return this.getAttribute('label') ?? ''; }
126
+ set label(value) { this._setOptionalAttribute('label', value); }
127
+ get icon() { return this.getAttribute('icon') ?? ''; }
128
+ set icon(value) { this._setOptionalAttribute('icon', value); }
129
+ get value() { return this.getAttribute('value') ?? ''; }
130
+ set value(value) { this.setAttribute('value', String(value ?? '')); }
131
+ get closable() { return this.hasAttribute('closable'); }
132
+ set closable(value) { this.toggleAttribute('closable', Boolean(value)); }
133
+ get checkable() { return this.hasAttribute('checkable'); }
134
+ set checkable(value) { this.toggleAttribute('checkable', Boolean(value)); }
135
+ get checked() { return this.hasAttribute('checked'); }
136
+ set checked(value) { this.toggleAttribute('checked', Boolean(value)); }
137
+ get disabled() { return this.hasAttribute('disabled'); }
138
+ set disabled(value) { this.toggleAttribute('disabled', Boolean(value)); }
139
+ close() {
140
+ if (!this.closable || this.disabled)
141
+ return false;
142
+ const accepted = this.dispatchEvent(new CustomEvent('tag-close', {
143
+ detail: { value: this.value },
144
+ bubbles: true,
145
+ composed: true,
146
+ cancelable: true,
147
+ }));
148
+ if (accepted)
149
+ this.hidden = true;
150
+ return accepted;
151
+ }
152
+ _toggleChecked() {
153
+ if (!this.checkable || this.disabled)
154
+ return;
155
+ this.checked = !this.checked;
156
+ this.dispatchEvent(new CustomEvent('checked-change', {
157
+ detail: { checked: this.checked, value: this.value },
158
+ bubbles: true,
159
+ composed: true,
160
+ }));
161
+ }
162
+ _sync() {
163
+ this._tag.dataset.variant = this.variant;
164
+ const color = this.color;
165
+ if (color)
166
+ this._tag.style.setProperty('--_tone', color);
167
+ else
168
+ this._tag.style.removeProperty('--_tone');
169
+ this._close.disabled = this.disabled;
170
+ this._close.tabIndex = this.closable ? 0 : -1;
171
+ if (this.checkable) {
172
+ this.setAttribute('role', 'checkbox');
173
+ this.setAttribute('aria-checked', String(this.checked));
174
+ this.setAttribute('aria-disabled', String(this.disabled));
175
+ if (!this.hasAttribute('tabindex'))
176
+ this.tabIndex = this.disabled ? -1 : 0;
177
+ }
178
+ else {
179
+ this.removeAttribute('role');
180
+ this.removeAttribute('aria-checked');
181
+ this.removeAttribute('aria-disabled');
182
+ if (this.getAttribute('tabindex') === '0' || this.getAttribute('tabindex') === '-1')
183
+ this.removeAttribute('tabindex');
184
+ }
185
+ this._syncIcon();
186
+ this._syncLabel();
187
+ }
188
+ _syncIcon = () => {
189
+ const assigned = this._iconSlot.assignedNodes({ flatten: true }).some(node => node.nodeType === Node.ELEMENT_NODE || Boolean(node.textContent?.trim()));
190
+ this._iconText.textContent = assigned ? '' : this.icon;
191
+ this._icon.hidden = !assigned && !this.icon;
192
+ };
193
+ _syncLabel = () => {
194
+ const assigned = this._labelSlot.assignedNodes({ flatten: true }).some(node => node.nodeType === Node.ELEMENT_NODE || Boolean(node.textContent?.trim()));
195
+ this._labelText.textContent = assigned ? '' : this.label;
196
+ this._labelText.hidden = assigned || !this.label;
197
+ };
198
+ _setOptionalAttribute(name, value) {
199
+ const normalized = String(value ?? '').trim();
200
+ if (normalized)
201
+ this.setAttribute(name, normalized);
202
+ else
203
+ this.removeAttribute(name);
204
+ }
205
+ _onTagClick = (event) => {
206
+ if (event.composedPath().includes(this._close))
207
+ return;
208
+ this._toggleChecked();
209
+ };
210
+ _onCloseClick = (event) => {
211
+ event.stopPropagation();
212
+ this.close();
213
+ };
214
+ _onKeydown = (event) => {
215
+ if (!this.checkable || this.disabled || (event.key !== 'Enter' && event.key !== ' '))
216
+ return;
217
+ event.preventDefault();
218
+ this._toggleChecked();
219
+ };
220
+ }
221
+ export function defineTagComponents() {
222
+ if (!customElements.get('hy-tag'))
223
+ customElements.define('hy-tag', HYTag);
224
+ }
225
+ //# sourceMappingURL=tag.js.map
@@ -0,0 +1,62 @@
1
+ export interface HYTimePickerChangeDetail {
2
+ readonly value: string;
3
+ readonly hour: number | null;
4
+ readonly minute: number | null;
5
+ readonly second: number | null;
6
+ }
7
+ export interface HYTimePickerOpenChangeDetail {
8
+ readonly open: boolean;
9
+ }
10
+ /** Accessible column-based time picker with stable 24-hour values. */
11
+ export declare class HYTimePicker extends HTMLElement {
12
+ private readonly _control;
13
+ private readonly _trigger;
14
+ private readonly _label;
15
+ private readonly _arrow;
16
+ private readonly _clear;
17
+ private readonly _panel;
18
+ private readonly _panelId;
19
+ private _value;
20
+ private _draft;
21
+ private _reflecting;
22
+ private _outsideAbort;
23
+ static get observedAttributes(): string[];
24
+ constructor();
25
+ connectedCallback(): void;
26
+ disconnectedCallback(): void;
27
+ attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
28
+ get value(): string;
29
+ set value(value: string);
30
+ get open(): boolean;
31
+ set open(value: boolean);
32
+ get disabled(): boolean;
33
+ set disabled(value: boolean);
34
+ get clearable(): boolean;
35
+ set clearable(value: boolean);
36
+ get placeholder(): string;
37
+ set placeholder(value: string);
38
+ get showSeconds(): boolean;
39
+ set showSeconds(value: boolean);
40
+ get minuteStep(): number;
41
+ set minuteStep(value: number);
42
+ get secondStep(): number;
43
+ set secondStep(value: number);
44
+ get min(): string;
45
+ set min(value: string);
46
+ get max(): string;
47
+ set max(value: string);
48
+ private _syncAttributes;
49
+ private _normalizeValue;
50
+ private _reflectValue;
51
+ private _isAllowed;
52
+ private _setDraft;
53
+ private _render;
54
+ private _renderPanel;
55
+ private _createColumn;
56
+ private _handleOptionKeydown;
57
+ private _focusSelected;
58
+ private _commit;
59
+ private _syncOutsideListener;
60
+ private _dispatchOpenChange;
61
+ }
62
+ export declare function defineTimePickerComponents(): void;