@aihu/primitives 0.0.11 → 0.1.0
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/README.md +14 -7
- package/dist/{button-C-8c-A17.js → button-Cha1gKlr.js} +2 -2
- package/dist/{button-C-8c-A17.js.map → button-Cha1gKlr.js.map} +1 -1
- package/dist/button.d.ts +1 -1
- package/dist/button.js +1 -1
- package/dist/checkbox.d.ts +45 -0
- package/dist/checkbox.d.ts.map +1 -0
- package/dist/checkbox.js +190 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/{dialog-y7MHc6vf.js → dialog-VDL-W3Vy.js} +17 -7
- package/dist/{dialog-y7MHc6vf.js.map → dialog-VDL-W3Vy.js.map} +1 -1
- package/dist/dialog.d.ts +1 -1
- package/dist/dialog.js +1 -1
- package/dist/form-control-B_BO9j7_.js +223 -0
- package/dist/form-control-B_BO9j7_.js.map +1 -0
- package/dist/form-control.d.ts +2 -41
- package/dist/form-control.js +2 -145
- package/dist/index-BvFa1Y-Z.d.ts +60 -0
- package/dist/index-BvFa1Y-Z.d.ts.map +1 -0
- package/dist/{index-D9kf9rVU.d.ts → index-D7hJLfnb.d.ts} +10 -3
- package/dist/{index-D9kf9rVU.d.ts.map → index-D7hJLfnb.d.ts.map} +1 -1
- package/dist/{index-DPD4L6Nj.d.ts → index-yPv3StRL.d.ts} +1 -1
- package/dist/{index-DPD4L6Nj.d.ts.map → index-yPv3StRL.d.ts.map} +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.js +12 -4
- package/dist/input.d.ts +13 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +42 -0
- package/dist/input.js.map +1 -0
- package/dist/label.d.ts +24 -0
- package/dist/label.d.ts.map +1 -0
- package/dist/label.js +136 -0
- package/dist/label.js.map +1 -0
- package/dist/radio-group.d.ts +82 -0
- package/dist/radio-group.d.ts.map +1 -0
- package/dist/radio-group.js +298 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/roving-focus.d.ts +4 -2
- package/dist/roving-focus.d.ts.map +1 -1
- package/dist/roving-focus.js +5 -3
- package/dist/roving-focus.js.map +1 -1
- package/dist/separator.d.ts +25 -0
- package/dist/separator.d.ts.map +1 -0
- package/dist/separator.js +85 -0
- package/dist/separator.js.map +1 -0
- package/dist/switch.d.ts +44 -0
- package/dist/switch.d.ts.map +1 -0
- package/dist/switch.js +176 -0
- package/dist/switch.js.map +1 -0
- package/dist/text-control-BBX7s8Oe.js +181 -0
- package/dist/text-control-BBX7s8Oe.js.map +1 -0
- package/dist/text-control-Brv5fUEX.d.ts +38 -0
- package/dist/text-control-Brv5fUEX.d.ts.map +1 -0
- package/dist/textarea.d.ts +13 -0
- package/dist/textarea.d.ts.map +1 -0
- package/dist/textarea.js +38 -0
- package/dist/textarea.js.map +1 -0
- package/dist/tooltip.d.ts +8 -2
- package/dist/tooltip.d.ts.map +1 -1
- package/dist/tooltip.js +15 -6
- package/dist/tooltip.js.map +1 -1
- package/package.json +33 -2
- package/dist/form-control.d.ts.map +0 -1
- package/dist/form-control.js.map +0 -1
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { createDomContext, provideContext } from "./dom-context.js";
|
|
2
|
+
import { effect, signal } from "@aihu/signals";
|
|
3
|
+
//#region src/form-control/hidden-input.ts
|
|
4
|
+
/**
|
|
5
|
+
* `attachHiddenInput` — form-association substrate for custom form controls
|
|
6
|
+
* (checkbox/switch/radio hosts). Mirrors a host's reactive state onto a
|
|
7
|
+
* visually-hidden native `<input>` in the host's LIGHT DOM so the value rides
|
|
8
|
+
* native `FormData` / form submission with zero re-implementation.
|
|
9
|
+
*
|
|
10
|
+
* The input only exists while BOTH conditions hold: the host is inside a
|
|
11
|
+
* `<form>` (`host.closest('form')`) AND `name()` is non-null. When `name()`
|
|
12
|
+
* becomes null the input is removed (reactively, inside the effect). The
|
|
13
|
+
* inline visually-hidden styles are behavioral plumbing on a functional
|
|
14
|
+
* element, not appearance — they do not violate the zero-CSS contract.
|
|
15
|
+
*
|
|
16
|
+
* The input is inserted as the host's NEXT SIBLING, not a child: hosts like
|
|
17
|
+
* checkbox/switch carry an interactive ARIA role (`role="checkbox"` etc.), and
|
|
18
|
+
* a nested native form control would be an `aria-hidden`-not-withstanding
|
|
19
|
+
* `nested-interactive` violation. Sibling placement keeps it in the same form
|
|
20
|
+
* (so `FormData` is unchanged) while staying out of the host's subtree. When
|
|
21
|
+
* the host has no parent yet (pre-insertion), it falls back to a child.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Attach a visually-hidden native input to `host`, kept in sync with the
|
|
25
|
+
* provided signals by a single effect. Returns a disposer that stops the
|
|
26
|
+
* effect and removes the input.
|
|
27
|
+
*/
|
|
28
|
+
function attachHiddenInput(host, opts) {
|
|
29
|
+
let input = null;
|
|
30
|
+
const remove = () => {
|
|
31
|
+
input?.remove();
|
|
32
|
+
input = null;
|
|
33
|
+
};
|
|
34
|
+
const stop = effect(() => {
|
|
35
|
+
const name = opts.name();
|
|
36
|
+
const value = opts.value();
|
|
37
|
+
const checked = opts.checked();
|
|
38
|
+
const required = opts.required();
|
|
39
|
+
const disabled = opts.disabled();
|
|
40
|
+
if (name === null || host.closest("form") === null) {
|
|
41
|
+
remove();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (input === null) {
|
|
45
|
+
input = document.createElement("input");
|
|
46
|
+
input.type = opts.type;
|
|
47
|
+
input.setAttribute("aria-hidden", "true");
|
|
48
|
+
input.setAttribute("tabindex", "-1");
|
|
49
|
+
input.style.position = "absolute";
|
|
50
|
+
input.style.opacity = "0";
|
|
51
|
+
input.style.pointerEvents = "none";
|
|
52
|
+
input.style.margin = "0";
|
|
53
|
+
input.style.transform = "translateX(-100%)";
|
|
54
|
+
if (host.parentNode !== null) host.after(input);
|
|
55
|
+
else host.appendChild(input);
|
|
56
|
+
}
|
|
57
|
+
input.name = name;
|
|
58
|
+
input.value = value;
|
|
59
|
+
input.checked = checked;
|
|
60
|
+
input.required = required;
|
|
61
|
+
input.disabled = disabled;
|
|
62
|
+
});
|
|
63
|
+
return () => {
|
|
64
|
+
stop();
|
|
65
|
+
remove();
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/form-control/index.ts
|
|
70
|
+
/**
|
|
71
|
+
* `<aihu-form-control>` — headless form-field coordinator. Owns the
|
|
72
|
+
* disabled/required/invalid state for a field and wires the ARIA association
|
|
73
|
+
* between a slotted control, its label, and its error/description text. Emits
|
|
74
|
+
* NO CSS.
|
|
75
|
+
*
|
|
76
|
+
* Reflected attributes: `disabled`, `required`, `invalid` (boolean); `name`,
|
|
77
|
+
* `control-id` (string).
|
|
78
|
+
* Owned signals: `disabled`, `required`, `invalid`.
|
|
79
|
+
* ARIA emitted onto the slotted control: `aria-required`, `aria-invalid`,
|
|
80
|
+
* `aria-disabled`, `aria-describedby` (wired to a slotted `[data-fc-description]`
|
|
81
|
+
* / `[data-fc-error]` element's id); a slotted `<label>` is associated via
|
|
82
|
+
* `for`/`id`.
|
|
83
|
+
* Context: provides `formControlContext` carrying
|
|
84
|
+
* `{ disabled, required, invalid, controlId, describedById, labelId }` signals
|
|
85
|
+
* so descendant pieces consume the shared state without prop-drilling.
|
|
86
|
+
*/
|
|
87
|
+
const formControlContext = createDomContext("form-control");
|
|
88
|
+
let _idCounter = 0;
|
|
89
|
+
function nextId() {
|
|
90
|
+
_idCounter += 1;
|
|
91
|
+
return `aihu-fc-${_idCounter}`;
|
|
92
|
+
}
|
|
93
|
+
var AihuFormControl = class extends HTMLElement {
|
|
94
|
+
static observedAttributes = [
|
|
95
|
+
"disabled",
|
|
96
|
+
"required",
|
|
97
|
+
"invalid",
|
|
98
|
+
"name",
|
|
99
|
+
"control-id"
|
|
100
|
+
];
|
|
101
|
+
_disabled = signal(false);
|
|
102
|
+
_required = signal(false);
|
|
103
|
+
_invalid = signal(false);
|
|
104
|
+
_controlId = signal("");
|
|
105
|
+
_describedById = signal(null);
|
|
106
|
+
_labelId = signal(null);
|
|
107
|
+
_disposers = [];
|
|
108
|
+
get disabled() {
|
|
109
|
+
return this._disabled[0];
|
|
110
|
+
}
|
|
111
|
+
get required() {
|
|
112
|
+
return this._required[0];
|
|
113
|
+
}
|
|
114
|
+
get invalid() {
|
|
115
|
+
return this._invalid[0];
|
|
116
|
+
}
|
|
117
|
+
get controlId() {
|
|
118
|
+
return this._controlId[0];
|
|
119
|
+
}
|
|
120
|
+
get labelId() {
|
|
121
|
+
return this._labelId[0];
|
|
122
|
+
}
|
|
123
|
+
constructor() {
|
|
124
|
+
super();
|
|
125
|
+
provideContext(this, formControlContext, {
|
|
126
|
+
disabled: this._disabled[0],
|
|
127
|
+
required: this._required[0],
|
|
128
|
+
invalid: this._invalid[0],
|
|
129
|
+
controlId: this._controlId[0],
|
|
130
|
+
describedById: this._describedById[0],
|
|
131
|
+
labelId: this._labelId[0]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
connectedCallback() {
|
|
135
|
+
const supplied = this.getAttribute("control-id");
|
|
136
|
+
this._controlId[1](supplied ?? nextId());
|
|
137
|
+
this._syncBooleans();
|
|
138
|
+
this._wireAssociations();
|
|
139
|
+
this._disposers.push(effect(() => {
|
|
140
|
+
const control = this._control();
|
|
141
|
+
if (!control) return;
|
|
142
|
+
reflectAria(control, "aria-disabled", this._disabled[0]());
|
|
143
|
+
reflectAria(control, "aria-required", this._required[0]());
|
|
144
|
+
reflectAria(control, "aria-invalid", this._invalid[0]());
|
|
145
|
+
const describedBy = this._describedById[0]();
|
|
146
|
+
if (describedBy) control.setAttribute("aria-describedby", describedBy);
|
|
147
|
+
else control.removeAttribute("aria-describedby");
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
disconnectedCallback() {
|
|
151
|
+
for (const d of this._disposers) d();
|
|
152
|
+
this._disposers = [];
|
|
153
|
+
}
|
|
154
|
+
attributeChangedCallback(name, _old, value) {
|
|
155
|
+
switch (name) {
|
|
156
|
+
case "disabled":
|
|
157
|
+
this._disabled[1](value !== null);
|
|
158
|
+
break;
|
|
159
|
+
case "required":
|
|
160
|
+
this._required[1](value !== null);
|
|
161
|
+
break;
|
|
162
|
+
case "invalid":
|
|
163
|
+
this._invalid[1](value !== null);
|
|
164
|
+
break;
|
|
165
|
+
case "control-id":
|
|
166
|
+
if (value) this._controlId[1](value);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/** Re-derive `aria-describedby` from the slotted description/error pieces.
|
|
171
|
+
* Call after a piece mounts/unmounts. */
|
|
172
|
+
recomputeDescribedBy() {
|
|
173
|
+
this._wireAssociations();
|
|
174
|
+
}
|
|
175
|
+
_syncBooleans() {
|
|
176
|
+
this._disabled[1](this.hasAttribute("disabled"));
|
|
177
|
+
this._required[1](this.hasAttribute("required"));
|
|
178
|
+
this._invalid[1](this.hasAttribute("invalid"));
|
|
179
|
+
}
|
|
180
|
+
/** The slotted control element (input/select/textarea/[data-fc-control]). */
|
|
181
|
+
_control() {
|
|
182
|
+
return this.querySelector("[data-fc-control], input, select, textarea, [role=\"textbox\"]");
|
|
183
|
+
}
|
|
184
|
+
_wireAssociations() {
|
|
185
|
+
const control = this._control();
|
|
186
|
+
if (control) if (!control.id) control.id = this._controlId[0]();
|
|
187
|
+
else this._controlId[1](control.id);
|
|
188
|
+
const label = this.querySelector("label, [data-fc-label]");
|
|
189
|
+
if (label && control) if (label instanceof HTMLLabelElement) {
|
|
190
|
+
label.htmlFor = control.id;
|
|
191
|
+
this._labelId[1](label.id || null);
|
|
192
|
+
} else {
|
|
193
|
+
label.setAttribute("for", control.id);
|
|
194
|
+
if (!label.id) label.id = nextId();
|
|
195
|
+
control.setAttribute("aria-labelledby", label.id);
|
|
196
|
+
this._labelId[1](label.id);
|
|
197
|
+
}
|
|
198
|
+
const described = [];
|
|
199
|
+
for (const el of this.querySelectorAll("[data-fc-description], [data-fc-error]")) {
|
|
200
|
+
if (!el.id) el.id = nextId();
|
|
201
|
+
described.push(el.id);
|
|
202
|
+
}
|
|
203
|
+
this._describedById[1](described.length ? described.join(" ") : null);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
function reflectAria(el, attr, on) {
|
|
207
|
+
if (on) el.setAttribute(attr, "true");
|
|
208
|
+
else el.removeAttribute(attr);
|
|
209
|
+
}
|
|
210
|
+
let _defined = false;
|
|
211
|
+
/** Register `<aihu-form-control>` (idempotent). */
|
|
212
|
+
function defineFormControl(tag = "aihu-form-control") {
|
|
213
|
+
if (_defined || customElements.get(tag)) {
|
|
214
|
+
_defined = true;
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
customElements.define(tag, AihuFormControl);
|
|
218
|
+
_defined = true;
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
export { attachHiddenInput as i, defineFormControl as n, formControlContext as r, AihuFormControl as t };
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=form-control-B_BO9j7_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"form-control-B_BO9j7_.js","names":[],"sources":["../src/form-control/hidden-input.ts","../src/form-control/index.ts"],"sourcesContent":["/**\n * `attachHiddenInput` — form-association substrate for custom form controls\n * (checkbox/switch/radio hosts). Mirrors a host's reactive state onto a\n * visually-hidden native `<input>` in the host's LIGHT DOM so the value rides\n * native `FormData` / form submission with zero re-implementation.\n *\n * The input only exists while BOTH conditions hold: the host is inside a\n * `<form>` (`host.closest('form')`) AND `name()` is non-null. When `name()`\n * becomes null the input is removed (reactively, inside the effect). The\n * inline visually-hidden styles are behavioral plumbing on a functional\n * element, not appearance — they do not violate the zero-CSS contract.\n *\n * The input is inserted as the host's NEXT SIBLING, not a child: hosts like\n * checkbox/switch carry an interactive ARIA role (`role=\"checkbox\"` etc.), and\n * a nested native form control would be an `aria-hidden`-not-withstanding\n * `nested-interactive` violation. Sibling placement keeps it in the same form\n * (so `FormData` is unchanged) while staying out of the host's subtree. When\n * the host has no parent yet (pre-insertion), it falls back to a child.\n */\n\nimport { effect, type Read } from '@aihu/signals'\n\nexport interface HiddenInputOptions {\n type: 'checkbox' | 'radio'\n name: Read<string | null>\n value: Read<string>\n checked: Read<boolean>\n required: Read<boolean>\n disabled: Read<boolean>\n}\n\n/**\n * Attach a visually-hidden native input to `host`, kept in sync with the\n * provided signals by a single effect. Returns a disposer that stops the\n * effect and removes the input.\n */\nexport function attachHiddenInput(host: HTMLElement, opts: HiddenInputOptions): () => void {\n let input: HTMLInputElement | null = null\n\n const remove = (): void => {\n input?.remove()\n input = null\n }\n\n const stop = effect(() => {\n // Read every signal unconditionally so the effect re-runs on any change\n // (including `name` flipping back from null).\n const name = opts.name()\n const value = opts.value()\n const checked = opts.checked()\n const required = opts.required()\n const disabled = opts.disabled()\n\n if (name === null || host.closest('form') === null) {\n remove()\n return\n }\n\n if (input === null) {\n input = document.createElement('input')\n input.type = opts.type\n input.setAttribute('aria-hidden', 'true')\n input.setAttribute('tabindex', '-1')\n // Visually hidden, but still form-associated. Behavior, not appearance.\n input.style.position = 'absolute'\n input.style.opacity = '0'\n input.style.pointerEvents = 'none'\n input.style.margin = '0'\n input.style.transform = 'translateX(-100%)'\n // Sibling-after-host (see header): avoids nested-interactive on roled\n // hosts. Fall back to a child if the host isn't inserted yet.\n if (host.parentNode !== null) host.after(input)\n else host.appendChild(input)\n }\n input.name = name\n input.value = value\n input.checked = checked\n input.required = required\n input.disabled = disabled\n })\n\n return () => {\n stop()\n remove()\n }\n}\n","/**\n * `<aihu-form-control>` — headless form-field coordinator. Owns the\n * disabled/required/invalid state for a field and wires the ARIA association\n * between a slotted control, its label, and its error/description text. Emits\n * NO CSS.\n *\n * Reflected attributes: `disabled`, `required`, `invalid` (boolean); `name`,\n * `control-id` (string).\n * Owned signals: `disabled`, `required`, `invalid`.\n * ARIA emitted onto the slotted control: `aria-required`, `aria-invalid`,\n * `aria-disabled`, `aria-describedby` (wired to a slotted `[data-fc-description]`\n * / `[data-fc-error]` element's id); a slotted `<label>` is associated via\n * `for`/`id`.\n * Context: provides `formControlContext` carrying\n * `{ disabled, required, invalid, controlId, describedById, labelId }` signals\n * so descendant pieces consume the shared state without prop-drilling.\n */\n\nimport { effect, type Read, signal } from '@aihu/signals'\nimport { createDomContext, provideContext } from '../dom-context.ts'\n\nexport { attachHiddenInput, type HiddenInputOptions } from './hidden-input.ts'\n\nexport interface FormControlContextValue {\n readonly disabled: Read<boolean>\n readonly required: Read<boolean>\n readonly invalid: Read<boolean>\n readonly controlId: Read<string>\n readonly describedById: Read<string | null>\n readonly labelId: Read<string | null>\n}\n\nexport const formControlContext = createDomContext<FormControlContextValue>('form-control')\n\nlet _idCounter = 0\nfunction nextId(): string {\n _idCounter += 1\n return `aihu-fc-${_idCounter}`\n}\n\nexport class AihuFormControl extends HTMLElement {\n static readonly observedAttributes = ['disabled', 'required', 'invalid', 'name', 'control-id']\n\n private readonly _disabled = signal(false)\n private readonly _required = signal(false)\n private readonly _invalid = signal(false)\n private readonly _controlId = signal('')\n private readonly _describedById = signal<string | null>(null)\n private readonly _labelId = signal<string | null>(null)\n\n private _disposers: Array<() => void> = []\n\n get disabled(): Read<boolean> {\n return this._disabled[0]\n }\n get required(): Read<boolean> {\n return this._required[0]\n }\n get invalid(): Read<boolean> {\n return this._invalid[0]\n }\n get controlId(): Read<string> {\n return this._controlId[0]\n }\n get labelId(): Read<string | null> {\n return this._labelId[0]\n }\n\n constructor() {\n super()\n provideContext(this, formControlContext, {\n disabled: this._disabled[0],\n required: this._required[0],\n invalid: this._invalid[0],\n controlId: this._controlId[0],\n describedById: this._describedById[0],\n labelId: this._labelId[0],\n })\n }\n\n connectedCallback(): void {\n // Stable control id (generated if not supplied).\n const supplied = this.getAttribute('control-id')\n this._controlId[1](supplied ?? nextId())\n\n this._syncBooleans()\n this._wireAssociations()\n\n // Reflect ARIA onto the slotted control reactively.\n this._disposers.push(\n effect(() => {\n const control = this._control()\n if (!control) return\n reflectAria(control, 'aria-disabled', this._disabled[0]())\n reflectAria(control, 'aria-required', this._required[0]())\n reflectAria(control, 'aria-invalid', this._invalid[0]())\n const describedBy = this._describedById[0]()\n if (describedBy) control.setAttribute('aria-describedby', describedBy)\n else control.removeAttribute('aria-describedby')\n }),\n )\n }\n\n disconnectedCallback(): void {\n for (const d of this._disposers) d()\n this._disposers = []\n }\n\n attributeChangedCallback(name: string, _old: string | null, value: string | null): void {\n switch (name) {\n case 'disabled':\n this._disabled[1](value !== null)\n break\n case 'required':\n this._required[1](value !== null)\n break\n case 'invalid':\n this._invalid[1](value !== null)\n break\n case 'control-id':\n if (value) this._controlId[1](value)\n break\n }\n }\n\n /** Re-derive `aria-describedby` from the slotted description/error pieces.\n * Call after a piece mounts/unmounts. */\n recomputeDescribedBy(): void {\n this._wireAssociations()\n }\n\n private _syncBooleans(): void {\n this._disabled[1](this.hasAttribute('disabled'))\n this._required[1](this.hasAttribute('required'))\n this._invalid[1](this.hasAttribute('invalid'))\n }\n\n /** The slotted control element (input/select/textarea/[data-fc-control]). */\n private _control(): HTMLElement | null {\n return this.querySelector<HTMLElement>(\n '[data-fc-control], input, select, textarea, [role=\"textbox\"]',\n )\n }\n\n private _wireAssociations(): void {\n const control = this._control()\n if (control) {\n if (!control.id) control.id = this._controlId[0]()\n else this._controlId[1](control.id)\n }\n\n // Associate a slotted label.\n const label = this.querySelector<HTMLElement>('label, [data-fc-label]')\n if (label && control) {\n if (label instanceof HTMLLabelElement) {\n label.htmlFor = control.id\n this._labelId[1](label.id || null)\n } else {\n // Non-native label ([data-fc-label]): `for` has no native semantics,\n // so associate via aria-labelledby pointing at the label's id.\n label.setAttribute('for', control.id)\n if (!label.id) label.id = nextId()\n control.setAttribute('aria-labelledby', label.id)\n this._labelId[1](label.id)\n }\n }\n\n // Collect description + error ids into aria-describedby.\n const described: string[] = []\n for (const el of this.querySelectorAll<HTMLElement>('[data-fc-description], [data-fc-error]')) {\n if (!el.id) el.id = nextId()\n described.push(el.id)\n }\n this._describedById[1](described.length ? described.join(' ') : null)\n }\n}\n\nfunction reflectAria(el: HTMLElement, attr: string, on: boolean): void {\n if (on) el.setAttribute(attr, 'true')\n else el.removeAttribute(attr)\n}\n\nlet _defined = false\n/** Register `<aihu-form-control>` (idempotent). */\nexport function defineFormControl(tag = 'aihu-form-control'): void {\n if (_defined || customElements.get(tag)) {\n _defined = true\n return\n }\n customElements.define(tag, AihuFormControl)\n _defined = true\n}\n"],"mappings":"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"}
|
package/dist/form-control.d.ts
CHANGED
|
@@ -1,41 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//#region src/form-control/index.d.ts
|
|
5
|
-
interface FormControlContextValue {
|
|
6
|
-
readonly disabled: Read<boolean>;
|
|
7
|
-
readonly required: Read<boolean>;
|
|
8
|
-
readonly invalid: Read<boolean>;
|
|
9
|
-
readonly controlId: Read<string>;
|
|
10
|
-
readonly describedById: Read<string | null>;
|
|
11
|
-
}
|
|
12
|
-
declare const formControlContext: DomContext<FormControlContextValue>;
|
|
13
|
-
declare class AihuFormControl extends HTMLElement {
|
|
14
|
-
static readonly observedAttributes: string[];
|
|
15
|
-
private readonly _disabled;
|
|
16
|
-
private readonly _required;
|
|
17
|
-
private readonly _invalid;
|
|
18
|
-
private readonly _controlId;
|
|
19
|
-
private readonly _describedById;
|
|
20
|
-
private _disposers;
|
|
21
|
-
get disabled(): Read<boolean>;
|
|
22
|
-
get required(): Read<boolean>;
|
|
23
|
-
get invalid(): Read<boolean>;
|
|
24
|
-
get controlId(): Read<string>;
|
|
25
|
-
constructor();
|
|
26
|
-
connectedCallback(): void;
|
|
27
|
-
disconnectedCallback(): void;
|
|
28
|
-
attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
|
|
29
|
-
/** Re-derive `aria-describedby` from the slotted description/error pieces.
|
|
30
|
-
* Call after a piece mounts/unmounts. */
|
|
31
|
-
recomputeDescribedBy(): void;
|
|
32
|
-
private _syncBooleans;
|
|
33
|
-
/** The slotted control element (input/select/textarea/[data-fc-control]). */
|
|
34
|
-
private _control;
|
|
35
|
-
private _wireAssociations;
|
|
36
|
-
}
|
|
37
|
-
/** Register `<aihu-form-control>` (idempotent). */
|
|
38
|
-
declare function defineFormControl(tag?: string): void;
|
|
39
|
-
//#endregion
|
|
40
|
-
export { AihuFormControl, FormControlContextValue, defineFormControl, formControlContext };
|
|
41
|
-
//# sourceMappingURL=form-control.d.ts.map
|
|
1
|
+
import { a as HiddenInputOptions, i as formControlContext, n as FormControlContextValue, o as attachHiddenInput, r as defineFormControl, t as AihuFormControl } from "./index-BvFa1Y-Z.js";
|
|
2
|
+
export { AihuFormControl, FormControlContextValue, HiddenInputOptions, attachHiddenInput, defineFormControl, formControlContext };
|
package/dist/form-control.js
CHANGED
|
@@ -1,145 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/form-control/index.ts
|
|
4
|
-
/**
|
|
5
|
-
* `<aihu-form-control>` — headless form-field coordinator. Owns the
|
|
6
|
-
* disabled/required/invalid state for a field and wires the ARIA association
|
|
7
|
-
* between a slotted control, its label, and its error/description text. Emits
|
|
8
|
-
* NO CSS.
|
|
9
|
-
*
|
|
10
|
-
* Reflected attributes: `disabled`, `required`, `invalid` (boolean); `name`,
|
|
11
|
-
* `control-id` (string).
|
|
12
|
-
* Owned signals: `disabled`, `required`, `invalid`.
|
|
13
|
-
* ARIA emitted onto the slotted control: `aria-required`, `aria-invalid`,
|
|
14
|
-
* `aria-disabled`, `aria-describedby` (wired to a slotted `[data-fc-description]`
|
|
15
|
-
* / `[data-fc-error]` element's id); a slotted `<label>` is associated via
|
|
16
|
-
* `for`/`id`.
|
|
17
|
-
* Context: provides `formControlContext` carrying
|
|
18
|
-
* `{ disabled, required, invalid, controlId, describedById }` signals so
|
|
19
|
-
* descendant pieces consume the shared state without prop-drilling.
|
|
20
|
-
*/
|
|
21
|
-
const formControlContext = createDomContext("form-control");
|
|
22
|
-
let _idCounter = 0;
|
|
23
|
-
function nextId() {
|
|
24
|
-
_idCounter += 1;
|
|
25
|
-
return `aihu-fc-${_idCounter}`;
|
|
26
|
-
}
|
|
27
|
-
var AihuFormControl = class extends HTMLElement {
|
|
28
|
-
static observedAttributes = [
|
|
29
|
-
"disabled",
|
|
30
|
-
"required",
|
|
31
|
-
"invalid",
|
|
32
|
-
"name",
|
|
33
|
-
"control-id"
|
|
34
|
-
];
|
|
35
|
-
_disabled = signal(false);
|
|
36
|
-
_required = signal(false);
|
|
37
|
-
_invalid = signal(false);
|
|
38
|
-
_controlId = signal("");
|
|
39
|
-
_describedById = signal(null);
|
|
40
|
-
_disposers = [];
|
|
41
|
-
get disabled() {
|
|
42
|
-
return this._disabled[0];
|
|
43
|
-
}
|
|
44
|
-
get required() {
|
|
45
|
-
return this._required[0];
|
|
46
|
-
}
|
|
47
|
-
get invalid() {
|
|
48
|
-
return this._invalid[0];
|
|
49
|
-
}
|
|
50
|
-
get controlId() {
|
|
51
|
-
return this._controlId[0];
|
|
52
|
-
}
|
|
53
|
-
constructor() {
|
|
54
|
-
super();
|
|
55
|
-
provideContext(this, formControlContext, {
|
|
56
|
-
disabled: this._disabled[0],
|
|
57
|
-
required: this._required[0],
|
|
58
|
-
invalid: this._invalid[0],
|
|
59
|
-
controlId: this._controlId[0],
|
|
60
|
-
describedById: this._describedById[0]
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
connectedCallback() {
|
|
64
|
-
const supplied = this.getAttribute("control-id");
|
|
65
|
-
this._controlId[1](supplied ?? nextId());
|
|
66
|
-
this._syncBooleans();
|
|
67
|
-
this._wireAssociations();
|
|
68
|
-
this._disposers.push(effect(() => {
|
|
69
|
-
const control = this._control();
|
|
70
|
-
if (!control) return;
|
|
71
|
-
reflectAria(control, "aria-disabled", this._disabled[0]());
|
|
72
|
-
reflectAria(control, "aria-required", this._required[0]());
|
|
73
|
-
reflectAria(control, "aria-invalid", this._invalid[0]());
|
|
74
|
-
const describedBy = this._describedById[0]();
|
|
75
|
-
if (describedBy) control.setAttribute("aria-describedby", describedBy);
|
|
76
|
-
else control.removeAttribute("aria-describedby");
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
disconnectedCallback() {
|
|
80
|
-
for (const d of this._disposers) d();
|
|
81
|
-
this._disposers = [];
|
|
82
|
-
}
|
|
83
|
-
attributeChangedCallback(name, _old, value) {
|
|
84
|
-
switch (name) {
|
|
85
|
-
case "disabled":
|
|
86
|
-
this._disabled[1](value !== null);
|
|
87
|
-
break;
|
|
88
|
-
case "required":
|
|
89
|
-
this._required[1](value !== null);
|
|
90
|
-
break;
|
|
91
|
-
case "invalid":
|
|
92
|
-
this._invalid[1](value !== null);
|
|
93
|
-
break;
|
|
94
|
-
case "control-id":
|
|
95
|
-
if (value) this._controlId[1](value);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/** Re-derive `aria-describedby` from the slotted description/error pieces.
|
|
100
|
-
* Call after a piece mounts/unmounts. */
|
|
101
|
-
recomputeDescribedBy() {
|
|
102
|
-
this._wireAssociations();
|
|
103
|
-
}
|
|
104
|
-
_syncBooleans() {
|
|
105
|
-
this._disabled[1](this.hasAttribute("disabled"));
|
|
106
|
-
this._required[1](this.hasAttribute("required"));
|
|
107
|
-
this._invalid[1](this.hasAttribute("invalid"));
|
|
108
|
-
}
|
|
109
|
-
/** The slotted control element (input/select/textarea/[data-fc-control]). */
|
|
110
|
-
_control() {
|
|
111
|
-
return this.querySelector("[data-fc-control], input, select, textarea, [role=\"textbox\"]");
|
|
112
|
-
}
|
|
113
|
-
_wireAssociations() {
|
|
114
|
-
const control = this._control();
|
|
115
|
-
if (control) if (!control.id) control.id = this._controlId[0]();
|
|
116
|
-
else this._controlId[1](control.id);
|
|
117
|
-
const label = this.querySelector("label, [data-fc-label]");
|
|
118
|
-
if (label && control) if (label instanceof HTMLLabelElement) label.htmlFor = control.id;
|
|
119
|
-
else label.setAttribute("for", control.id);
|
|
120
|
-
const described = [];
|
|
121
|
-
for (const el of this.querySelectorAll("[data-fc-description], [data-fc-error]")) {
|
|
122
|
-
if (!el.id) el.id = nextId();
|
|
123
|
-
described.push(el.id);
|
|
124
|
-
}
|
|
125
|
-
this._describedById[1](described.length ? described.join(" ") : null);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
function reflectAria(el, attr, on) {
|
|
129
|
-
if (on) el.setAttribute(attr, "true");
|
|
130
|
-
else el.removeAttribute(attr);
|
|
131
|
-
}
|
|
132
|
-
let _defined = false;
|
|
133
|
-
/** Register `<aihu-form-control>` (idempotent). */
|
|
134
|
-
function defineFormControl(tag = "aihu-form-control") {
|
|
135
|
-
if (_defined || customElements.get(tag)) {
|
|
136
|
-
_defined = true;
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
customElements.define(tag, AihuFormControl);
|
|
140
|
-
_defined = true;
|
|
141
|
-
}
|
|
142
|
-
//#endregion
|
|
143
|
-
export { AihuFormControl, defineFormControl, formControlContext };
|
|
144
|
-
|
|
145
|
-
//# sourceMappingURL=form-control.js.map
|
|
1
|
+
import { i as attachHiddenInput, n as defineFormControl, r as formControlContext, t as AihuFormControl } from "./form-control-B_BO9j7_.js";
|
|
2
|
+
export { AihuFormControl, attachHiddenInput, defineFormControl, formControlContext };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { DomContext } from "./dom-context.js";
|
|
2
|
+
import { Read } from "@aihu/signals";
|
|
3
|
+
|
|
4
|
+
//#region src/form-control/hidden-input.d.ts
|
|
5
|
+
interface HiddenInputOptions {
|
|
6
|
+
type: 'checkbox' | 'radio';
|
|
7
|
+
name: Read<string | null>;
|
|
8
|
+
value: Read<string>;
|
|
9
|
+
checked: Read<boolean>;
|
|
10
|
+
required: Read<boolean>;
|
|
11
|
+
disabled: Read<boolean>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Attach a visually-hidden native input to `host`, kept in sync with the
|
|
15
|
+
* provided signals by a single effect. Returns a disposer that stops the
|
|
16
|
+
* effect and removes the input.
|
|
17
|
+
*/
|
|
18
|
+
declare function attachHiddenInput(host: HTMLElement, opts: HiddenInputOptions): () => void;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/form-control/index.d.ts
|
|
21
|
+
interface FormControlContextValue {
|
|
22
|
+
readonly disabled: Read<boolean>;
|
|
23
|
+
readonly required: Read<boolean>;
|
|
24
|
+
readonly invalid: Read<boolean>;
|
|
25
|
+
readonly controlId: Read<string>;
|
|
26
|
+
readonly describedById: Read<string | null>;
|
|
27
|
+
readonly labelId: Read<string | null>;
|
|
28
|
+
}
|
|
29
|
+
declare const formControlContext: DomContext<FormControlContextValue>;
|
|
30
|
+
declare class AihuFormControl extends HTMLElement {
|
|
31
|
+
static readonly observedAttributes: string[];
|
|
32
|
+
private readonly _disabled;
|
|
33
|
+
private readonly _required;
|
|
34
|
+
private readonly _invalid;
|
|
35
|
+
private readonly _controlId;
|
|
36
|
+
private readonly _describedById;
|
|
37
|
+
private readonly _labelId;
|
|
38
|
+
private _disposers;
|
|
39
|
+
get disabled(): Read<boolean>;
|
|
40
|
+
get required(): Read<boolean>;
|
|
41
|
+
get invalid(): Read<boolean>;
|
|
42
|
+
get controlId(): Read<string>;
|
|
43
|
+
get labelId(): Read<string | null>;
|
|
44
|
+
constructor();
|
|
45
|
+
connectedCallback(): void;
|
|
46
|
+
disconnectedCallback(): void;
|
|
47
|
+
attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
|
|
48
|
+
/** Re-derive `aria-describedby` from the slotted description/error pieces.
|
|
49
|
+
* Call after a piece mounts/unmounts. */
|
|
50
|
+
recomputeDescribedBy(): void;
|
|
51
|
+
private _syncBooleans;
|
|
52
|
+
/** The slotted control element (input/select/textarea/[data-fc-control]). */
|
|
53
|
+
private _control;
|
|
54
|
+
private _wireAssociations;
|
|
55
|
+
}
|
|
56
|
+
/** Register `<aihu-form-control>` (idempotent). */
|
|
57
|
+
declare function defineFormControl(tag?: string): void;
|
|
58
|
+
//#endregion
|
|
59
|
+
export { HiddenInputOptions as a, formControlContext as i, FormControlContextValue as n, attachHiddenInput as o, defineFormControl as r, AihuFormControl as t };
|
|
60
|
+
//# sourceMappingURL=index-BvFa1Y-Z.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-BvFa1Y-Z.d.ts","names":[],"sources":["../src/form-control/hidden-input.ts","../src/form-control/index.ts"],"mappings":";;;;UAsBiB,kBAAA;EACf,IAAA;EACA,IAAA,EAAM,IAAA;EACN,KAAA,EAAO,IAAA;EACP,OAAA,EAAS,IAAA;EACT,QAAA,EAAU,IAAA;EACV,QAAA,EAAU,IAAA;AAAA;;;;;;iBAQI,iBAAA,CAAkB,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,kBAAA;;;UCb1C,uBAAA;EAAA,SACN,QAAA,EAAU,IAAA;EAAA,SACV,QAAA,EAAU,IAAA;EAAA,SACV,OAAA,EAAS,IAAA;EAAA,SACT,SAAA,EAAW,IAAA;EAAA,SACX,aAAA,EAAe,IAAA;EAAA,SACf,OAAA,EAAS,IAAA;AAAA;AAAA,cAGP,kBAAA,EAAkB,UAAA,CAAA,uBAAA;AAAA,cAQlB,eAAA,SAAwB,WAAA;EAAA,gBACnB,kBAAA;EAAA,iBAEC,SAAA;EAAA,iBACA,SAAA;EAAA,iBACA,QAAA;EAAA,iBACA,UAAA;EAAA,iBACA,cAAA;EAAA,iBACA,QAAA;EAAA,QAET,UAAA;EAAA,IAEJ,QAAA,CAAA,GAAY,IAAA;EAAA,IAGZ,QAAA,CAAA,GAAY,IAAA;EAAA,IAGZ,OAAA,CAAA,GAAW,IAAA;EAAA,IAGX,SAAA,CAAA,GAAa,IAAA;EAAA,IAGb,OAAA,CAAA,GAAW,IAAA;;EAgBf,iBAAA,CAAA;EAuBA,oBAAA,CAAA;EAKA,wBAAA,CAAyB,IAAA,UAAc,IAAA,iBAAqB,KAAA;EAjFxC;;EAoGpB,oBAAA,CAAA;EAAA,QAIQ,aAAA;EAtGc;EAAA,QA6Gd,QAAA;EAAA,QAMA,iBAAA;AAAA;;iBAwCM,iBAAA,CAAkB,GAAA"}
|
|
@@ -79,8 +79,15 @@ declare class AihuDialogTitle extends DialogPiece {
|
|
|
79
79
|
declare class AihuDialogDescription extends DialogPiece {
|
|
80
80
|
protected onConnect(): void;
|
|
81
81
|
}
|
|
82
|
-
/**
|
|
83
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Register all dialog custom elements under `<prefix>-dialog-*` (idempotent
|
|
84
|
+
* per prefix). Non-default prefixes register a fresh trivial subclass per
|
|
85
|
+
* piece — a constructor can only be `customElements.define`d once, so the
|
|
86
|
+
* original classes stay reserved for the default tags. Demos/stories use a
|
|
87
|
+
* non-`aihu` prefix so styled recipes own the `aihu-dialog-*` namespace
|
|
88
|
+
* (spec §9.4).
|
|
89
|
+
*/
|
|
90
|
+
declare function defineDialog(prefix?: string): void;
|
|
84
91
|
//#endregion
|
|
85
92
|
export { AihuDialogRoot as a, DialogContextValue as c, FocusTrap as d, createFocusTrap as f, AihuDialogDescription as i, defineDialog as l, AihuDialogClose as n, AihuDialogTitle as o, AihuDialogContent as r, AihuDialogTrigger as s, AihuDialogBackdrop as t, dialogContext as u };
|
|
86
|
-
//# sourceMappingURL=index-
|
|
93
|
+
//# sourceMappingURL=index-D7hJLfnb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-D7hJLfnb.d.ts","names":[],"sources":["../src/dialog/focus-trap.ts","../src/dialog/index.ts"],"mappings":";;;;;;;;AAYA;;UAAiB,SAAA;EACf,QAAA;EACA,UAAA;AAAA;AAAA,iBAcc,eAAA,CAAgB,SAAA,EAAW,OAAA,GAAU,SAAA;;;UCbpC,kBAAA;EAAA,SACN,IAAA,EAAM,IAAA;EAAA,SACN,KAAA,EAAO,IAAA;EAAA,SACP,SAAA,EAAW,IAAA;EAAA,SACX,OAAA,EAAS,IAAA;EAAA,SACT,aAAA,EAAe,IAAA;EACxB,UAAA,CAAW,EAAA;EACX,gBAAA,CAAiB,EAAA;EACjB,OAAA,CAAQ,IAAA;EACR,KAAA;EACA,MAAA;AAAA;AAAA,cAGW,aAAA,EAAa,UAAA,CAAA,kBAAA;AAAA,cAKb,cAAA,SAAuB,WAAA;EAAA,gBAClB,kBAAA;EAAA,iBAEC,KAAA;EAAA,iBACA,MAAA;EAAA,iBACA,UAAA;EAAA,iBACA,QAAA;EAAA,iBACA,cAAA;EAAA,QACT,UAAA;EAAA,QACA,IAAA;;MAmBJ,IAAA,CAAA,GAAQ,IAAA;EAIZ,OAAA,CAAQ,IAAA;EAOR,iBAAA,CAAA;EAUA,oBAAA,CAAA;EAKA,wBAAA,CAAyB,IAAA,UAAc,IAAA,iBAAqB,KAAA;AAAA;;uBAO/C,WAAA,SAAoB,WAAA;EAAA,UACvB,GAAA,EAAM,kBAAA;EAAA,UACN,SAAA,EAAW,KAAA;EAErB,iBAAA,CAAA;EAKA,oBAAA,CAAA;EAAA,UAKU,YAAA,CAAA;EAAA,mBAQS,SAAA,CAAA;AAAA;AAAA,cAGR,iBAAA,SAA0B,WAAA;EAAA,UAC3B,SAAA,CAAA;EAAA,iBAiBO,QAAA;AAAA;AAAA,cAKN,iBAAA,SAA0B,WAAA;EAAA,QAC7B,KAAA;EAAA,UAEE,SAAA,CAAA;EAmBD,oBAAA,CAAA;EAAA,QAMD,aAAA;EAAA,QAMA,eAAA;EAAA,iBAKS,UAAA;AAAA;AAAA,cAQN,kBAAA,SAA2B,WAAA;EAAA,UAC5B,SAAA,CAAA;EAAA,iBAKO,QAAA;AAAA;AAAA,cAON,eAAA,SAAwB,WAAA;EAAA,UACzB,SAAA,CAAA;EAAA,iBASO,QAAA;AAAA;AAAA,cAKN,eAAA,SAAwB,WAAA;EAAA,UACzB,SAAA,CAAA;AAAA;AAAA,cAMC,qBAAA,SAA8B,WAAA;EAAA,UAC/B,SAAA,CAAA;AAAA;;;;;;;;AAtIX;iBA+Je,YAAA,CAAa,MAAA"}
|
|
@@ -28,4 +28,4 @@ declare class AihuButton extends HTMLElement {
|
|
|
28
28
|
declare function defineButton(tag: string): typeof AihuButton;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { ButtonType as n, defineButton as r, AihuButton as t };
|
|
31
|
-
//# sourceMappingURL=index-
|
|
31
|
+
//# sourceMappingURL=index-yPv3StRL.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-yPv3StRL.d.ts","names":[],"sources":["../src/button/button.ts"],"mappings":";;;KAqBY,UAAA;AAAA,cAEC,UAAA,SAAmB,WAAA;EAAA,gBACd,kBAAA;EAAA,iBAEC,SAAA;EAAA,iBACA,QAAA;EAAA,QACT,kBAAA;EAAA,QACA,UAAA;EAKQ;EAAA,QAFR,SAAA;EAAA,IAEJ,QAAA,CAAA,GAAY,IAAA;EAAA,IAGZ,OAAA,CAAA,GAAW,IAAA;EAAA,YAIH,eAAA,CAAA;EAIZ,iBAAA,CAAA;EAiCA,oBAAA,CAAA;EAOA,wBAAA,CAAyB,IAAA,UAAc,IAAA,iBAAqB,KAAA;EAArB;EAavC,MAAA,CAAA;EAAA,QAKQ,kBAAA;EAAA,QAKA,YAAA;EAAA,iBAMS,UAAA;EAAA,iBAQA,eAAA;EAAA,QAST,cAAA;AAAA;;iBAOM,YAAA,CAAa,GAAA,kBAAqB,UAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import { n as ButtonType, r as defineButton, t as AihuButton } from "./index-
|
|
1
|
+
import { n as ButtonType, r as defineButton, t as AihuButton } from "./index-yPv3StRL.js";
|
|
2
2
|
import { DomContext, MissingContextError, createDomContext, injectContext, provideContext } from "./dom-context.js";
|
|
3
|
+
import { AihuCheckboxIndicator, AihuCheckboxRoot, CheckboxContextValue, CheckboxState, checkboxContext, defineCheckbox } from "./checkbox.js";
|
|
3
4
|
import { AihuCollection, CollectionContextValue, collectionContext, createCollection, defineCollection } from "./collection.js";
|
|
4
5
|
import { AihuConfigProvider, ColorScheme, ConfigContextValue, Density, Direction, configContext, defineConfigProvider } from "./config-provider.js";
|
|
5
|
-
import { a as AihuDialogRoot, c as DialogContextValue, d as FocusTrap, f as createFocusTrap, i as AihuDialogDescription, l as defineDialog, n as AihuDialogClose, o as AihuDialogTitle, r as AihuDialogContent, s as AihuDialogTrigger, t as AihuDialogBackdrop, u as dialogContext } from "./index-
|
|
6
|
-
import {
|
|
6
|
+
import { a as AihuDialogRoot, c as DialogContextValue, d as FocusTrap, f as createFocusTrap, i as AihuDialogDescription, l as defineDialog, n as AihuDialogClose, o as AihuDialogTitle, r as AihuDialogContent, s as AihuDialogTrigger, t as AihuDialogBackdrop, u as dialogContext } from "./index-D7hJLfnb.js";
|
|
7
|
+
import { a as HiddenInputOptions, i as formControlContext, n as FormControlContextValue, o as attachHiddenInput, r as defineFormControl, t as AihuFormControl } from "./index-BvFa1Y-Z.js";
|
|
8
|
+
import { t as AihuTextControlBase } from "./text-control-Brv5fUEX.js";
|
|
9
|
+
import { AihuInput, defineInput } from "./input.js";
|
|
10
|
+
import { AihuLabel, defineLabel } from "./label.js";
|
|
7
11
|
import { AihuPresenceGate, definePresenceGate, presenceContext } from "./presence-gate.js";
|
|
8
12
|
import { AihuRovingFocus, Orientation, defineRovingFocus } from "./roving-focus.js";
|
|
13
|
+
import { AihuRadioGroupIndicator, AihuRadioGroupItem, AihuRadioGroupRoot, RadioGroupContextValue, RadioGroupItemContextValue, defineRadioGroup, radioGroupContext, radioGroupItemContext } from "./radio-group.js";
|
|
14
|
+
import { AihuSeparator, SeparatorOrientation, defineSeparator } from "./separator.js";
|
|
15
|
+
import { AihuSwitchRoot, AihuSwitchThumb, SwitchContextValue, defineSwitch, switchContext } from "./switch.js";
|
|
16
|
+
import { AihuTextarea, defineTextarea } from "./textarea.js";
|
|
9
17
|
import { AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, TooltipContextValue, TooltipCoords, defineTooltip, tooltipContext } from "./tooltip.js";
|
|
10
|
-
export { AihuButton, AihuCollection, AihuConfigProvider, AihuDialogBackdrop, AihuDialogClose, AihuDialogContent, AihuDialogDescription, AihuDialogRoot, AihuDialogTitle, AihuDialogTrigger, AihuFormControl, AihuPresenceGate, AihuRovingFocus, AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, type ButtonType, type CollectionContextValue, type ColorScheme, type ConfigContextValue, type Density, type DialogContextValue, type Direction, type DomContext, type FocusTrap, type FormControlContextValue, MissingContextError, type Orientation, type TooltipContextValue, type TooltipCoords, collectionContext, configContext, createCollection, createDomContext, createFocusTrap, defineButton, defineCollection, defineConfigProvider, defineDialog, defineFormControl, definePresenceGate, defineRovingFocus, defineTooltip, dialogContext, formControlContext, injectContext, presenceContext, provideContext, tooltipContext };
|
|
18
|
+
export { AihuButton, AihuCheckboxIndicator, AihuCheckboxRoot, AihuCollection, AihuConfigProvider, AihuDialogBackdrop, AihuDialogClose, AihuDialogContent, AihuDialogDescription, AihuDialogRoot, AihuDialogTitle, AihuDialogTrigger, AihuFormControl, AihuInput, AihuLabel, AihuPresenceGate, AihuRadioGroupIndicator, AihuRadioGroupItem, AihuRadioGroupRoot, AihuRovingFocus, AihuSeparator, AihuSwitchRoot, AihuSwitchThumb, AihuTextControlBase, AihuTextarea, AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, type ButtonType, type CheckboxContextValue, type CheckboxState, type CollectionContextValue, type ColorScheme, type ConfigContextValue, type Density, type DialogContextValue, type Direction, type DomContext, type FocusTrap, type FormControlContextValue, type HiddenInputOptions, MissingContextError, type Orientation, type RadioGroupContextValue, type RadioGroupItemContextValue, type SeparatorOrientation, type SwitchContextValue, type TooltipContextValue, type TooltipCoords, attachHiddenInput, checkboxContext, collectionContext, configContext, createCollection, createDomContext, createFocusTrap, defineButton, defineCheckbox, defineCollection, defineConfigProvider, defineDialog, defineFormControl, defineInput, defineLabel, definePresenceGate, defineRadioGroup, defineRovingFocus, defineSeparator, defineSwitch, defineTextarea, defineTooltip, dialogContext, formControlContext, injectContext, presenceContext, provideContext, radioGroupContext, radioGroupItemContext, switchContext, tooltipContext };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { MissingContextError, createDomContext, injectContext, provideContext } from "./dom-context.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as defineButton, t as AihuButton } from "./button-
|
|
2
|
+
import { i as attachHiddenInput, n as defineFormControl, r as formControlContext, t as AihuFormControl } from "./form-control-B_BO9j7_.js";
|
|
3
|
+
import { n as defineButton, t as AihuButton } from "./button-Cha1gKlr.js";
|
|
4
|
+
import { AihuCheckboxIndicator, AihuCheckboxRoot, checkboxContext, defineCheckbox } from "./checkbox.js";
|
|
4
5
|
import { AihuCollection, collectionContext, createCollection, defineCollection } from "./collection.js";
|
|
5
6
|
import { AihuConfigProvider, configContext, defineConfigProvider } from "./config-provider.js";
|
|
6
|
-
import { a as AihuDialogRoot, c as defineDialog, i as AihuDialogDescription, l as dialogContext, n as AihuDialogClose, o as AihuDialogTitle, r as AihuDialogContent, s as AihuDialogTrigger, t as AihuDialogBackdrop, u as createFocusTrap } from "./dialog-
|
|
7
|
+
import { a as AihuDialogRoot, c as defineDialog, i as AihuDialogDescription, l as dialogContext, n as AihuDialogClose, o as AihuDialogTitle, r as AihuDialogContent, s as AihuDialogTrigger, t as AihuDialogBackdrop, u as createFocusTrap } from "./dialog-VDL-W3Vy.js";
|
|
8
|
+
import { t as AihuTextControlBase } from "./text-control-BBX7s8Oe.js";
|
|
9
|
+
import { AihuInput, defineInput } from "./input.js";
|
|
10
|
+
import { AihuLabel, defineLabel } from "./label.js";
|
|
7
11
|
import { AihuPresenceGate, definePresenceGate, presenceContext } from "./presence-gate.js";
|
|
8
12
|
import { AihuRovingFocus, defineRovingFocus } from "./roving-focus.js";
|
|
13
|
+
import { AihuRadioGroupIndicator, AihuRadioGroupItem, AihuRadioGroupRoot, defineRadioGroup, radioGroupContext, radioGroupItemContext } from "./radio-group.js";
|
|
14
|
+
import { AihuSeparator, defineSeparator } from "./separator.js";
|
|
15
|
+
import { AihuSwitchRoot, AihuSwitchThumb, defineSwitch, switchContext } from "./switch.js";
|
|
16
|
+
import { AihuTextarea, defineTextarea } from "./textarea.js";
|
|
9
17
|
import { AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, defineTooltip, tooltipContext } from "./tooltip.js";
|
|
10
|
-
export { AihuButton, AihuCollection, AihuConfigProvider, AihuDialogBackdrop, AihuDialogClose, AihuDialogContent, AihuDialogDescription, AihuDialogRoot, AihuDialogTitle, AihuDialogTrigger, AihuFormControl, AihuPresenceGate, AihuRovingFocus, AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, MissingContextError, collectionContext, configContext, createCollection, createDomContext, createFocusTrap, defineButton, defineCollection, defineConfigProvider, defineDialog, defineFormControl, definePresenceGate, defineRovingFocus, defineTooltip, dialogContext, formControlContext, injectContext, presenceContext, provideContext, tooltipContext };
|
|
18
|
+
export { AihuButton, AihuCheckboxIndicator, AihuCheckboxRoot, AihuCollection, AihuConfigProvider, AihuDialogBackdrop, AihuDialogClose, AihuDialogContent, AihuDialogDescription, AihuDialogRoot, AihuDialogTitle, AihuDialogTrigger, AihuFormControl, AihuInput, AihuLabel, AihuPresenceGate, AihuRadioGroupIndicator, AihuRadioGroupItem, AihuRadioGroupRoot, AihuRovingFocus, AihuSeparator, AihuSwitchRoot, AihuSwitchThumb, AihuTextControlBase, AihuTextarea, AihuTooltipContent, AihuTooltipRoot, AihuTooltipTrigger, MissingContextError, attachHiddenInput, checkboxContext, collectionContext, configContext, createCollection, createDomContext, createFocusTrap, defineButton, defineCheckbox, defineCollection, defineConfigProvider, defineDialog, defineFormControl, defineInput, defineLabel, definePresenceGate, defineRadioGroup, defineRovingFocus, defineSeparator, defineSwitch, defineTextarea, defineTooltip, dialogContext, formControlContext, injectContext, presenceContext, provideContext, radioGroupContext, radioGroupItemContext, switchContext, tooltipContext };
|
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { t as AihuTextControlBase } from "./text-control-Brv5fUEX.js";
|
|
2
|
+
|
|
3
|
+
//#region src/input/index.d.ts
|
|
4
|
+
declare class AihuInput extends AihuTextControlBase {
|
|
5
|
+
static readonly observedAttributes: string[];
|
|
6
|
+
protected static readonly FORWARDED: readonly string[];
|
|
7
|
+
protected readonly nativeTag: "input";
|
|
8
|
+
}
|
|
9
|
+
/** Register `<aihu-input>` (idempotent). */
|
|
10
|
+
declare function defineInput(tag?: string): void;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { AihuInput, AihuTextControlBase, defineInput };
|
|
13
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","names":[],"sources":["../src/input/index.ts"],"mappings":";;;cAyBa,SAAA,SAAkB,mBAAA;EAAA,gBACb,kBAAA;EAAA,0BACmB,SAAA;EAAA,mBAEP,SAAA;AAAA;AAK9B;AAAA,iBAAgB,WAAA,CAAY,GAAA"}
|