@haiyue/ui 0.2.1 → 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.
package/dist/collapse.js CHANGED
@@ -18,8 +18,16 @@ export class HYCollapse extends HTMLElement {
18
18
  _itemsAssigned = false;
19
19
  _activeKeys = [];
20
20
  _panels = new Map();
21
+ _motion = window.matchMedia('(prefers-reduced-motion: reduce)');
22
+ _resizeObserver = new ResizeObserver(() => {
23
+ for (const panel of this._panels.values()) {
24
+ if (panel.animation && panel.expanded && panel.targetHeight !== panel.body.offsetHeight) {
25
+ this._transition(panel, Number.parseFloat(getComputedStyle(panel.region).height), this._duration());
26
+ }
27
+ }
28
+ });
21
29
  static get observedAttributes() {
22
- return ['items', 'active-keys', 'default-active-keys', 'accordion', 'bordered', 'ghost', 'icon-position', 'collapsible', 'destroy-on-hidden', 'aria-label'];
30
+ return ['items', 'active-keys', 'default-active-keys', 'accordion', 'bordered', 'ghost', 'icon-position', 'collapsible', 'destroy-on-hidden', 'animated', 'animation-duration', 'aria-label'];
23
31
  }
24
32
  constructor() {
25
33
  super();
@@ -34,7 +42,7 @@ export class HYCollapse extends HTMLElement {
34
42
  .trigger:hover:not(:disabled) { background: var(--hy-hover-bg-color, #273241); }
35
43
  .trigger:focus-visible { position: relative; z-index: 1; outline: 2px solid var(--hy-focus-border-color, #79a8ff); outline-offset: -2px; }
36
44
  .trigger:disabled { color: var(--hy-muted-color, #788697); cursor: not-allowed; }
37
- .arrow { display: grid; width: 16px; height: 16px; flex: 0 0 auto; place-items: center; color: var(--hy-muted-color, #788697); transition: transform 160ms ease; }
45
+ .arrow { display: grid; width: 16px; height: 16px; flex: 0 0 auto; place-items: center; color: var(--hy-muted-color, #788697); transition: transform var(--hy-collapse-animation-duration, 200ms) var(--hy-collapse-animation-easing, ease); }
38
46
  .arrow::before { content: ''; width: 6px; height: 6px; border-block-start: 1.5px solid currentColor; border-inline-end: 1.5px solid currentColor; transform: rotate(45deg); }
39
47
  .panel.expanded .arrow { transform: rotate(90deg); }
40
48
  .title { min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@@ -54,6 +62,7 @@ export class HYCollapse extends HTMLElement {
54
62
  root.append(style, this._container);
55
63
  }
56
64
  connectedCallback() {
65
+ this._motion.addEventListener('change', this._onMotionChange);
57
66
  if (!this._itemsAssigned && this.hasAttribute('items'))
58
67
  this._readItemsAttribute();
59
68
  this._activeKeys = this.hasAttribute('active-keys') ? parseKeys(this.getAttribute('active-keys')) : parseKeys(this.getAttribute('default-active-keys'));
@@ -61,6 +70,12 @@ export class HYCollapse extends HTMLElement {
61
70
  this._syncItems();
62
71
  this._syncLabel();
63
72
  }
73
+ disconnectedCallback() {
74
+ this._motion.removeEventListener('change', this._onMotionChange);
75
+ this._resizeObserver.disconnect();
76
+ for (const panel of this._panels.values())
77
+ this._finishTransition(panel);
78
+ }
64
79
  attributeChangedCallback(name, oldValue, newValue) {
65
80
  if (oldValue === newValue)
66
81
  return;
@@ -120,6 +135,18 @@ export class HYCollapse extends HTMLElement {
120
135
  set collapsible(value) { this.setAttribute('collapsible', value === 'icon' || value === 'disabled' ? value : 'header'); }
121
136
  get destroyOnHidden() { return this.hasAttribute('destroy-on-hidden'); }
122
137
  set destroyOnHidden(value) { this.toggleAttribute('destroy-on-hidden', Boolean(value)); }
138
+ /** Opt-in height and arrow transitions. Initial rendering is always immediate. */
139
+ get animated() { return this.hasAttribute('animated') && this.getAttribute('animated') !== 'false'; }
140
+ set animated(value) { if (value)
141
+ this.setAttribute('animated', '');
142
+ else
143
+ this.removeAttribute('animated'); }
144
+ /** Milliseconds; zero disables animation. Defaults to 200 (or the inherited duration token). */
145
+ get animationDuration() {
146
+ const value = Number(this.getAttribute('animation-duration') ?? 200);
147
+ return Number.isFinite(value) ? Math.max(0, Math.min(10_000, value)) : 200;
148
+ }
149
+ set animationDuration(value) { this.setAttribute('animation-duration', String(Number.isFinite(value) ? Math.max(0, Math.min(10_000, value)) : 200)); }
123
150
  toggle(key, expanded) {
124
151
  const normalized = String(key);
125
152
  const panel = this._panels.get(normalized);
@@ -153,6 +180,9 @@ export class HYCollapse extends HTMLElement {
153
180
  _syncItems() {
154
181
  if (!this.isConnected)
155
182
  return;
183
+ this._resizeObserver.disconnect();
184
+ for (const panel of this._panels.values())
185
+ this._finishTransition(panel);
156
186
  this._panels.clear();
157
187
  const sections = [];
158
188
  this._items.forEach((item, index) => {
@@ -197,9 +227,10 @@ export class HYCollapse extends HTMLElement {
197
227
  body.part.add('body');
198
228
  region.append(body);
199
229
  section.append(header, region);
200
- const record = { item, section, button, arrow, region, body, rendered: false };
230
+ const record = { item, section, button, arrow, region, body, rendered: false, expanded: null, animation: null, targetHeight: 0 };
201
231
  this._panels.set(item.key, record);
202
232
  sections.push(section);
233
+ this._resizeObserver.observe(body, { box: 'border-box' });
203
234
  button.addEventListener('click', event => { if (this.collapsible === 'icon' && event.detail !== 0 && !event.composedPath()[0]?.closest?.('.arrow'))
204
235
  return; this.toggle(item.key); });
205
236
  });
@@ -209,6 +240,7 @@ export class HYCollapse extends HTMLElement {
209
240
  _syncExpanded() {
210
241
  if (!this.isConnected)
211
242
  return;
243
+ const duration = this._duration();
212
244
  for (const [key, panel] of this._panels) {
213
245
  const expanded = this._activeKeys.includes(key);
214
246
  const disabled = Boolean(panel.item.disabled) || this.collapsible === 'disabled';
@@ -216,15 +248,70 @@ export class HYCollapse extends HTMLElement {
216
248
  panel.section.toggleAttribute('data-disabled', disabled);
217
249
  panel.button.disabled = disabled;
218
250
  panel.button.setAttribute('aria-expanded', String(expanded));
219
- panel.region.hidden = !expanded;
251
+ panel.arrow.style.transitionDuration = `${duration}ms`;
252
+ if (!expanded && panel.region.matches(':focus-within'))
253
+ panel.button.focus({ preventScroll: true });
254
+ panel.region.inert = !expanded;
255
+ panel.region.setAttribute('aria-hidden', String(!expanded));
220
256
  if (expanded && !panel.rendered)
221
257
  this._renderContent(panel);
222
- else if (!expanded && this.destroyOnHidden && panel.rendered) {
223
- panel.body.replaceChildren();
224
- panel.rendered = false;
258
+ if (panel.expanded !== expanded) {
259
+ const from = panel.animation ? Number.parseFloat(getComputedStyle(panel.region).height) : expanded ? 0 : panel.region.offsetHeight;
260
+ const animate = panel.expanded !== null && duration > 0;
261
+ panel.expanded = expanded;
262
+ if (animate)
263
+ this._transition(panel, from, duration);
264
+ else
265
+ this._finishTransition(panel);
225
266
  }
267
+ else if (!panel.animation || duration === 0)
268
+ this._finishTransition(panel);
269
+ }
270
+ }
271
+ _duration() {
272
+ if (!this.animated || this._motion.matches)
273
+ return 0;
274
+ if (this.hasAttribute('animation-duration'))
275
+ return this.animationDuration;
276
+ const token = getComputedStyle(this).getPropertyValue('--hy-collapse-animation-duration').trim();
277
+ if (!token)
278
+ return 200;
279
+ const value = Number.parseFloat(token) * (token.endsWith('ms') ? 1 : 1000);
280
+ return Number.isFinite(value) ? Math.max(0, Math.min(10_000, value)) : 200;
281
+ }
282
+ _transition(panel, from, duration) {
283
+ if (!Number.isFinite(from))
284
+ from = 0;
285
+ panel.animation?.cancel();
286
+ panel.animation = null;
287
+ panel.region.hidden = false;
288
+ const to = panel.expanded ? panel.body.offsetHeight : 0;
289
+ panel.targetHeight = to;
290
+ if (!duration || from === to) {
291
+ this._finishTransition(panel);
292
+ return;
293
+ }
294
+ panel.region.style.overflow = 'hidden';
295
+ const token = getComputedStyle(this).getPropertyValue('--hy-collapse-animation-easing').trim() || 'ease';
296
+ const easing = CSS.supports('transition-timing-function', token) ? token : 'ease';
297
+ const animation = panel.region.animate([{ height: `${from}px` }, { height: `${to}px` }], { duration, easing, fill: 'both' });
298
+ panel.animation = animation;
299
+ void animation.finished.then(() => {
300
+ if (panel.animation === animation)
301
+ this._finishTransition(panel);
302
+ }, () => { });
303
+ }
304
+ _finishTransition(panel) {
305
+ panel.animation?.cancel();
306
+ panel.animation = null;
307
+ panel.region.style.removeProperty('overflow');
308
+ panel.region.hidden = !panel.expanded;
309
+ if (!panel.expanded && this.destroyOnHidden && panel.rendered) {
310
+ panel.body.replaceChildren();
311
+ panel.rendered = false;
226
312
  }
227
313
  }
314
+ _onMotionChange = () => { this._syncExpanded(); };
228
315
  _renderContent(panel) {
229
316
  const source = typeof panel.item.content === 'function' ? panel.item.content() : panel.item.content;
230
317
  if (source instanceof Node)
@@ -68,6 +68,14 @@ export interface HYAccessibility {
68
68
  readonly error?: string;
69
69
  readonly role?: 'button' | 'text' | 'textbox' | 'checkbox' | 'tab' | 'dialog' | 'image' | 'slider' | 'list' | 'tree';
70
70
  }
71
+ export type HYIconName = 'save' | 'export' | 'play' | 'pause' | 'reset' | 'step' | 'settings' | 'back' | 'chevronDown' | 'check' | 'close' | 'add';
72
+ export type HYButtonVariant = 'primary' | 'secondary' | 'quiet' | 'danger';
73
+ export type HYTextStyle = 'title' | 'body' | 'caption';
74
+ export interface HYTypography {
75
+ readonly fontSize: number;
76
+ readonly lineHeight: number;
77
+ readonly weight?: 'normal' | 'medium' | 'bold';
78
+ }
71
79
  export interface HYCommonProps {
72
80
  readonly layout?: HYLayout;
73
81
  readonly a11y?: HYAccessibility;
@@ -95,6 +103,8 @@ export interface HYComponentProps {
95
103
  Text: HYCommonProps & {
96
104
  readonly text: string;
97
105
  readonly wrap?: boolean;
106
+ readonly textStyle?: HYTextStyle;
107
+ readonly tone?: 'default' | 'muted' | 'danger';
98
108
  };
99
109
  Image: HYCommonProps & {
100
110
  readonly resource: HYResource;
@@ -108,6 +118,9 @@ export interface HYComponentProps {
108
118
  readonly text: string;
109
119
  readonly disabled?: boolean;
110
120
  readonly busy?: boolean;
121
+ readonly icon?: HYIconName;
122
+ readonly variant?: HYButtonVariant;
123
+ readonly size?: 'regular' | 'compact';
111
124
  };
112
125
  Checkbox: HYCommonProps & {
113
126
  readonly checked: boolean;
@@ -131,8 +144,12 @@ export interface HYComponentProps {
131
144
  readonly checked: boolean;
132
145
  readonly disabled?: boolean;
133
146
  };
134
- Select: HYCommonProps & HYSelectionProps;
135
- Tabs: HYCommonProps & HYSelectionProps;
147
+ Select: HYCommonProps & HYSelectionProps & {
148
+ readonly presentation?: 'auto' | 'popover' | 'sheet';
149
+ };
150
+ Tabs: HYCommonProps & HYSelectionProps & {
151
+ readonly variant?: 'underline' | 'segmented';
152
+ };
136
153
  TextInput: HYCommonProps & HYTextProps;
137
154
  TextArea: HYCommonProps & Omit<HYTextProps, 'secure'>;
138
155
  Slider: HYCommonProps & {
@@ -149,6 +166,7 @@ export interface HYComponentProps {
149
166
  };
150
167
  FormGroup: HYCommonProps & {
151
168
  readonly label: string;
169
+ readonly description?: string;
152
170
  readonly error?: string;
153
171
  };
154
172
  PlatformView: HYCommonProps & {
@@ -222,11 +240,12 @@ export interface HYPlatformView {
222
240
  dispose(): void;
223
241
  }
224
242
  export interface HYTheme {
225
- readonly color: Readonly<Record<'text' | 'muted' | 'surface' | 'input' | 'accent' | 'danger' | 'border' | 'focus', string>>;
243
+ readonly color: Readonly<Record<'text' | 'muted' | 'surface' | 'input' | 'accent' | 'danger' | 'border' | 'focus', string> & Partial<Record<'selected' | 'pressed' | 'disabled' | 'elevated' | 'onAccent', string>>>;
226
244
  readonly fontSize: number;
227
245
  readonly lineHeight: number;
228
246
  readonly gap: number;
229
247
  readonly radius: number;
248
+ readonly typography?: Readonly<Partial<Record<HYTextStyle, HYTypography>>>;
230
249
  }
231
250
  export interface HYSourceLocation {
232
251
  readonly file: string;
@@ -80,20 +80,20 @@ const text = { value: string, disabled: boolean, readOnly: boolean, placeholder:
80
80
  const schemas = {
81
81
  Row: shape(common), Column: shape(common), Grid: shape(common), Overlay: shape(common),
82
82
  Scroll: shape({ ...common, axis: choice('horizontal', 'vertical') }, ['axis']),
83
- Text: shape({ ...common, text: string, wrap: boolean }, ['text']),
83
+ Text: shape({ ...common, text: string, wrap: boolean, textStyle: choice('title', 'body', 'caption'), tone: choice('default', 'muted', 'danger') }, ['text']),
84
84
  Image: shape({ ...common, resource, fit: choice('contain', 'cover') }, ['resource']),
85
85
  Icon: shape({ ...common, resource, systemName: name }, ['resource']),
86
- Button: shape({ ...common, text: string, disabled: boolean, busy: boolean }, ['text']),
86
+ Button: shape({ ...common, text: string, disabled: boolean, busy: boolean, icon: choice('save', 'export', 'play', 'pause', 'reset', 'step', 'settings', 'back', 'chevronDown', 'check', 'close', 'add'), variant: choice('primary', 'secondary', 'quiet', 'danger'), size: choice('regular', 'compact') }, ['text']),
87
87
  Checkbox: shape({ ...common, checked: boolean, disabled: boolean, text: string }, ['checked', 'text']),
88
88
  RadioGroup: shape({ ...common, ...selection }, ['value', 'options']),
89
89
  Rate: shape({ ...common, value: integer, count: check(v => Number.isInteger(v) && v >= 1 && v <= 10, 'Expected count 1–10'), disabled: boolean, readOnly: boolean }, ['value', 'count']),
90
90
  Badge: shape({ ...common, text: string }, ['text']), Divider: shape({ ...common, text: string }),
91
91
  Toggle: shape({ ...common, checked: boolean, disabled: boolean }, ['checked']),
92
- Select: shape({ ...common, ...selection }, ['value', 'options']), Tabs: shape({ ...common, ...selection }, ['value', 'options']),
92
+ Select: shape({ ...common, ...selection, presentation: choice('auto', 'popover', 'sheet') }, ['value', 'options']), Tabs: shape({ ...common, ...selection, variant: choice('underline', 'segmented') }, ['value', 'options']),
93
93
  TextInput: shape({ ...common, ...text, secure: boolean }, ['value']), TextArea: shape({ ...common, ...text }, ['value']),
94
94
  Slider: shape({ ...common, value: number, min: number, max: number, step: positive, disabled: boolean }, ['value', 'min', 'max', 'step']),
95
95
  Dialog: shape({ ...common, open: boolean, title: string, dismissible: boolean }, ['open', 'title']),
96
- FormGroup: shape({ ...common, label: string, error: string }, ['label']),
96
+ FormGroup: shape({ ...common, label: string, description: string, error: string }, ['label']),
97
97
  PlatformView: shape({ ...common, slot: name, resourceId: name }, ['slot', 'resourceId']),
98
98
  };
99
99
  export const HY_COMPONENTS = Object.freeze(Object.keys(schemas));
@@ -140,6 +140,11 @@ export function hyValidateProps(kind, props, context = {}, capabilities) {
140
140
  if (!p.options.some(o => o.value === p.value))
141
141
  fail('Unknown controlled value', field(context, 'value'));
142
142
  }
143
+ if (kind === 'Button') {
144
+ const p = props;
145
+ if (p.icon && !p.text.trim() && !p.a11y?.label.trim())
146
+ fail('Icon-only button needs an accessible label', field(context, 'a11y.label'));
147
+ }
143
148
  if (kind === 'Rate' && props.value > props.count)
144
149
  fail('Rating exceeds count', context);
145
150
  if (kind === 'Slider') {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  export { defineExpandableComponents, HYExpandable } from './expandable.js';
2
2
  export type { HYExpandableButtonPosition, HYExpandableChangeDetail } from './expandable.js';
3
+ export { defineModalComponents, HYModal } from './modal.js';
4
+ export type { HYModalCloseReason, HYModalActionDetail, HYModalCloseDetail } from './modal.js';
5
+ export { defineQRCodeComponents, HYQRCode } from './qr-code.js';
6
+ export type { HYQRCodeErrorCorrectionLevel, HYQRCodeStatus, HYQRCodeRenderDetail, HYQRCodeErrorDetail, HYQRCodeIconErrorDetail } from './qr-code.js';
7
+ export { defineCarouselComponents, HYCarousel } from './carousel.js';
8
+ export type { HYCarouselDirection, HYCarouselIndicatorPosition, HYCarouselIndicatorStyle, HYCarouselChangeSource, HYCarouselChangeDetail, HYCarouselIndicatorRenderer } from './carousel.js';
9
+ export { defineMasonryComponents, HYMasonry } from './masonry.js';
10
+ export type { HYMasonryLayoutChangeDetail } from './masonry.js';
3
11
  export { defineButtonComponents, HYButton, } from './button.js';
4
12
  export type { HYButtonIconPosition } from './button.js';
5
13
  export { defineButtonGroupComponents, HYButtonGroup, } from './button-group.js';
package/dist/index.js CHANGED
@@ -4,6 +4,14 @@ import { defineButtonComponents } from './button.js';
4
4
  import { defineButtonGroupComponents } from './button-group.js';
5
5
  import { defineBorderBeamComponents } from './border-beam.js';
6
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';
7
15
  import { defineSplitComponents } from './split.js';
8
16
  import { defineSelectComponents } from './select.js';
9
17
  import { defineTabsComponents } from './tabs.js';
@@ -87,6 +95,10 @@ export function defineHaiyueUI() {
87
95
  defineButtonGroupComponents();
88
96
  defineTreeComponents();
89
97
  defineSplitComponents();
98
+ defineMasonryComponents();
99
+ defineCarouselComponents();
100
+ defineQRCodeComponents();
101
+ defineModalComponents();
90
102
  defineSelectComponents();
91
103
  defineTabsComponents();
92
104
  defineContextMenuComponents();
@@ -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 };