@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/index.js CHANGED
@@ -1,8 +1,17 @@
1
1
  import { defineExpandableComponents } from './expandable.js';
2
2
  export { defineExpandableComponents, HYExpandable } from './expandable.js';
3
3
  import { defineButtonComponents } from './button.js';
4
+ import { defineButtonGroupComponents } from './button-group.js';
4
5
  import { defineBorderBeamComponents } from './border-beam.js';
5
6
  import { defineTreeComponents } from './tree.js';
7
+ import { defineModalComponents } from './modal.js';
8
+ export { defineModalComponents, HYModal } from './modal.js';
9
+ import { defineQRCodeComponents } from './qr-code.js';
10
+ export { defineQRCodeComponents, HYQRCode } from './qr-code.js';
11
+ import { defineCarouselComponents } from './carousel.js';
12
+ export { defineCarouselComponents, HYCarousel } from './carousel.js';
13
+ import { defineMasonryComponents } from './masonry.js';
14
+ export { defineMasonryComponents, HYMasonry } from './masonry.js';
6
15
  import { defineSplitComponents } from './split.js';
7
16
  import { defineSelectComponents } from './select.js';
8
17
  import { defineTabsComponents } from './tabs.js';
@@ -12,13 +21,35 @@ import { defineTooltipComponents } from './tooltip.js';
12
21
  import { defineCheckboxComponents } from './checkbox.js';
13
22
  import { defineRadioComponents } from './radio.js';
14
23
  import { defineRangeComponents } from './range.js';
24
+ import { defineResizableComponents } from './resizable.js';
15
25
  import { defineDialogComponents } from './dialog.js';
16
26
  import { defineDrawerComponents } from './drawer.js';
27
+ import { defineDraggableComponents } from './draggable.js';
17
28
  import { defineInputComponents } from './input.js';
18
29
  import { defineNotificationComponents } from './notification.js';
30
+ import { defineToastComponents } from './toast.js';
19
31
  import { defineHistoryControlsComponents } from './history-controls.js';
20
32
  import { defineVirtualListComponents } from './virtual-list.js';
33
+ import { defineVirtualMouseComponents } from './virtual-mouse.js';
34
+ import { defineVirtualKeyboardComponents } from './virtual-keyboard.js';
35
+ import { defineTableComponents } from './table.js';
36
+ import { defineBreadcrumbComponents } from './breadcrumb.js';
37
+ import { defineCascaderComponents } from './cascader.js';
38
+ import { defineDatePickerComponents } from './date-picker.js';
39
+ import { defineTimePickerComponents } from './time-picker.js';
40
+ import { defineSkeletonComponents } from './skeleton.js';
41
+ import { defineWatermarkComponents } from './watermark.js';
42
+ import { defineTimelineComponents } from './timeline.js';
43
+ import { defineRateComponents } from './rate.js';
44
+ import { defineDividerComponents } from './divider.js';
45
+ import { defineStepsComponents } from './steps.js';
46
+ import { defineAffixComponents } from './affix.js';
47
+ import { defineTourComponents } from './tour.js';
48
+ import { defineBadgeComponents } from './badge.js';
49
+ import { defineTagComponents } from './tag.js';
50
+ import { defineCollapseComponents } from './collapse.js';
21
51
  export { defineButtonComponents, HYButton, } from './button.js';
52
+ export { defineButtonGroupComponents, HYButtonGroup, } from './button-group.js';
22
53
  export { defineBorderBeamComponents, HYBorderBeam, } from './border-beam.js';
23
54
  export { defineTreeComponents, HYTree, HYTreeNode, } from './tree.js';
24
55
  export { defineSplitComponents, HYSplit, } from './split.js';
@@ -30,18 +61,44 @@ export { defineTooltipComponents, HYTooltip, } from './tooltip.js';
30
61
  export { defineCheckboxComponents, HYCheckbox, } from './checkbox.js';
31
62
  export { defineRadioComponents, HYRadio, } from './radio.js';
32
63
  export { defineRangeComponents, HYRange, } from './range.js';
64
+ export { defineResizableComponents, HYResizable, } from './resizable.js';
33
65
  export { defineDialogComponents, HYDialog, } from './dialog.js';
34
66
  export { defineDrawerComponents, HYDrawer, } from './drawer.js';
67
+ export { defineDraggableComponents, HYDraggable, } from './draggable.js';
35
68
  export { defineInputComponents, HYInput, } from './input.js';
36
69
  export { defineNotificationComponents, HYNotification, } from './notification.js';
70
+ export { defineToastComponents, HYToast, } from './toast.js';
37
71
  export { defineHistoryControlsComponents, HYHistoryControls, } from './history-controls.js';
38
72
  export { calculateVirtualListRange, defineVirtualListComponents, HYVirtualList, } from './virtual-list.js';
73
+ export { defineVirtualMouseComponents, HYVirtualMouse, } from './virtual-mouse.js';
74
+ export { defineVirtualKeyboardComponents, HYVirtualKeyboard, HY_VIRTUAL_KEYBOARD_NUMERIC_LAYOUT, HY_VIRTUAL_KEYBOARD_QWERTY_LAYOUT, } from './virtual-keyboard.js';
75
+ export { defineTableComponents, HYTable, } from './table.js';
76
+ export { defineBreadcrumbComponents, HYBreadcrumb, } from './breadcrumb.js';
77
+ export { defineCascaderComponents, HYCascader, } from './cascader.js';
78
+ export { defineDatePickerComponents, HYDatePicker, } from './date-picker.js';
79
+ export { defineTimePickerComponents, HYTimePicker, } from './time-picker.js';
80
+ export { defineSkeletonComponents, HYSkeleton, } from './skeleton.js';
81
+ export { defineWatermarkComponents, HYWatermark, } from './watermark.js';
82
+ export { defineTimelineComponents, HYTimeline, } from './timeline.js';
83
+ export { defineRateComponents, HYRate, } from './rate.js';
84
+ export { defineDividerComponents, HYDivider, } from './divider.js';
85
+ export { defineStepsComponents, HYSteps, } from './steps.js';
86
+ export { defineAffixComponents, HYAffix, } from './affix.js';
87
+ export { defineTourComponents, HYTour, } from './tour.js';
88
+ export { defineBadgeComponents, HYBadge, } from './badge.js';
89
+ export { defineTagComponents, HYTag, } from './tag.js';
90
+ export { defineCollapseComponents, HYCollapse, } from './collapse.js';
39
91
  export function defineHaiyueUI() {
40
92
  defineExpandableComponents();
41
93
  defineBorderBeamComponents();
42
94
  defineButtonComponents();
95
+ defineButtonGroupComponents();
43
96
  defineTreeComponents();
44
97
  defineSplitComponents();
98
+ defineMasonryComponents();
99
+ defineCarouselComponents();
100
+ defineQRCodeComponents();
101
+ defineModalComponents();
45
102
  defineSelectComponents();
46
103
  defineTabsComponents();
47
104
  defineContextMenuComponents();
@@ -50,11 +107,32 @@ export function defineHaiyueUI() {
50
107
  defineCheckboxComponents();
51
108
  defineRadioComponents();
52
109
  defineRangeComponents();
110
+ defineResizableComponents();
53
111
  defineDialogComponents();
54
112
  defineDrawerComponents();
113
+ defineDraggableComponents();
55
114
  defineInputComponents();
56
115
  defineNotificationComponents();
116
+ defineToastComponents();
57
117
  defineHistoryControlsComponents();
58
118
  defineVirtualListComponents();
119
+ defineVirtualMouseComponents();
120
+ defineVirtualKeyboardComponents();
121
+ defineTableComponents();
122
+ defineBreadcrumbComponents();
123
+ defineCascaderComponents();
124
+ defineDatePickerComponents();
125
+ defineTimePickerComponents();
126
+ defineSkeletonComponents();
127
+ defineWatermarkComponents();
128
+ defineTimelineComponents();
129
+ defineRateComponents();
130
+ defineDividerComponents();
131
+ defineStepsComponents();
132
+ defineAffixComponents();
133
+ defineTourComponents();
134
+ defineBadgeComponents();
135
+ defineTagComponents();
136
+ defineCollapseComponents();
59
137
  }
60
138
  //# sourceMappingURL=index.js.map
package/dist/input.d.ts CHANGED
@@ -1,11 +1,25 @@
1
- export type HYInputType = 'text' | 'number' | 'color';
1
+ export type HYInputType = 'text' | 'number' | 'color' | 'search' | 'password';
2
+ export type HYInputSearchSource = 'enter' | 'button' | 'api';
2
3
  export interface HYInputChangeDetail {
3
4
  value: string;
4
5
  valueAsNumber: number | null;
5
6
  valid: boolean;
6
7
  }
8
+ export interface HYInputSearchDetail {
9
+ value: string;
10
+ valid: boolean;
11
+ source: HYInputSearchSource;
12
+ }
7
13
  export declare class HYInput extends HTMLElement {
14
+ private readonly _control;
15
+ private readonly _prefix;
16
+ private readonly _prefixSlot;
17
+ private readonly _prefixText;
8
18
  private readonly _input;
19
+ private readonly _suffix;
20
+ private readonly _suffixSlot;
21
+ private readonly _suffixText;
22
+ private readonly _searchButton;
9
23
  static get observedAttributes(): string[];
10
24
  constructor();
11
25
  connectedCallback(): void;
@@ -16,6 +30,12 @@ export declare class HYInput extends HTMLElement {
16
30
  get value(): string;
17
31
  set value(value: string);
18
32
  get valueAsNumber(): number;
33
+ get prefix(): string;
34
+ set prefix(value: string);
35
+ get suffix(): string;
36
+ set suffix(value: string);
37
+ get searchLabel(): string;
38
+ set searchLabel(value: string);
19
39
  get disabled(): boolean;
20
40
  set disabled(value: boolean);
21
41
  get readOnly(): boolean;
@@ -23,8 +43,17 @@ export declare class HYInput extends HTMLElement {
23
43
  get valid(): boolean;
24
44
  focus(options?: FocusOptions): void;
25
45
  select(): void;
46
+ search(): boolean;
26
47
  private _sync;
48
+ private _syncAffixes;
49
+ private _syncAffix;
50
+ private _syncValidity;
51
+ private _setOptionalAttribute;
52
+ private _onSlotChange;
27
53
  private _onInput;
28
54
  private _onChange;
55
+ private _onKeydown;
56
+ private _onSearchClick;
57
+ private _emitSearch;
29
58
  }
30
59
  export declare function defineInputComponents(): void;
package/dist/input.js CHANGED
@@ -1,9 +1,18 @@
1
1
  export class HYInput extends HTMLElement {
2
+ _control = document.createElement('div');
3
+ _prefix = document.createElement('span');
4
+ _prefixSlot = document.createElement('slot');
5
+ _prefixText = document.createElement('span');
2
6
  _input = document.createElement('input');
7
+ _suffix = document.createElement('span');
8
+ _suffixSlot = document.createElement('slot');
9
+ _suffixText = document.createElement('span');
10
+ _searchButton = document.createElement('button');
3
11
  static get observedAttributes() {
4
12
  return [
5
13
  'type', 'value', 'min', 'max', 'step', 'placeholder', 'disabled', 'readonly',
6
- 'required', 'name', 'autocomplete', 'aria-label', 'title',
14
+ 'required', 'name', 'autocomplete', 'aria-label', 'title', 'prefix', 'suffix',
15
+ 'search-label',
7
16
  ];
8
17
  }
9
18
  constructor() {
@@ -11,74 +20,132 @@ export class HYInput extends HTMLElement {
11
20
  const root = this.attachShadow({ mode: 'open' });
12
21
  const style = document.createElement('style');
13
22
  style.textContent = `
14
- :host {
15
- display: block;
23
+ :host { display: block; width: 100%; min-width: 0; }
24
+ .control {
25
+ display: flex;
16
26
  width: 100%;
17
27
  min-width: 0;
18
- }
19
- input {
20
- box-sizing: border-box;
21
- width: 100%;
22
28
  height: var(--hy-input-height, 28px);
23
- min-width: 0;
24
- padding: 0 8px;
29
+ box-sizing: border-box;
30
+ align-items: stretch;
31
+ overflow: hidden;
25
32
  border: 1px solid var(--hy-border-color, #303746);
26
- border-radius: 4px;
27
- outline: none;
33
+ border-radius: var(--hy-input-radius, 4px);
28
34
  color: var(--hy-text-color, #d8e2f2);
29
35
  background: var(--hy-input-bg-color, var(--hy-surface-color, #121822));
36
+ transition: border-color 120ms ease, box-shadow 120ms ease;
37
+ }
38
+ .control:hover:not(.disabled):not(.readonly) { border-color: var(--hy-hover-border-color, #435268); }
39
+ .control:focus-within { border-color: var(--hy-focus-border-color, #3d6fa8); box-shadow: 0 0 0 2px var(--hy-focus-ring-color, rgba(61, 111, 168, 0.24)); }
40
+ .control.invalid { border-color: var(--hy-invalid-border-color, #b64f62); }
41
+ .control.disabled, .control.readonly { opacity: 0.55; }
42
+ input {
43
+ flex: 1 1 auto;
44
+ width: 0;
45
+ min-width: 0;
46
+ box-sizing: border-box;
47
+ padding: 0 var(--hy-input-padding-inline, 8px);
48
+ border: 0;
49
+ outline: none;
50
+ color: inherit;
51
+ background: transparent;
30
52
  font: var(--hy-input-font, 12px system-ui, sans-serif);
31
53
  color-scheme: inherit;
32
54
  }
33
- input:hover:not(:disabled):not(:read-only) {
34
- border-color: var(--hy-hover-border-color, #435268);
35
- }
36
- input:focus {
37
- border-color: var(--hy-focus-border-color, #3d6fa8);
38
- box-shadow: 0 0 0 2px var(--hy-focus-ring-color, rgba(61, 111, 168, 0.24));
39
- }
40
- input:invalid {
41
- border-color: var(--hy-invalid-border-color, #b64f62);
42
- }
43
- input:disabled,
44
- input:read-only {
45
- opacity: 0.55;
46
- cursor: default;
47
- }
48
- input[type="color"] {
49
- padding: 3px;
50
- cursor: pointer;
51
- }
55
+ input:disabled, input:read-only { cursor: default; }
56
+ input[type="color"] { min-width: 42px; padding: 3px; cursor: pointer; }
52
57
  input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
53
- input[type="color"]::-webkit-color-swatch {
58
+ input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 2px; }
59
+ input[type="search"]::-webkit-search-cancel-button { cursor: pointer; }
60
+ .affix {
61
+ display: inline-flex;
62
+ flex: 0 0 auto;
63
+ align-items: center;
64
+ max-width: 42%;
65
+ padding-inline: var(--hy-input-affix-padding, 8px);
66
+ overflow: hidden;
67
+ color: var(--hy-input-affix-color, var(--hy-muted-text-color, #8290a3));
68
+ font: var(--hy-input-affix-font, 12px system-ui, sans-serif);
69
+ text-overflow: ellipsis;
70
+ white-space: nowrap;
71
+ }
72
+ .prefix { padding-right: 0; }
73
+ .suffix { padding-left: 0; }
74
+ .affix[hidden], .search-button[hidden] { display: none; }
75
+ .search-button {
76
+ display: grid;
77
+ flex: 0 0 var(--hy-input-search-button-width, 32px);
78
+ width: var(--hy-input-search-button-width, 32px);
79
+ padding: 0;
80
+ place-items: center;
54
81
  border: 0;
55
- border-radius: 2px;
82
+ border-left: 1px solid var(--hy-border-color, #303746);
83
+ color: var(--hy-input-search-color, var(--hy-accent-color, #79a8ff));
84
+ background: var(--hy-input-search-bg, color-mix(in srgb, var(--hy-accent-color, #79a8ff) 11%, transparent));
85
+ cursor: pointer;
86
+ font: 16px/1 system-ui, sans-serif;
56
87
  }
88
+ .search-button:hover:not(:disabled) { background: var(--hy-input-search-hover-bg, color-mix(in srgb, var(--hy-accent-color, #79a8ff) 20%, transparent)); }
89
+ .search-button:focus-visible { outline: 2px solid var(--hy-focus-border-color, #3d6fa8); outline-offset: -3px; }
90
+ .search-button:disabled { cursor: default; }
91
+ @media (prefers-reduced-motion: reduce) { .control { transition: none; } }
57
92
  `;
58
- root.append(style, this._input);
93
+ this._control.className = 'control';
94
+ this._control.part.add('control');
95
+ this._prefix.className = 'affix prefix';
96
+ this._prefix.part.add('prefix');
97
+ this._prefixSlot.name = 'prefix';
98
+ this._prefixText.className = 'affix-text';
99
+ this._prefix.append(this._prefixSlot, this._prefixText);
100
+ this._input.part.add('input');
101
+ this._suffix.className = 'affix suffix';
102
+ this._suffix.part.add('suffix');
103
+ this._suffixSlot.name = 'suffix';
104
+ this._suffixText.className = 'affix-text';
105
+ this._suffix.append(this._suffixSlot, this._suffixText);
106
+ this._searchButton.className = 'search-button';
107
+ this._searchButton.type = 'button';
108
+ this._searchButton.part.add('search-button');
109
+ this._searchButton.textContent = '⌕';
110
+ this._control.append(this._prefix, this._input, this._suffix, this._searchButton);
111
+ root.append(style, this._control);
59
112
  }
60
113
  connectedCallback() {
61
114
  this._input.addEventListener('input', this._onInput);
62
115
  this._input.addEventListener('change', this._onChange);
116
+ this._input.addEventListener('keydown', this._onKeydown);
117
+ this._searchButton.addEventListener('click', this._onSearchClick);
118
+ this._prefixSlot.addEventListener('slotchange', this._onSlotChange);
119
+ this._suffixSlot.addEventListener('slotchange', this._onSlotChange);
63
120
  this._sync();
64
121
  }
65
122
  disconnectedCallback() {
66
123
  this._input.removeEventListener('input', this._onInput);
67
124
  this._input.removeEventListener('change', this._onChange);
125
+ this._input.removeEventListener('keydown', this._onKeydown);
126
+ this._searchButton.removeEventListener('click', this._onSearchClick);
127
+ this._prefixSlot.removeEventListener('slotchange', this._onSlotChange);
128
+ this._suffixSlot.removeEventListener('slotchange', this._onSlotChange);
68
129
  }
69
- attributeChangedCallback() {
70
- this._sync();
71
- }
130
+ attributeChangedCallback() { this._sync(); }
72
131
  get type() { return normalizedType(this.getAttribute('type')); }
73
132
  set type(value) { this.setAttribute('type', normalizedType(value)); }
74
133
  get value() { return this.getAttribute('value') ?? ''; }
75
134
  set value(value) {
76
- this.setAttribute('value', String(value));
77
- this._input.value = String(value);
78
- }
79
- get valueAsNumber() {
80
- return this._input.valueAsNumber;
135
+ const text = String(value);
136
+ if (this.getAttribute('value') !== text)
137
+ this.setAttribute('value', text);
138
+ if (this._input.value !== text)
139
+ this._input.value = text;
140
+ this._syncValidity();
81
141
  }
142
+ get valueAsNumber() { return this._input.valueAsNumber; }
143
+ get prefix() { return this.getAttribute('prefix') ?? ''; }
144
+ set prefix(value) { this._setOptionalAttribute('prefix', value); }
145
+ get suffix() { return this.getAttribute('suffix') ?? ''; }
146
+ set suffix(value) { this._setOptionalAttribute('suffix', value); }
147
+ get searchLabel() { return this.getAttribute('search-label')?.trim() || 'Search'; }
148
+ set searchLabel(value) { this._setOptionalAttribute('search-label', value); }
82
149
  get disabled() { return this.hasAttribute('disabled'); }
83
150
  set disabled(value) { this.toggleAttribute('disabled', value); }
84
151
  get readOnly() { return this.hasAttribute('readonly'); }
@@ -86,46 +153,91 @@ export class HYInput extends HTMLElement {
86
153
  get valid() { return this._input.validity.valid; }
87
154
  focus(options) { this._input.focus(options); }
88
155
  select() { this._input.select(); }
156
+ search() { return this._emitSearch('api'); }
89
157
  _sync() {
90
158
  const type = this.type;
91
159
  if (this._input.type !== type)
92
160
  this._input.type = type;
93
161
  const value = this.value;
94
162
  if (this._input.value !== value)
95
- this._input.value = type === 'color' && !/^#[0-9a-f]{6}$/iu.test(value)
96
- ? '#000000'
97
- : value;
163
+ this._input.value = type === 'color' && !/^#[0-9a-f]{6}$/iu.test(value) ? '#000000' : value;
98
164
  for (const name of ['min', 'max', 'step', 'placeholder', 'name', 'autocomplete', 'aria-label', 'title']) {
99
165
  const attribute = this.getAttribute(name);
100
- if (attribute === null)
101
- this._input.removeAttribute(name);
102
- else
166
+ if (attribute === null) {
167
+ if (this._input.hasAttribute(name))
168
+ this._input.removeAttribute(name);
169
+ }
170
+ else if (this._input.getAttribute(name) !== attribute)
103
171
  this._input.setAttribute(name, attribute);
104
172
  }
105
- this._input.disabled = this.disabled;
106
- this._input.readOnly = this.readOnly;
107
- this._input.required = this.hasAttribute('required');
173
+ // Reassigning even an unchanged placeholder or state can split Chromium's undo group.
174
+ if (this._input.disabled !== this.disabled)
175
+ this._input.disabled = this.disabled;
176
+ if (this._input.readOnly !== this.readOnly)
177
+ this._input.readOnly = this.readOnly;
178
+ if (this._input.required !== this.hasAttribute('required'))
179
+ this._input.required = this.hasAttribute('required');
180
+ this._searchButton.hidden = type !== 'search';
181
+ this._searchButton.disabled = this.disabled;
182
+ this._searchButton.setAttribute('aria-label', this.searchLabel);
183
+ this._control.classList.toggle('disabled', this.disabled);
184
+ this._control.classList.toggle('readonly', this.readOnly);
185
+ this._syncAffixes();
186
+ this._syncValidity();
108
187
  }
188
+ _syncAffixes() {
189
+ this._syncAffix(this._prefix, this._prefixSlot, this._prefixText, this.prefix);
190
+ this._syncAffix(this._suffix, this._suffixSlot, this._suffixText, this.suffix);
191
+ }
192
+ _syncAffix(container, slot, fallback, text) {
193
+ const hasAssignedContent = slot.assignedNodes({ flatten: true }).some(node => node.nodeType === Node.ELEMENT_NODE || Boolean(node.textContent?.trim()));
194
+ fallback.textContent = hasAssignedContent ? '' : text;
195
+ fallback.hidden = hasAssignedContent || !text;
196
+ container.hidden = !hasAssignedContent && !text;
197
+ }
198
+ _syncValidity() { this._control.classList.toggle('invalid', !this.valid); }
199
+ _setOptionalAttribute(name, value) {
200
+ const normalized = String(value ?? '').trim();
201
+ if (normalized)
202
+ this.setAttribute(name, normalized);
203
+ else
204
+ this.removeAttribute(name);
205
+ }
206
+ _onSlotChange = () => { this._syncAffixes(); };
109
207
  _onInput = () => {
110
208
  this.setAttribute('value', this._input.value);
209
+ this._syncValidity();
111
210
  };
112
211
  _onChange = () => {
113
212
  this.setAttribute('value', this._input.value);
114
- const number = this.type === 'number' && Number.isFinite(this._input.valueAsNumber)
115
- ? this._input.valueAsNumber
116
- : null;
213
+ const number = this.type === 'number' && Number.isFinite(this._input.valueAsNumber) ? this._input.valueAsNumber : null;
117
214
  this.dispatchEvent(new CustomEvent('value-change', {
118
215
  detail: { value: this._input.value, valueAsNumber: number, valid: this.valid },
119
216
  bubbles: true,
120
217
  composed: true,
121
218
  }));
122
219
  };
220
+ _onKeydown = (event) => {
221
+ if (event.key === 'Enter' && this.type === 'search' && !event.isComposing)
222
+ this._emitSearch('enter');
223
+ };
224
+ _onSearchClick = () => { this._emitSearch('button'); };
225
+ _emitSearch(source) {
226
+ if (this.disabled || this.type !== 'search')
227
+ return false;
228
+ return this.dispatchEvent(new CustomEvent('search', {
229
+ detail: { value: this._input.value, valid: this.valid, source },
230
+ bubbles: true,
231
+ composed: true,
232
+ cancelable: true,
233
+ }));
234
+ }
123
235
  }
124
236
  export function defineInputComponents() {
125
237
  if (!customElements.get('hy-input'))
126
238
  customElements.define('hy-input', HYInput);
127
239
  }
128
240
  function normalizedType(value) {
129
- return value === 'number' || value === 'color' ? value : 'text';
241
+ return value === 'number' || value === 'color' || value === 'search' || value === 'password' ? value : 'text';
130
242
  }
131
243
  //# sourceMappingURL=input.js.map
@@ -0,0 +1,94 @@
1
+ declare namespace qrcodegen {
2
+ type bit = number;
3
+ type byte = number;
4
+ type int = number;
5
+ export class QrCode {
6
+ readonly version: int;
7
+ readonly errorCorrectionLevel: QrCode.Ecc;
8
+ static encodeText(text: string, ecl: QrCode.Ecc): QrCode;
9
+ static encodeBinary(data: Readonly<Array<byte>>, ecl: QrCode.Ecc): QrCode;
10
+ static encodeSegments(segs: Readonly<Array<QrSegment>>, ecl: QrCode.Ecc, minVersion?: int, maxVersion?: int, mask?: int, boostEcl?: boolean): QrCode;
11
+ readonly size: int;
12
+ readonly mask: int;
13
+ private readonly modules;
14
+ private readonly isFunction;
15
+ constructor(version: int, errorCorrectionLevel: QrCode.Ecc, dataCodewords: Readonly<Array<byte>>, msk: int);
16
+ getModule(x: int, y: int): boolean;
17
+ private drawFunctionPatterns;
18
+ private drawFormatBits;
19
+ private drawVersion;
20
+ private drawFinderPattern;
21
+ private drawAlignmentPattern;
22
+ private setFunctionModule;
23
+ private addEccAndInterleave;
24
+ private drawCodewords;
25
+ private applyMask;
26
+ private getPenaltyScore;
27
+ private getAlignmentPatternPositions;
28
+ private static getNumRawDataModules;
29
+ private static getNumDataCodewords;
30
+ private static reedSolomonComputeDivisor;
31
+ private static reedSolomonComputeRemainder;
32
+ private static reedSolomonMultiply;
33
+ private finderPenaltyCountPatterns;
34
+ private finderPenaltyTerminateAndCount;
35
+ private finderPenaltyAddHistory;
36
+ static readonly MIN_VERSION: int;
37
+ static readonly MAX_VERSION: int;
38
+ private static readonly PENALTY_N1;
39
+ private static readonly PENALTY_N2;
40
+ private static readonly PENALTY_N3;
41
+ private static readonly PENALTY_N4;
42
+ private static readonly ECC_CODEWORDS_PER_BLOCK;
43
+ private static readonly NUM_ERROR_CORRECTION_BLOCKS;
44
+ }
45
+ export class QrSegment {
46
+ readonly mode: QrSegment.Mode;
47
+ readonly numChars: int;
48
+ private readonly bitData;
49
+ static makeBytes(data: Readonly<Array<byte>>): QrSegment;
50
+ static makeNumeric(digits: string): QrSegment;
51
+ static makeAlphanumeric(text: string): QrSegment;
52
+ static makeSegments(text: string): Array<QrSegment>;
53
+ static makeEci(assignVal: int): QrSegment;
54
+ static isNumeric(text: string): boolean;
55
+ static isAlphanumeric(text: string): boolean;
56
+ constructor(mode: QrSegment.Mode, numChars: int, bitData: Array<bit>);
57
+ getData(): Array<bit>;
58
+ static getTotalBits(segs: Readonly<Array<QrSegment>>, version: int): number;
59
+ private static toUtf8ByteArray;
60
+ private static readonly NUMERIC_REGEX;
61
+ private static readonly ALPHANUMERIC_REGEX;
62
+ private static readonly ALPHANUMERIC_CHARSET;
63
+ }
64
+ export {};
65
+ }
66
+ declare namespace qrcodegen.QrCode {
67
+ type int = number;
68
+ export class Ecc {
69
+ readonly ordinal: int;
70
+ readonly formatBits: int;
71
+ static readonly LOW: Ecc;
72
+ static readonly MEDIUM: Ecc;
73
+ static readonly QUARTILE: Ecc;
74
+ static readonly HIGH: Ecc;
75
+ private constructor();
76
+ }
77
+ export {};
78
+ }
79
+ declare namespace qrcodegen.QrSegment {
80
+ type int = number;
81
+ export class Mode {
82
+ readonly modeBits: int;
83
+ private readonly numBitsCharCount;
84
+ static readonly NUMERIC: Mode;
85
+ static readonly ALPHANUMERIC: Mode;
86
+ static readonly BYTE: Mode;
87
+ static readonly KANJI: Mode;
88
+ static readonly ECI: Mode;
89
+ private constructor();
90
+ numCharCountBits(ver: int): int;
91
+ }
92
+ export {};
93
+ }
94
+ export { qrcodegen };