@hxdhxd/harmony-flow-ui 0.1.1 → 0.1.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/index.js CHANGED
@@ -331,7 +331,7 @@ function Modal({ open, title, children, onClose, footer }) {
331
331
  /* @__PURE__ */ jsx9("div", { className: "hf-modal-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ jsxs7("div", { ref: dialogRef, className: "hf-modal", role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [
332
332
  /* @__PURE__ */ jsxs7("header", { className: "hf-modal__header", children: [
333
333
  /* @__PURE__ */ jsx9("h2", { id: titleId, children: title }),
334
- /* @__PURE__ */ jsx9(Button, { variant: "quiet", size: "sm", onClick: onClose, "aria-label": "\u5173\u95ED\u5F39\u7A97", children: "\xD7" })
334
+ /* @__PURE__ */ jsx9(Button, { variant: "quiet", size: "sm", iconOnly: true, leadingIcon: /* @__PURE__ */ jsx9(Icon, { name: "close", size: 16 }), onClick: onClose, "aria-label": "\u5173\u95ED\u5F39\u7A97" })
335
335
  ] }),
336
336
  /* @__PURE__ */ jsx9("div", { className: "hf-modal__body", children }),
337
337
  footer && /* @__PURE__ */ jsx9("footer", { className: "hf-modal__footer", children: footer })
@@ -407,7 +407,10 @@ function Accordion({ items, value, defaultValue = [], onChange, multiple = false
407
407
  return /* @__PURE__ */ jsxs10("section", { className: open ? "is-open" : "", children: [
408
408
  /* @__PURE__ */ jsx12("h3", { children: /* @__PURE__ */ jsxs10("button", { type: "button", "aria-expanded": open, disabled: item.disabled, onClick: () => toggle(item.key), children: [
409
409
  /* @__PURE__ */ jsx12("span", { children: item.title }),
410
- /* @__PURE__ */ jsx12("span", { "aria-hidden": "true", children: "\u2304" })
410
+ /* @__PURE__ */ jsxs10("span", { className: "hf-accordion__toggle", "aria-hidden": "true", children: [
411
+ /* @__PURE__ */ jsx12("i", {}),
412
+ /* @__PURE__ */ jsx12("i", {})
413
+ ] })
411
414
  ] }) }),
412
415
  open && /* @__PURE__ */ jsx12("div", { className: "hf-accordion__panel", children: item.content })
413
416
  ] }, item.key);
@@ -456,7 +459,7 @@ function ColorPicker({ value, onChange, label, presets = ["#0a7cff", "#19a989",
456
459
  /* @__PURE__ */ jsxs12("button", { type: "button", className: "hf-color-picker__trigger", disabled, "aria-expanded": open, onClick: () => setOpen(!open), children: [
457
460
  /* @__PURE__ */ jsx15("span", { style: { background: value } }),
458
461
  /* @__PURE__ */ jsx15("code", { children: value.toUpperCase() }),
459
- /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\u2304" })
462
+ /* @__PURE__ */ jsx15(Icon, { className: "hf-picker-trigger__chevron", name: "chevron-down", size: 16 })
460
463
  ] }),
461
464
  open && /* @__PURE__ */ jsxs12("div", { className: "hf-color-picker__panel", children: [
462
465
  /* @__PURE__ */ jsx15("input", { type: "color", "aria-label": "\u9009\u62E9\u989C\u8272", value, onChange: (event) => onChange(event.target.value) }),
@@ -607,7 +610,7 @@ function ChatComposer({ value, onChange, onSend, attachments = [], onRemoveAttac
607
610
  item.icon,
608
611
  /* @__PURE__ */ jsx17("strong", { children: item.name }),
609
612
  item.size && /* @__PURE__ */ jsx17("small", { children: item.size }),
610
- onRemoveAttachment && /* @__PURE__ */ jsx17("button", { type: "button", "aria-label": `\u79FB\u9664\u9644\u4EF6 ${item.name}`, onClick: () => onRemoveAttachment(item.id), children: "\xD7" })
613
+ onRemoveAttachment && /* @__PURE__ */ jsx17("button", { type: "button", "aria-label": `\u79FB\u9664\u9644\u4EF6 ${item.name}`, onClick: () => onRemoveAttachment(item.id), children: /* @__PURE__ */ jsx17(Icon, { name: "close", size: 14 }) })
611
614
  ] }, item.id)) }),
612
615
  /* @__PURE__ */ jsx17("textarea", { "aria-label": "\u6D88\u606F\u5185\u5BB9", value, maxLength, disabled, placeholder, onChange: (event) => onChange(event.target.value), onKeyDown: keyDown }),
613
616
  /* @__PURE__ */ jsxs14("footer", { children: [
@@ -787,7 +790,7 @@ function CodeBlock({ code, language = "text", filename, wrap, showLineNumbers =
787
790
  function VoiceInput({ state = "idle", duration = "00:00", level = 0.45, disabled, onStart, onStop, onCancel, error }) {
788
791
  const active = state === "listening";
789
792
  return /* @__PURE__ */ jsxs15("div", { className: `hf-voice-input is-${state}`, role: "status", "aria-label": active ? "\u6B63\u5728\u5F55\u97F3" : state === "processing" ? "\u6B63\u5728\u8BC6\u522B\u8BED\u97F3" : "\u8BED\u97F3\u8F93\u5165", children: [
790
- /* @__PURE__ */ jsx18("button", { type: "button", className: "hf-voice-input__main", disabled: disabled || state === "processing", onClick: active ? onStop : onStart, children: state === "processing" ? /* @__PURE__ */ jsx18("span", { className: "hf-spinner" }) : active ? "\u25A0" : "\u25CF" }),
793
+ /* @__PURE__ */ jsx18("button", { type: "button", className: "hf-voice-input__main", "aria-label": active ? "\u505C\u6B62\u5F55\u97F3" : state === "processing" ? "\u6B63\u5728\u8BC6\u522B\u8BED\u97F3" : "\u5F00\u59CB\u8BED\u97F3\u8F93\u5165", disabled: disabled || state === "processing", onClick: active ? onStop : onStart, children: state === "processing" ? /* @__PURE__ */ jsx18("span", { className: "hf-spinner" }) : /* @__PURE__ */ jsx18("span", { className: active ? "hf-voice-input__stop-icon" : "hf-voice-input__record-icon" }) }),
791
794
  /* @__PURE__ */ jsxs15("div", { children: [
792
795
  /* @__PURE__ */ jsx18("div", { className: "hf-voice-input__wave", "aria-hidden": "true", children: Array.from({ length: 18 }, (_, index) => /* @__PURE__ */ jsx18("i", { style: { height: `${Math.max(12, index * 17 % 75 * level + 12)}%` } }, index)) }),
793
796
  /* @__PURE__ */ jsx18("span", { children: active ? duration : state === "processing" ? "\u6B63\u5728\u8F6C\u6362\u6587\u5B57\u2026" : error ?? "\u70B9\u51FB\u5F00\u59CB\u8BED\u97F3\u8F93\u5165" })
@@ -806,7 +809,7 @@ function ModelSelector({ models, value, onChange, label = "\u9009\u62E9\u6A21\u5
806
809
  /* @__PURE__ */ jsx18("strong", { children: selected?.name ?? label }),
807
810
  selected?.description && /* @__PURE__ */ jsx18("small", { children: selected.description })
808
811
  ] }),
809
- /* @__PURE__ */ jsx18("i", { "aria-hidden": "true", children: "\u2304" })
812
+ /* @__PURE__ */ jsx18(Icon, { className: "hf-model-selector__chevron", name: "chevron-down", size: 16 })
810
813
  ] }),
811
814
  open && /* @__PURE__ */ jsx18("div", { className: "hf-model-selector__menu", role: "listbox", "aria-label": label, children: models.map((model) => /* @__PURE__ */ jsxs15("button", { type: "button", role: "option", "aria-selected": model.id === value, disabled: model.disabled, onClick: () => {
812
815
  onChange(model.id);
@@ -1123,7 +1126,7 @@ function MemberPicker({ members, value, onChange, label = "\u6DFB\u52A0\u6210\u5
1123
1126
  return item && /* @__PURE__ */ jsxs17("span", { children: [
1124
1127
  /* @__PURE__ */ jsx20(Avatar, { name: item.name, src: item.avatar, size: "sm" }),
1125
1128
  item.name,
1126
- /* @__PURE__ */ jsx20("button", { type: "button", disabled, "aria-label": `\u79FB\u9664 ${item.name}`, onClick: () => onChange(value.filter((key) => key !== id)), children: "\xD7" })
1129
+ /* @__PURE__ */ jsx20("button", { type: "button", disabled, "aria-label": `\u79FB\u9664 ${item.name}`, onClick: () => onChange(value.filter((key) => key !== id)), children: /* @__PURE__ */ jsx20(Icon, { name: "close", size: 14 }) })
1127
1130
  ] }, id);
1128
1131
  }) }),
1129
1132
  /* @__PURE__ */ jsx20("input", { "aria-label": label, value: query, disabled, placeholder: label, onChange: (event) => setQuery(event.target.value) }),
@@ -1157,27 +1160,115 @@ function SharePanel({ scope, onScopeChange, members, onCopyLink, linkCopied, foo
1157
1160
  ] }, item)) }),
1158
1161
  members && /* @__PURE__ */ jsx20("div", { className: "hf-share-panel__members", children: members }),
1159
1162
  /* @__PURE__ */ jsxs17("footer", { children: [
1160
- /* @__PURE__ */ jsx20("button", { type: "button", onClick: onCopyLink, children: linkCopied ? "\u94FE\u63A5\u5DF2\u590D\u5236" : "\u590D\u5236\u94FE\u63A5" }),
1163
+ /* @__PURE__ */ jsx20(Button, { type: "button", size: "sm", variant: "secondary", onClick: onCopyLink, children: linkCopied ? "\u94FE\u63A5\u5DF2\u590D\u5236" : "\u590D\u5236\u94FE\u63A5" }),
1161
1164
  footer
1162
1165
  ] })
1163
1166
  ] });
1164
1167
  }
1165
1168
 
1166
- // src/components/Scheduling.tsx
1169
+ // src/forms/Select.tsx
1170
+ import { forwardRef as forwardRef5, useEffect as useEffect4, useId as useId4, useRef as useRef4, useState as useState10 } from "react";
1167
1171
  import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1172
+ var Select = forwardRef5(function Select2({ id, label, hint, error, options, placeholder, className = "", value, defaultValue, onChange, disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }, forwardedRef) {
1173
+ const generatedId = useId4();
1174
+ const inputId = id ?? generatedId;
1175
+ const triggerId = `${inputId}-trigger`;
1176
+ const listboxId = `${inputId}-listbox`;
1177
+ const descriptionId = `${inputId}-description`;
1178
+ const [open, setOpen] = useState10(false);
1179
+ const rootRef = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
1180
+ const nativeRef = useRef4(null);
1181
+ const [innerValue, setInnerValue] = useState10(() => String(defaultValue ?? (placeholder ? "" : options.find((option) => !option.disabled)?.value ?? "")));
1182
+ const selectedValue = value === void 0 ? innerValue : String(value);
1183
+ const selectedOption = options.find((option) => option.value === selectedValue);
1184
+ const enabledIndices = options.map((option, index) => option.disabled ? -1 : index).filter((index) => index >= 0);
1185
+ const selectedIndex = options.findIndex((option) => option.value === selectedValue);
1186
+ const [activeIndex, setActiveIndex] = useState10(selectedIndex >= 0 ? selectedIndex : enabledIndices[0] ?? -1);
1187
+ const assignRef = (node) => {
1188
+ nativeRef.current = node;
1189
+ if (typeof forwardedRef === "function") forwardedRef(node);
1190
+ else if (forwardedRef) forwardedRef.current = node;
1191
+ };
1192
+ const handleNativeChange = (event) => {
1193
+ if (value === void 0) setInnerValue(event.currentTarget.value);
1194
+ onChange?.(event);
1195
+ };
1196
+ const choose = (nextValue) => {
1197
+ const native = nativeRef.current;
1198
+ if (!native) return;
1199
+ Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, "value")?.set?.call(native, nextValue);
1200
+ native.dispatchEvent(new Event("change", { bubbles: true }));
1201
+ if (value === void 0) setInnerValue(nextValue);
1202
+ setOpen(false);
1203
+ window.requestAnimationFrame(() => document.getElementById(triggerId)?.focus());
1204
+ };
1205
+ useEffect4(() => {
1206
+ if (selectedIndex >= 0) setActiveIndex(selectedIndex);
1207
+ }, [selectedIndex]);
1208
+ const move = (direction) => {
1209
+ if (!enabledIndices.length) return;
1210
+ const current = enabledIndices.indexOf(activeIndex);
1211
+ const next = current < 0 ? 0 : (current + direction + enabledIndices.length) % enabledIndices.length;
1212
+ setActiveIndex(enabledIndices[next]);
1213
+ };
1214
+ const handleKeyDown = (event) => {
1215
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1216
+ event.preventDefault();
1217
+ if (!open) setOpen(true);
1218
+ move(event.key === "ArrowDown" ? 1 : -1);
1219
+ } else if ((event.key === "Enter" || event.key === " ") && open) {
1220
+ event.preventDefault();
1221
+ const option = options[activeIndex];
1222
+ if (option && !option.disabled) choose(option.value);
1223
+ } else if (event.key === "Escape" && open) {
1224
+ event.preventDefault();
1225
+ setOpen(false);
1226
+ } else if (event.key === "Home" && open && enabledIndices.length) {
1227
+ event.preventDefault();
1228
+ setActiveIndex(enabledIndices[0]);
1229
+ } else if (event.key === "End" && open && enabledIndices.length) {
1230
+ event.preventDefault();
1231
+ setActiveIndex(enabledIndices[enabledIndices.length - 1]);
1232
+ } else if (event.key === "Tab") setOpen(false);
1233
+ };
1234
+ return /* @__PURE__ */ jsxs18("div", { className: `hf-field ${className}`.trim(), ref: rootRef, children: [
1235
+ label && /* @__PURE__ */ jsx21("label", { className: "hf-field__label", htmlFor: triggerId, children: label }),
1236
+ /* @__PURE__ */ jsxs18("div", { className: `hf-select-shell ${open ? "hf-select-shell--open" : ""} ${error ? "hf-select-shell--error" : ""}`, children: [
1237
+ /* @__PURE__ */ jsxs18("select", { ref: assignRef, id: inputId, className: "hf-select-native", tabIndex: -1, "aria-hidden": "true", value: selectedValue, disabled, onChange: handleNativeChange, ...props, children: [
1238
+ placeholder && /* @__PURE__ */ jsx21("option", { value: "", disabled: true, children: placeholder }),
1239
+ options.map((option) => /* @__PURE__ */ jsx21("option", { value: option.value, disabled: option.disabled, children: typeof option.label === "string" ? option.label : option.value }, option.value))
1240
+ ] }),
1241
+ /* @__PURE__ */ jsxs18("button", { id: triggerId, type: "button", className: "hf-select", disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": open ? listboxId : void 0, "aria-activedescendant": open && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : void 0, "aria-invalid": Boolean(error), "aria-describedby": hint || error ? descriptionId : void 0, onClick: () => {
1242
+ setActiveIndex(selectedIndex >= 0 ? selectedIndex : enabledIndices[0] ?? -1);
1243
+ setOpen((current) => !current);
1244
+ }, onKeyDown: handleKeyDown, children: [
1245
+ /* @__PURE__ */ jsx21("span", { className: !selectedOption ? "hf-select__placeholder" : "", children: selectedOption?.label ?? placeholder ?? "\u8BF7\u9009\u62E9" }),
1246
+ /* @__PURE__ */ jsx21("svg", { className: "hf-select__chevron", viewBox: "0 0 16 16", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx21("path", { d: open ? "m4.5 9.75 3.5-3.5 3.5 3.5" : "m4.5 6.25 3.5 3.5 3.5-3.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
1247
+ ] }),
1248
+ open && /* @__PURE__ */ jsx21("div", { id: listboxId, className: "hf-select-menu", role: "listbox", "aria-labelledby": triggerId, children: options.map((option, index) => /* @__PURE__ */ jsxs18("button", { id: `${listboxId}-option-${index}`, type: "button", role: "option", "aria-selected": option.value === selectedValue, disabled: option.disabled, className: index === activeIndex ? "is-active" : "", onPointerMove: () => !option.disabled && setActiveIndex(index), onClick: () => choose(option.value), children: [
1249
+ /* @__PURE__ */ jsx21("span", { children: option.label }),
1250
+ option.value === selectedValue && /* @__PURE__ */ jsx21("svg", { viewBox: "0 0 16 16", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx21("path", { d: "m3.5 8 3 3 6-6", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) })
1251
+ ] }, option.value)) })
1252
+ ] }),
1253
+ (error || hint) && /* @__PURE__ */ jsx21("span", { id: descriptionId, className: `hf-field__hint ${error ? "hf-field__hint--error" : ""}`, children: error ?? hint })
1254
+ ] });
1255
+ });
1256
+
1257
+ // src/components/Scheduling.tsx
1258
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
1168
1259
  function EventCard({
1169
1260
  event,
1170
1261
  onClick
1171
1262
  }) {
1172
- return /* @__PURE__ */ jsxs18(
1263
+ return /* @__PURE__ */ jsxs19(
1173
1264
  "button",
1174
1265
  {
1175
1266
  type: "button",
1176
1267
  className: "hf-event-card",
1177
1268
  onClick: () => onClick?.(event.id),
1178
1269
  children: [
1179
- /* @__PURE__ */ jsx21("strong", { children: event.title }),
1180
- /* @__PURE__ */ jsxs18("time", { children: [
1270
+ /* @__PURE__ */ jsx22("strong", { children: event.title }),
1271
+ /* @__PURE__ */ jsxs19("time", { children: [
1181
1272
  event.start,
1182
1273
  "\u2013",
1183
1274
  event.end
@@ -1191,43 +1282,44 @@ function Scheduler({
1191
1282
  events,
1192
1283
  onEventClick
1193
1284
  }) {
1194
- return /* @__PURE__ */ jsx21("div", { className: "hf-scheduler", children: days.map((day2) => /* @__PURE__ */ jsxs18("section", { children: [
1195
- /* @__PURE__ */ jsx21("strong", { children: day2 }),
1196
- events.filter((e) => e.start.startsWith(day2)).map((e) => /* @__PURE__ */ jsx21(EventCard, { event: e, onClick: onEventClick }, e.id))
1285
+ return /* @__PURE__ */ jsx22("div", { className: "hf-scheduler", children: days.map((day2) => /* @__PURE__ */ jsxs19("section", { children: [
1286
+ /* @__PURE__ */ jsx22("strong", { children: day2 }),
1287
+ events.filter((e) => e.start.startsWith(day2)).map((e) => /* @__PURE__ */ jsx22(EventCard, { event: e, onClick: onEventClick }, e.id))
1197
1288
  ] }, day2)) });
1198
1289
  }
1199
1290
  function ResourceCalendar({
1200
1291
  resources,
1201
1292
  events
1202
1293
  }) {
1203
- return /* @__PURE__ */ jsx21("div", { className: "hf-resource-calendar", children: resources.map((r) => /* @__PURE__ */ jsxs18("section", { children: [
1204
- /* @__PURE__ */ jsx21("strong", { children: r.name }),
1205
- events.filter((e) => e.resourceId === r.id).map((e) => /* @__PURE__ */ jsx21(EventCard, { event: e }, e.id))
1294
+ return /* @__PURE__ */ jsx22("div", { className: "hf-resource-calendar", children: resources.map((r) => /* @__PURE__ */ jsxs19("section", { children: [
1295
+ /* @__PURE__ */ jsx22("strong", { children: r.name }),
1296
+ events.filter((e) => e.resourceId === r.id).map((e) => /* @__PURE__ */ jsx22(EventCard, { event: e }, e.id))
1206
1297
  ] }, r.id)) });
1207
1298
  }
1208
1299
  function RecurrenceEditor({
1209
1300
  value,
1210
1301
  onChange
1211
1302
  }) {
1212
- return /* @__PURE__ */ jsxs18("div", { className: "hf-recurrence", children: [
1213
- /* @__PURE__ */ jsxs18(
1214
- "select",
1303
+ return /* @__PURE__ */ jsxs19("div", { className: "hf-recurrence", children: [
1304
+ /* @__PURE__ */ jsx22(
1305
+ Select,
1215
1306
  {
1307
+ className: "hf-recurrence__select",
1216
1308
  "aria-label": "\u91CD\u590D\u9891\u7387",
1217
1309
  value: value.frequency,
1310
+ options: [
1311
+ { value: "none", label: "\u4E0D\u91CD\u590D" },
1312
+ { value: "daily", label: "\u6BCF\u5929" },
1313
+ { value: "weekly", label: "\u6BCF\u5468" },
1314
+ { value: "monthly", label: "\u6BCF\u6708" }
1315
+ ],
1218
1316
  onChange: (e) => onChange({
1219
1317
  ...value,
1220
1318
  frequency: e.target.value
1221
- }),
1222
- children: [
1223
- /* @__PURE__ */ jsx21("option", { value: "none", children: "\u4E0D\u91CD\u590D" }),
1224
- /* @__PURE__ */ jsx21("option", { value: "daily", children: "\u6BCF\u5929" }),
1225
- /* @__PURE__ */ jsx21("option", { value: "weekly", children: "\u6BCF\u5468" }),
1226
- /* @__PURE__ */ jsx21("option", { value: "monthly", children: "\u6BCF\u6708" })
1227
- ]
1319
+ })
1228
1320
  }
1229
1321
  ),
1230
- /* @__PURE__ */ jsx21(
1322
+ /* @__PURE__ */ jsx22(
1231
1323
  "input",
1232
1324
  {
1233
1325
  "aria-label": "\u91CD\u590D\u95F4\u9694",
@@ -1244,19 +1336,17 @@ function TimezoneSelect({
1244
1336
  value,
1245
1337
  onChange
1246
1338
  }) {
1247
- return /* @__PURE__ */ jsx21(
1248
- "select",
1339
+ return /* @__PURE__ */ jsx22(
1340
+ Select,
1249
1341
  {
1250
1342
  "aria-label": "\u65F6\u533A",
1251
1343
  className: "hf-timezone",
1252
1344
  value,
1253
- onChange: (e) => onChange(e.target.value),
1254
- children: options.map((o) => /* @__PURE__ */ jsxs18("option", { value: o.value, children: [
1255
- o.label,
1256
- " (",
1257
- o.offset,
1258
- ")"
1259
- ] }, o.value))
1345
+ options: options.map((option) => ({
1346
+ value: option.value,
1347
+ label: `${option.label} (${option.offset})`
1348
+ })),
1349
+ onChange: (e) => onChange(e.target.value)
1260
1350
  }
1261
1351
  );
1262
1352
  }
@@ -1265,24 +1355,24 @@ function AvailabilityGrid({
1265
1355
  slots,
1266
1356
  value
1267
1357
  }) {
1268
- return /* @__PURE__ */ jsx21("div", { className: "hf-availability", children: /* @__PURE__ */ jsxs18("table", { children: [
1269
- /* @__PURE__ */ jsx21("thead", { children: /* @__PURE__ */ jsxs18("tr", { children: [
1270
- /* @__PURE__ */ jsx21("th", { children: "\u6210\u5458" }),
1271
- slots.map((s) => /* @__PURE__ */ jsx21("th", { children: s }, s))
1358
+ return /* @__PURE__ */ jsx22("div", { className: "hf-availability", children: /* @__PURE__ */ jsxs19("table", { children: [
1359
+ /* @__PURE__ */ jsx22("thead", { children: /* @__PURE__ */ jsxs19("tr", { children: [
1360
+ /* @__PURE__ */ jsx22("th", { children: "\u6210\u5458" }),
1361
+ slots.map((s) => /* @__PURE__ */ jsx22("th", { children: s }, s))
1272
1362
  ] }) }),
1273
- /* @__PURE__ */ jsx21("tbody", { children: people.map((p) => /* @__PURE__ */ jsxs18("tr", { children: [
1274
- /* @__PURE__ */ jsx21("th", { children: p.name }),
1275
- slots.map((s) => /* @__PURE__ */ jsx21("td", { children: /* @__PURE__ */ jsx21("i", { className: `is-${value[p.id]?.[s] ?? "unavailable"}` }) }, s))
1363
+ /* @__PURE__ */ jsx22("tbody", { children: people.map((p) => /* @__PURE__ */ jsxs19("tr", { children: [
1364
+ /* @__PURE__ */ jsx22("th", { children: p.name }),
1365
+ slots.map((s) => /* @__PURE__ */ jsx22("td", { children: /* @__PURE__ */ jsx22("i", { className: `is-${value[p.id]?.[s] ?? "unavailable"}` }) }, s))
1276
1366
  ] }, p.id)) })
1277
1367
  ] }) });
1278
1368
  }
1279
1369
 
1280
1370
  // src/foundations/Typography.tsx
1281
- import { jsx as jsx22 } from "react/jsx-runtime";
1371
+ import { jsx as jsx23 } from "react/jsx-runtime";
1282
1372
  function Typography({ as, variant = "body", muted, truncate, className = "", ...props }) {
1283
1373
  const defaults = { display: "h1", h1: "h1", h2: "h2", h3: "h3", code: "code" };
1284
1374
  const Tag2 = as ?? defaults[variant] ?? "p";
1285
- return /* @__PURE__ */ jsx22(Tag2, { className: `hf-typography hf-typography--${variant}${muted ? " is-muted" : ""}${truncate ? " is-truncated" : ""} ${className}`, ...props });
1375
+ return /* @__PURE__ */ jsx23(Tag2, { className: `hf-typography hf-typography--${variant}${muted ? " is-muted" : ""}${truncate ? " is-truncated" : ""} ${className}`, ...props });
1286
1376
  }
1287
1377
 
1288
1378
  // src/navigation/types.ts
@@ -1291,85 +1381,85 @@ function activateNavigationItem(item, onItemSelect) {
1291
1381
  }
1292
1382
 
1293
1383
  // src/navigation/FloatingNav.tsx
1294
- import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
1384
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1295
1385
  function FloatingNav({ brand, items, action, activeKey, onItemSelect, className = "", ...props }) {
1296
- return /* @__PURE__ */ jsxs19("nav", { className: `hf-floating-nav ${className}`.trim(), "aria-label": "\u4E3B\u5BFC\u822A", ...props, children: [
1297
- /* @__PURE__ */ jsx23("div", { className: "hf-floating-nav__brand", children: brand }),
1298
- /* @__PURE__ */ jsx23("div", { className: "hf-floating-nav__items", children: items.map((item) => /* @__PURE__ */ jsx23("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: item.label }, item.key)) }),
1299
- action && /* @__PURE__ */ jsx23("div", { className: "hf-floating-nav__action", children: action })
1386
+ return /* @__PURE__ */ jsxs20("nav", { className: `hf-floating-nav ${className}`.trim(), "aria-label": "\u4E3B\u5BFC\u822A", ...props, children: [
1387
+ /* @__PURE__ */ jsx24("div", { className: "hf-floating-nav__brand", children: brand }),
1388
+ /* @__PURE__ */ jsx24("div", { className: "hf-floating-nav__items", children: items.map((item) => /* @__PURE__ */ jsx24("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: item.label }, item.key)) }),
1389
+ action && /* @__PURE__ */ jsx24("div", { className: "hf-floating-nav__action", children: action })
1300
1390
  ] });
1301
1391
  }
1302
1392
 
1303
1393
  // src/navigation/Sidebar.tsx
1304
- import { useState as useState10 } from "react";
1305
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
1394
+ import { useState as useState11 } from "react";
1395
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1306
1396
  function Sidebar({ brand, items, activeKey, collapsed, defaultCollapsed = false, onCollapsedChange, onItemSelect, appearance = "flush", className = "", ...props }) {
1307
- const [internalCollapsed, setInternalCollapsed] = useState10(defaultCollapsed);
1397
+ const [internalCollapsed, setInternalCollapsed] = useState11(defaultCollapsed);
1308
1398
  const isCollapsed = collapsed ?? internalCollapsed;
1309
1399
  const toggle = () => {
1310
1400
  const next = !isCollapsed;
1311
1401
  if (collapsed === void 0) setInternalCollapsed(next);
1312
1402
  onCollapsedChange?.(next);
1313
1403
  };
1314
- return /* @__PURE__ */ jsxs20("aside", { className: `hf-sidebar hf-sidebar--${appearance} ${isCollapsed ? "hf-sidebar--collapsed" : ""} ${className}`.trim(), ...props, children: [
1315
- /* @__PURE__ */ jsxs20("div", { className: "hf-sidebar__top", children: [
1316
- brand && /* @__PURE__ */ jsx24("div", { className: "hf-sidebar__brand", children: brand }),
1317
- /* @__PURE__ */ jsx24("button", { type: "button", onClick: toggle, "aria-label": isCollapsed ? "\u5C55\u5F00\u4FA7\u8FB9\u680F" : "\u6536\u8D77\u4FA7\u8FB9\u680F", "aria-expanded": !isCollapsed, children: "\u2039" })
1404
+ return /* @__PURE__ */ jsxs21("aside", { className: `hf-sidebar hf-sidebar--${appearance} ${isCollapsed ? "hf-sidebar--collapsed" : ""} ${className}`.trim(), ...props, children: [
1405
+ /* @__PURE__ */ jsxs21("div", { className: "hf-sidebar__top", children: [
1406
+ brand && /* @__PURE__ */ jsx25("div", { className: "hf-sidebar__brand", children: brand }),
1407
+ /* @__PURE__ */ jsx25("button", { className: "hf-sidebar__collapse", type: "button", onClick: toggle, "aria-label": isCollapsed ? "\u5C55\u5F00\u4FA7\u8FB9\u680F" : "\u6536\u8D77\u4FA7\u8FB9\u680F", "aria-expanded": !isCollapsed, children: /* @__PURE__ */ jsx25(Icon, { name: "arrow-right", size: 17 }) })
1318
1408
  ] }),
1319
- /* @__PURE__ */ jsx24("nav", { "aria-label": "\u4FA7\u8FB9\u5BFC\u822A", children: items.map((item) => /* @__PURE__ */ jsxs20("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, title: isCollapsed ? item.label : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: [
1320
- /* @__PURE__ */ jsx24("span", { className: "hf-sidebar__icon", children: item.icon ?? item.label.slice(0, 1) }),
1321
- /* @__PURE__ */ jsx24("span", { className: "hf-sidebar__label", children: item.label })
1409
+ /* @__PURE__ */ jsx25("nav", { "aria-label": "\u4FA7\u8FB9\u5BFC\u822A", children: items.map((item) => /* @__PURE__ */ jsxs21("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, title: isCollapsed ? item.label : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: [
1410
+ /* @__PURE__ */ jsx25("span", { className: "hf-sidebar__icon", children: item.icon ?? item.label.slice(0, 1) }),
1411
+ /* @__PURE__ */ jsx25("span", { className: "hf-sidebar__label", children: item.label })
1322
1412
  ] }, item.key)) })
1323
1413
  ] });
1324
1414
  }
1325
1415
 
1326
1416
  // src/navigation/Breadcrumb.tsx
1327
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
1417
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1328
1418
  function Breadcrumb({ items, separator = "/", onItemSelect, className = "", ...props }) {
1329
- return /* @__PURE__ */ jsx25("nav", { className: `hf-breadcrumb ${className}`.trim(), "aria-label": "\u9762\u5305\u5C51", ...props, children: /* @__PURE__ */ jsx25("ol", { children: items.map((item, index) => {
1419
+ return /* @__PURE__ */ jsx26("nav", { className: `hf-breadcrumb ${className}`.trim(), "aria-label": "\u9762\u5305\u5C51", ...props, children: /* @__PURE__ */ jsx26("ol", { children: items.map((item, index) => {
1330
1420
  const current = index === items.length - 1;
1331
- return /* @__PURE__ */ jsxs21("li", { children: [
1332
- current ? /* @__PURE__ */ jsx25("span", { "aria-current": "page", children: item.label }) : /* @__PURE__ */ jsx25("a", { href: item.href ?? "#", onClick: () => activateNavigationItem(item, onItemSelect), children: item.label }),
1333
- !current && /* @__PURE__ */ jsx25("i", { "aria-hidden": "true", children: separator })
1421
+ return /* @__PURE__ */ jsxs22("li", { children: [
1422
+ current ? /* @__PURE__ */ jsx26("span", { "aria-current": "page", children: item.label }) : /* @__PURE__ */ jsx26("a", { href: item.href ?? "#", onClick: () => activateNavigationItem(item, onItemSelect), children: item.label }),
1423
+ !current && /* @__PURE__ */ jsx26("i", { "aria-hidden": "true", children: separator })
1334
1424
  ] }, item.key);
1335
1425
  }) }) });
1336
1426
  }
1337
1427
 
1338
1428
  // src/navigation/Menu.tsx
1339
- import { useState as useState11 } from "react";
1340
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
1429
+ import { useState as useState12 } from "react";
1430
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1341
1431
  function DropdownMenu({ label, items, activeKey, onItemSelect, className = "", ...props }) {
1342
- const [open, setOpen] = useState11(false);
1432
+ const [open, setOpen] = useState12(false);
1343
1433
  const ref = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
1344
- return /* @__PURE__ */ jsxs22("div", { ref, className: `hf-menu ${className}`.trim(), ...props, children: [
1345
- /* @__PURE__ */ jsxs22("button", { type: "button", "aria-expanded": open, "aria-haspopup": "menu", onClick: () => setOpen((value) => !value), children: [
1346
- label,
1347
- /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: "\u2304" })
1434
+ return /* @__PURE__ */ jsxs23("div", { ref, className: `hf-menu ${className}`.trim(), ...props, children: [
1435
+ /* @__PURE__ */ jsxs23("button", { type: "button", "aria-expanded": open, "aria-haspopup": "menu", onClick: () => setOpen((value) => !value), children: [
1436
+ /* @__PURE__ */ jsx27("span", { children: label }),
1437
+ /* @__PURE__ */ jsx27(Icon, { className: "hf-menu__chevron", name: "chevron-down", size: 16 })
1348
1438
  ] }),
1349
- open && /* @__PURE__ */ jsx26("div", { className: "hf-menu__panel", role: "menu", children: items.map((item) => /* @__PURE__ */ jsx26("a", { role: "menuitem", href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => {
1439
+ open && /* @__PURE__ */ jsx27("div", { className: "hf-menu__panel", role: "menu", children: items.map((item) => /* @__PURE__ */ jsx27("a", { role: "menuitem", href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => {
1350
1440
  activateNavigationItem(item, onItemSelect);
1351
1441
  setOpen(false);
1352
1442
  }, children: item.label }, item.key)) })
1353
1443
  ] });
1354
1444
  }
1355
1445
  function MegaMenu({ label, items, onItemSelect, className = "", ...props }) {
1356
- const [open, setOpen] = useState11(false);
1446
+ const [open, setOpen] = useState12(false);
1357
1447
  const ref = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
1358
- return /* @__PURE__ */ jsxs22("div", { ref, className: `hf-menu hf-mega-menu ${className}`.trim(), ...props, children: [
1359
- /* @__PURE__ */ jsxs22("button", { type: "button", "aria-expanded": open, "aria-haspopup": "menu", onClick: () => setOpen((value) => !value), children: [
1360
- label,
1361
- /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: "\u2304" })
1448
+ return /* @__PURE__ */ jsxs23("div", { ref, className: `hf-menu hf-mega-menu ${className}`.trim(), ...props, children: [
1449
+ /* @__PURE__ */ jsxs23("button", { type: "button", "aria-expanded": open, "aria-haspopup": "menu", onClick: () => setOpen((value) => !value), children: [
1450
+ /* @__PURE__ */ jsx27("span", { children: label }),
1451
+ /* @__PURE__ */ jsx27(Icon, { className: "hf-menu__chevron", name: "chevron-down", size: 16 })
1362
1452
  ] }),
1363
- open && /* @__PURE__ */ jsx26("div", { className: "hf-mega-menu__panel", role: "menu", children: items.map((group) => /* @__PURE__ */ jsxs22("section", { children: [
1364
- /* @__PURE__ */ jsx26("h3", { children: group.label }),
1365
- group.children?.map((item) => /* @__PURE__ */ jsxs22("a", { role: "menuitem", href: item.href ?? "#", onClick: () => {
1453
+ open && /* @__PURE__ */ jsx27("div", { className: "hf-mega-menu__panel", role: "menu", children: items.map((group) => /* @__PURE__ */ jsxs23("section", { children: [
1454
+ /* @__PURE__ */ jsx27("h3", { children: group.label }),
1455
+ group.children?.map((item) => /* @__PURE__ */ jsxs23("a", { role: "menuitem", href: item.href ?? "#", onClick: () => {
1366
1456
  activateNavigationItem(item, onItemSelect);
1367
1457
  setOpen(false);
1368
1458
  }, children: [
1369
- /* @__PURE__ */ jsx26("span", { children: item.icon }),
1370
- /* @__PURE__ */ jsxs22("span", { children: [
1371
- /* @__PURE__ */ jsx26("strong", { children: item.label }),
1372
- item.description && /* @__PURE__ */ jsx26("small", { children: item.description })
1459
+ /* @__PURE__ */ jsx27("span", { children: item.icon }),
1460
+ /* @__PURE__ */ jsxs23("span", { children: [
1461
+ /* @__PURE__ */ jsx27("strong", { children: item.label }),
1462
+ item.description && /* @__PURE__ */ jsx27("small", { children: item.description })
1373
1463
  ] })
1374
1464
  ] }, item.key))
1375
1465
  ] }, group.key)) })
@@ -1377,49 +1467,49 @@ function MegaMenu({ label, items, onItemSelect, className = "", ...props }) {
1377
1467
  }
1378
1468
 
1379
1469
  // src/navigation/MobileNavigation.tsx
1380
- import { useId as useId4, useState as useState12 } from "react";
1381
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
1470
+ import { useId as useId5, useState as useState13 } from "react";
1471
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
1382
1472
  function MobileNavigation({ brand, items, mode = "drawer", activeKey, open, onOpenChange, onItemSelect, className = "", ...props }) {
1383
- const [internalOpen, setInternalOpen] = useState12(false);
1473
+ const [internalOpen, setInternalOpen] = useState13(false);
1384
1474
  const isOpen = open ?? internalOpen;
1385
- const panelId = useId4();
1475
+ const panelId = useId5();
1386
1476
  const setOpen = (next) => {
1387
1477
  if (open === void 0) setInternalOpen(next);
1388
1478
  onOpenChange?.(next);
1389
1479
  };
1390
1480
  const panelRef = useDismissibleLayer(isOpen, () => setOpen(false), true);
1391
- return /* @__PURE__ */ jsxs23("div", { className: `hf-mobile-nav ${className}`.trim(), ...props, children: [
1392
- /* @__PURE__ */ jsxs23("div", { className: "hf-mobile-nav__bar", children: [
1393
- /* @__PURE__ */ jsx27("div", { children: brand }),
1394
- /* @__PURE__ */ jsxs23("button", { type: "button", "aria-label": "\u6253\u5F00\u5BFC\u822A", "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => setOpen(true), children: [
1395
- /* @__PURE__ */ jsx27("i", {}),
1396
- /* @__PURE__ */ jsx27("i", {}),
1397
- /* @__PURE__ */ jsx27("i", {})
1481
+ return /* @__PURE__ */ jsxs24("div", { className: `hf-mobile-nav ${className}`.trim(), ...props, children: [
1482
+ /* @__PURE__ */ jsxs24("div", { className: "hf-mobile-nav__bar", children: [
1483
+ /* @__PURE__ */ jsx28("div", { children: brand }),
1484
+ /* @__PURE__ */ jsxs24("button", { type: "button", "aria-label": "\u6253\u5F00\u5BFC\u822A", "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => setOpen(true), children: [
1485
+ /* @__PURE__ */ jsx28("i", {}),
1486
+ /* @__PURE__ */ jsx28("i", {}),
1487
+ /* @__PURE__ */ jsx28("i", {})
1398
1488
  ] })
1399
1489
  ] }),
1400
- isOpen && /* @__PURE__ */ jsx27("div", { className: `hf-mobile-nav__backdrop hf-mobile-nav__backdrop--${mode}`, onMouseDown: (event) => event.target === event.currentTarget && setOpen(false), children: /* @__PURE__ */ jsxs23("nav", { ref: panelRef, id: panelId, className: "hf-mobile-nav__panel", "aria-label": "\u79FB\u52A8\u5BFC\u822A", tabIndex: -1, children: [
1401
- /* @__PURE__ */ jsxs23("header", { children: [
1402
- /* @__PURE__ */ jsx27("div", { children: brand }),
1403
- /* @__PURE__ */ jsx27("button", { type: "button", "aria-label": "\u5173\u95ED\u5BFC\u822A", onClick: () => setOpen(false), children: "\xD7" })
1490
+ isOpen && /* @__PURE__ */ jsx28("div", { className: `hf-mobile-nav__backdrop hf-mobile-nav__backdrop--${mode}`, onMouseDown: (event) => event.target === event.currentTarget && setOpen(false), children: /* @__PURE__ */ jsxs24("nav", { ref: panelRef, id: panelId, className: "hf-mobile-nav__panel", "aria-label": "\u79FB\u52A8\u5BFC\u822A", tabIndex: -1, children: [
1491
+ /* @__PURE__ */ jsxs24("header", { children: [
1492
+ /* @__PURE__ */ jsx28("div", { children: brand }),
1493
+ /* @__PURE__ */ jsx28("button", { type: "button", "aria-label": "\u5173\u95ED\u5BFC\u822A", onClick: () => setOpen(false), children: /* @__PURE__ */ jsx28(Icon, { name: "close", size: 18 }) })
1404
1494
  ] }),
1405
- /* @__PURE__ */ jsx27("div", { className: "hf-mobile-nav__links", children: items.map((item, index) => /* @__PURE__ */ jsxs23("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, style: { "--hf-nav-index": index }, onClick: () => {
1495
+ /* @__PURE__ */ jsx28("div", { className: "hf-mobile-nav__links", children: items.map((item, index) => /* @__PURE__ */ jsxs24("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, style: { "--hf-nav-index": index }, onClick: () => {
1406
1496
  activateNavigationItem(item, onItemSelect);
1407
1497
  setOpen(false);
1408
1498
  }, children: [
1409
- /* @__PURE__ */ jsx27("span", { children: item.label }),
1410
- item.description && /* @__PURE__ */ jsx27("small", { children: item.description })
1499
+ /* @__PURE__ */ jsx28("span", { children: item.label }),
1500
+ item.description && /* @__PURE__ */ jsx28("small", { children: item.description })
1411
1501
  ] }, item.key)) })
1412
1502
  ] }) })
1413
1503
  ] });
1414
1504
  }
1415
1505
 
1416
1506
  // src/navigation/Scrollspy.tsx
1417
- import { useEffect as useEffect4, useState as useState13 } from "react";
1418
- import { jsx as jsx28 } from "react/jsx-runtime";
1507
+ import { useEffect as useEffect5, useState as useState14 } from "react";
1508
+ import { jsx as jsx29 } from "react/jsx-runtime";
1419
1509
  function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%", className = "", ...props }) {
1420
- const [observedKey, setObservedKey] = useState13(items[0]?.key);
1510
+ const [observedKey, setObservedKey] = useState14(items[0]?.key);
1421
1511
  const currentKey = activeKey ?? observedKey;
1422
- useEffect4(() => {
1512
+ useEffect5(() => {
1423
1513
  if (activeKey || !("IntersectionObserver" in window)) return;
1424
1514
  const observer = new IntersectionObserver((entries) => {
1425
1515
  const visible = entries.find((entry) => entry.isIntersecting);
@@ -1431,15 +1521,15 @@ function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%
1431
1521
  });
1432
1522
  return () => observer.disconnect();
1433
1523
  }, [activeKey, items, rootMargin]);
1434
- return /* @__PURE__ */ jsx28("nav", { className: `hf-scrollspy ${className}`.trim(), "aria-label": "\u9875\u5185\u5BFC\u822A", ...props, children: items.map((item) => /* @__PURE__ */ jsx28("a", { href: item.href ?? `#${item.key}`, "aria-current": currentKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) });
1524
+ return /* @__PURE__ */ jsx29("nav", { className: `hf-scrollspy ${className}`.trim(), "aria-label": "\u9875\u5185\u5BFC\u822A", ...props, children: items.map((item) => /* @__PURE__ */ jsx29("a", { href: item.href ?? `#${item.key}`, "aria-current": currentKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) });
1435
1525
  }
1436
1526
 
1437
1527
  // src/navigation/ShrinkNav.tsx
1438
- import { useEffect as useEffect5, useState as useState14 } from "react";
1439
- import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
1528
+ import { useEffect as useEffect6, useState as useState15 } from "react";
1529
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
1440
1530
  function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSelect, className = "", ...props }) {
1441
- const [compact, setCompact] = useState14(false);
1442
- useEffect5(() => {
1531
+ const [compact, setCompact] = useState15(false);
1532
+ useEffect6(() => {
1443
1533
  let frame = 0;
1444
1534
  const update = () => {
1445
1535
  cancelAnimationFrame(frame);
@@ -1452,18 +1542,18 @@ function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSele
1452
1542
  window.removeEventListener("scroll", update);
1453
1543
  };
1454
1544
  }, [threshold]);
1455
- return /* @__PURE__ */ jsxs24("nav", { className: `hf-shrink-nav ${compact ? "hf-shrink-nav--compact" : ""} ${className}`.trim(), "aria-label": "\u6EDA\u52A8\u5BFC\u822A", ...props, children: [
1456
- /* @__PURE__ */ jsx29("div", { className: "hf-shrink-nav__brand", children: brand }),
1457
- /* @__PURE__ */ jsx29("div", { className: "hf-shrink-nav__items", children: items.map((item) => /* @__PURE__ */ jsx29("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) }),
1545
+ return /* @__PURE__ */ jsxs25("nav", { className: `hf-shrink-nav ${compact ? "hf-shrink-nav--compact" : ""} ${className}`.trim(), "aria-label": "\u6EDA\u52A8\u5BFC\u822A", ...props, children: [
1546
+ /* @__PURE__ */ jsx30("div", { className: "hf-shrink-nav__brand", children: brand }),
1547
+ /* @__PURE__ */ jsx30("div", { className: "hf-shrink-nav__items", children: items.map((item) => /* @__PURE__ */ jsx30("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) }),
1458
1548
  action
1459
1549
  ] });
1460
1550
  }
1461
1551
 
1462
1552
  // src/navigation/Tabs.tsx
1463
- import { useId as useId5 } from "react";
1464
- import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
1553
+ import { useId as useId6 } from "react";
1554
+ import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
1465
1555
  function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\u6807\u7B7E" }) {
1466
- const id = useId5();
1556
+ const id = useId6();
1467
1557
  const active = items.find((item) => item.key === value) ?? items[0];
1468
1558
  const onKeyDown = (event) => {
1469
1559
  if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
@@ -1474,43 +1564,43 @@ function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\
1474
1564
  const next = enabled[(current + offset + enabled.length) % enabled.length];
1475
1565
  if (next) onChange(next.key);
1476
1566
  };
1477
- return /* @__PURE__ */ jsxs25("div", { className: `hf-tabs hf-tabs--${variant}`, children: [
1478
- /* @__PURE__ */ jsx30("div", { role: "tablist", "aria-label": label, onKeyDown, children: items.map((item) => /* @__PURE__ */ jsxs25("button", { type: "button", role: "tab", id: `${id}-${item.key}`, "aria-controls": `${id}-${item.key}-panel`, "aria-selected": item.key === value, tabIndex: item.key === value ? 0 : -1, disabled: item.disabled, onClick: () => onChange(item.key), children: [
1567
+ return /* @__PURE__ */ jsxs26("div", { className: `hf-tabs hf-tabs--${variant}`, children: [
1568
+ /* @__PURE__ */ jsx31("div", { role: "tablist", "aria-label": label, onKeyDown, children: items.map((item) => /* @__PURE__ */ jsxs26("button", { type: "button", role: "tab", id: `${id}-${item.key}`, "aria-controls": `${id}-${item.key}-panel`, "aria-selected": item.key === value, tabIndex: item.key === value ? 0 : -1, disabled: item.disabled, onClick: () => onChange(item.key), children: [
1479
1569
  item.icon,
1480
- /* @__PURE__ */ jsx30("span", { children: item.label }),
1481
- item.badge && /* @__PURE__ */ jsx30("small", { children: item.badge })
1570
+ /* @__PURE__ */ jsx31("span", { children: item.label }),
1571
+ item.badge && /* @__PURE__ */ jsx31("small", { children: item.badge })
1482
1572
  ] }, item.key)) }),
1483
- active && /* @__PURE__ */ jsx30("div", { role: "tabpanel", id: `${id}-${active.key}-panel`, "aria-labelledby": `${id}-${active.key}`, tabIndex: 0, children: active.content })
1573
+ active && /* @__PURE__ */ jsx31("div", { role: "tabpanel", id: `${id}-${active.key}-panel`, "aria-labelledby": `${id}-${active.key}`, tabIndex: 0, children: active.content })
1484
1574
  ] });
1485
1575
  }
1486
1576
 
1487
1577
  // src/navigation/Steps.tsx
1488
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
1578
+ import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
1489
1579
  function Steps({ items, current, onChange, orientation = "horizontal" }) {
1490
1580
  const currentIndex = Math.max(0, items.findIndex((item) => item.key === current));
1491
- return /* @__PURE__ */ jsx31("ol", { className: `hf-steps hf-steps--${orientation}`, children: items.map((item, index) => {
1581
+ return /* @__PURE__ */ jsx32("ol", { className: `hf-steps hf-steps--${orientation}`, children: items.map((item, index) => {
1492
1582
  const state = index < currentIndex ? "complete" : index === currentIndex ? "current" : "upcoming";
1493
- return /* @__PURE__ */ jsx31("li", { className: `is-${state}`, "aria-current": state === "current" ? "step" : void 0, children: /* @__PURE__ */ jsxs26("button", { type: "button", disabled: item.disabled || !onChange, onClick: () => onChange?.(item.key), children: [
1494
- /* @__PURE__ */ jsx31("span", { children: state === "complete" ? "\u2713" : index + 1 }),
1495
- /* @__PURE__ */ jsxs26("span", { children: [
1496
- /* @__PURE__ */ jsx31("strong", { children: item.title }),
1497
- item.optional && /* @__PURE__ */ jsx31("small", { children: "\u53EF\u9009" }),
1498
- item.description && /* @__PURE__ */ jsx31("small", { children: item.description })
1583
+ return /* @__PURE__ */ jsx32("li", { className: `is-${state}`, "aria-current": state === "current" ? "step" : void 0, children: /* @__PURE__ */ jsxs27("button", { type: "button", disabled: item.disabled || !onChange, onClick: () => onChange?.(item.key), children: [
1584
+ /* @__PURE__ */ jsx32("span", { children: state === "complete" ? "\u2713" : index + 1 }),
1585
+ /* @__PURE__ */ jsxs27("span", { children: [
1586
+ /* @__PURE__ */ jsx32("strong", { children: item.title }),
1587
+ item.optional && /* @__PURE__ */ jsx32("small", { children: "\u53EF\u9009" }),
1588
+ item.description && /* @__PURE__ */ jsx32("small", { children: item.description })
1499
1589
  ] })
1500
1590
  ] }) }, item.key);
1501
1591
  }) });
1502
1592
  }
1503
1593
 
1504
1594
  // src/navigation/CommandPalette.tsx
1505
- import { useEffect as useEffect6, useMemo as useMemo4, useState as useState15 } from "react";
1595
+ import { useEffect as useEffect7, useMemo as useMemo4, useState as useState16 } from "react";
1506
1596
  import { createPortal as createPortal3 } from "react-dom";
1507
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
1597
+ import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
1508
1598
  function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u8F93\u5165\u547D\u4EE4\u6216\u641C\u7D22\u2026" }) {
1509
- const [query, setQuery] = useState15("");
1510
- const [active, setActive] = useState15(0);
1599
+ const [query, setQuery] = useState16("");
1600
+ const [active, setActive] = useState16(0);
1511
1601
  const enabled = useMemo4(() => items.filter((item) => !item.disabled && `${item.label} ${item.description ?? ""} ${item.group ?? ""}`.toLowerCase().includes(query.toLowerCase())), [items, query]);
1512
1602
  const dialogRef = useDismissibleLayer(open, () => onOpenChange(false), true);
1513
- useEffect6(() => {
1603
+ useEffect7(() => {
1514
1604
  if (!open) {
1515
1605
  setQuery("");
1516
1606
  setActive(0);
@@ -1534,39 +1624,39 @@ function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u
1534
1624
  }
1535
1625
  };
1536
1626
  if (!open) return null;
1537
- return createPortal3(/* @__PURE__ */ jsx32("div", { className: "hf-command-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onOpenChange(false), children: /* @__PURE__ */ jsxs27("div", { ref: dialogRef, tabIndex: -1, className: "hf-command", role: "dialog", "aria-modal": "true", "aria-label": "\u547D\u4EE4\u9762\u677F", children: [
1538
- /* @__PURE__ */ jsxs27("div", { className: "hf-command__search", children: [
1539
- /* @__PURE__ */ jsx32("span", { "aria-hidden": "true", children: "\u2315" }),
1540
- /* @__PURE__ */ jsx32("input", { autoFocus: true, role: "combobox", "aria-expanded": "true", "aria-controls": "hf-command-list", value: query, placeholder, onChange: (event) => {
1627
+ return createPortal3(/* @__PURE__ */ jsx33("div", { className: "hf-command-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onOpenChange(false), children: /* @__PURE__ */ jsxs28("div", { ref: dialogRef, tabIndex: -1, className: "hf-command", role: "dialog", "aria-modal": "true", "aria-label": "\u547D\u4EE4\u9762\u677F", children: [
1628
+ /* @__PURE__ */ jsxs28("div", { className: "hf-command__search", children: [
1629
+ /* @__PURE__ */ jsx33("span", { "aria-hidden": "true", children: "\u2315" }),
1630
+ /* @__PURE__ */ jsx33("input", { autoFocus: true, role: "combobox", "aria-expanded": "true", "aria-controls": "hf-command-list", value: query, placeholder, onChange: (event) => {
1541
1631
  setQuery(event.target.value);
1542
1632
  setActive(0);
1543
1633
  }, onKeyDown: keydown }),
1544
- /* @__PURE__ */ jsx32("kbd", { children: "Esc" })
1634
+ /* @__PURE__ */ jsx33("kbd", { children: "Esc" })
1545
1635
  ] }),
1546
- /* @__PURE__ */ jsxs27("div", { id: "hf-command-list", className: "hf-command__list", role: "listbox", children: [
1547
- enabled.map((item, index) => /* @__PURE__ */ jsxs27("button", { type: "button", role: "option", "aria-selected": index === active, onPointerMove: () => setActive(index), onClick: () => {
1636
+ /* @__PURE__ */ jsxs28("div", { id: "hf-command-list", className: "hf-command__list", role: "listbox", children: [
1637
+ enabled.map((item, index) => /* @__PURE__ */ jsxs28("button", { type: "button", role: "option", "aria-selected": index === active, onPointerMove: () => setActive(index), onClick: () => {
1548
1638
  onSelect(item.key);
1549
1639
  onOpenChange(false);
1550
1640
  }, children: [
1551
1641
  item.icon,
1552
- /* @__PURE__ */ jsxs27("span", { children: [
1553
- /* @__PURE__ */ jsx32("strong", { children: item.label }),
1554
- item.description && /* @__PURE__ */ jsx32("small", { children: item.description })
1642
+ /* @__PURE__ */ jsxs28("span", { children: [
1643
+ /* @__PURE__ */ jsx33("strong", { children: item.label }),
1644
+ item.description && /* @__PURE__ */ jsx33("small", { children: item.description })
1555
1645
  ] }),
1556
- item.shortcut && /* @__PURE__ */ jsx32("kbd", { children: item.shortcut })
1646
+ item.shortcut && /* @__PURE__ */ jsx33("kbd", { children: item.shortcut })
1557
1647
  ] }, item.key)),
1558
- !enabled.length && /* @__PURE__ */ jsx32("div", { className: "hf-command__empty", children: "\u6CA1\u6709\u5339\u914D\u547D\u4EE4" })
1648
+ !enabled.length && /* @__PURE__ */ jsx33("div", { className: "hf-command__empty", children: "\u6CA1\u6709\u5339\u914D\u547D\u4EE4" })
1559
1649
  ] })
1560
1650
  ] }) }), document.body);
1561
1651
  }
1562
1652
 
1563
1653
  // src/layout/Layout.tsx
1564
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
1654
+ import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
1565
1655
  function Container({ size = "lg", padding = 24, className = "", style, ...props }) {
1566
- return /* @__PURE__ */ jsx33("div", { className: `hf-container hf-container--${size} ${className}`.trim(), style: { "--hf-container-padding": `${padding}px`, ...style }, ...props });
1656
+ return /* @__PURE__ */ jsx34("div", { className: `hf-container hf-container--${size} ${className}`.trim(), style: { "--hf-container-padding": `${padding}px`, ...style }, ...props });
1567
1657
  }
1568
1658
  function Stack({ direction = "column", gap = 12, align, justify, wrap = false, className = "", style, ...props }) {
1569
- return /* @__PURE__ */ jsx33("div", { className: `hf-stack hf-stack--${direction} ${className}`.trim(), style: { "--hf-stack-gap": `${gap}px`, alignItems: align, justifyContent: justify, flexWrap: wrap ? "wrap" : void 0, ...style }, ...props });
1659
+ return /* @__PURE__ */ jsx34("div", { className: `hf-stack hf-stack--${direction} ${className}`.trim(), style: { "--hf-stack-gap": `${gap}px`, alignItems: align, justifyContent: justify, flexWrap: wrap ? "wrap" : void 0, ...style }, ...props });
1570
1660
  }
1571
1661
  function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "", style, ...props }) {
1572
1662
  const gridStyle = {
@@ -1574,7 +1664,7 @@ function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "",
1574
1664
  "--hf-grid-gap": `${gap}px`,
1575
1665
  ...style
1576
1666
  };
1577
- return /* @__PURE__ */ jsx33("div", { className: `hf-grid ${className}`.trim(), style: gridStyle, ...props });
1667
+ return /* @__PURE__ */ jsx34("div", { className: `hf-grid ${className}`.trim(), style: gridStyle, ...props });
1578
1668
  }
1579
1669
  function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", style, children, ...props }) {
1580
1670
  const masonryStyle = {
@@ -1583,154 +1673,66 @@ function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", styl
1583
1673
  "--hf-masonry-gap": `${gap}px`,
1584
1674
  ...style
1585
1675
  };
1586
- return /* @__PURE__ */ jsx33("div", { className: `hf-masonry ${className}`.trim(), style: masonryStyle, ...props, children });
1676
+ return /* @__PURE__ */ jsx34("div", { className: `hf-masonry ${className}`.trim(), style: masonryStyle, ...props, children });
1587
1677
  }
1588
1678
  function PageLayout({ variant = "single", sidebar, header, sidebarWidth = 280, className = "", style, children, ...props }) {
1589
1679
  const layoutStyle = { "--hf-layout-sidebar": `${sidebarWidth}px`, ...style };
1590
- return /* @__PURE__ */ jsxs28("div", { className: `hf-page-layout hf-page-layout--${variant} ${className}`.trim(), style: layoutStyle, ...props, children: [
1591
- header && /* @__PURE__ */ jsx33("header", { className: "hf-page-layout__header", children: header }),
1592
- sidebar && /* @__PURE__ */ jsx33("aside", { className: "hf-page-layout__sidebar", children: sidebar }),
1593
- /* @__PURE__ */ jsx33("main", { className: "hf-page-layout__main", children })
1680
+ return /* @__PURE__ */ jsxs29("div", { className: `hf-page-layout hf-page-layout--${variant} ${className}`.trim(), style: layoutStyle, ...props, children: [
1681
+ header && /* @__PURE__ */ jsx34("header", { className: "hf-page-layout__header", children: header }),
1682
+ sidebar && /* @__PURE__ */ jsx34("aside", { className: "hf-page-layout__sidebar", children: sidebar }),
1683
+ /* @__PURE__ */ jsx34("main", { className: "hf-page-layout__main", children })
1594
1684
  ] });
1595
1685
  }
1596
1686
 
1597
1687
  // src/layout/Skeleton.tsx
1598
- import { jsx as jsx34 } from "react/jsx-runtime";
1688
+ import { jsx as jsx35 } from "react/jsx-runtime";
1599
1689
  function Skeleton({ width = "100%", height = 16, radius, circle, animated = true, className = "", style, ...props }) {
1600
1690
  const value = (input) => typeof input === "number" ? `${input}px` : input;
1601
- return /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: `hf-skeleton ${animated ? "is-animated" : ""} ${circle ? "is-circle" : ""} ${className}`.trim(), style: { width: value(width), height: value(height), borderRadius: radius ? value(radius) : void 0, ...style }, ...props });
1691
+ return /* @__PURE__ */ jsx35("span", { "aria-hidden": "true", className: `hf-skeleton ${animated ? "is-animated" : ""} ${circle ? "is-circle" : ""} ${className}`.trim(), style: { width: value(width), height: value(height), borderRadius: radius ? value(radius) : void 0, ...style }, ...props });
1602
1692
  }
1603
1693
 
1604
1694
  // src/feedback/Loading.tsx
1605
- import { jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
1695
+ import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
1606
1696
  function Spinner({ label = "\u6B63\u5728\u52A0\u8F7D", size = 20, className = "" }) {
1607
- return /* @__PURE__ */ jsx35("span", { className: `hf-loading-spinner ${className}`.trim(), role: "status", "aria-label": label, style: { "--hf-loading-size": `${size}px` } });
1697
+ return /* @__PURE__ */ jsx36("span", { className: `hf-loading-spinner ${className}`.trim(), role: "status", "aria-label": label, style: { "--hf-loading-size": `${size}px` } });
1608
1698
  }
1609
1699
  function LoadingDots({ label = "\u6B63\u5728\u52A0\u8F7D" }) {
1610
- return /* @__PURE__ */ jsxs29("span", { className: "hf-loading-dots", role: "status", "aria-label": label, children: [
1611
- /* @__PURE__ */ jsx35("i", {}),
1612
- /* @__PURE__ */ jsx35("i", {}),
1613
- /* @__PURE__ */ jsx35("i", {})
1700
+ return /* @__PURE__ */ jsxs30("span", { className: "hf-loading-dots", role: "status", "aria-label": label, children: [
1701
+ /* @__PURE__ */ jsx36("i", {}),
1702
+ /* @__PURE__ */ jsx36("i", {}),
1703
+ /* @__PURE__ */ jsx36("i", {})
1614
1704
  ] });
1615
1705
  }
1616
1706
  function ProgressBar({ value, label, indeterminate = false, className = "" }) {
1617
1707
  const percent = Math.min(100, Math.max(0, value ?? 0));
1618
- return /* @__PURE__ */ jsxs29("div", { className: `hf-progress ${indeterminate ? "is-indeterminate" : ""} ${className}`.trim(), children: [
1619
- label && /* @__PURE__ */ jsxs29("div", { className: "hf-progress__label", children: [
1620
- /* @__PURE__ */ jsx35("span", { children: label }),
1621
- !indeterminate && /* @__PURE__ */ jsxs29("strong", { children: [
1708
+ return /* @__PURE__ */ jsxs30("div", { className: `hf-progress ${indeterminate ? "is-indeterminate" : ""} ${className}`.trim(), children: [
1709
+ label && /* @__PURE__ */ jsxs30("div", { className: "hf-progress__label", children: [
1710
+ /* @__PURE__ */ jsx36("span", { children: label }),
1711
+ !indeterminate && /* @__PURE__ */ jsxs30("strong", { children: [
1622
1712
  percent,
1623
1713
  "%"
1624
1714
  ] })
1625
1715
  ] }),
1626
- /* @__PURE__ */ jsx35("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": indeterminate ? void 0 : percent, children: /* @__PURE__ */ jsx35("i", { style: { "--hf-progress": `${percent}%` } }) })
1716
+ /* @__PURE__ */ jsx36("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": indeterminate ? void 0 : percent, children: /* @__PURE__ */ jsx36("i", { style: { "--hf-progress": `${percent}%` } }) })
1627
1717
  ] });
1628
1718
  }
1629
1719
  function ProgressRing({ value, size = 72, label }) {
1630
1720
  const percent = Math.min(100, Math.max(0, value));
1631
- return /* @__PURE__ */ jsx35("span", { className: "hf-progress-ring", role: "progressbar", "aria-label": label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percent, style: { "--hf-ring-value": `${percent * 3.6}deg`, "--hf-ring-size": `${size}px` }, children: /* @__PURE__ */ jsxs29("strong", { children: [
1721
+ return /* @__PURE__ */ jsx36("span", { className: "hf-progress-ring", role: "progressbar", "aria-label": label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percent, style: { "--hf-ring-value": `${percent * 3.6}deg`, "--hf-ring-size": `${size}px` }, children: /* @__PURE__ */ jsxs30("strong", { children: [
1632
1722
  percent,
1633
1723
  "%"
1634
1724
  ] }) });
1635
1725
  }
1636
1726
  function LoadingOverlay({ active = true, label = "\u6B63\u5728\u51C6\u5907\u5185\u5BB9", className = "", children, ...props }) {
1637
- return /* @__PURE__ */ jsxs29("div", { className: `hf-loading-overlay ${className}`.trim(), "aria-busy": active, ...props, children: [
1727
+ return /* @__PURE__ */ jsxs30("div", { className: `hf-loading-overlay ${className}`.trim(), "aria-busy": active, ...props, children: [
1638
1728
  children,
1639
- active && /* @__PURE__ */ jsxs29("div", { className: "hf-loading-overlay__veil", role: "status", children: [
1640
- /* @__PURE__ */ jsx35(Spinner, { label, size: 28 }),
1641
- /* @__PURE__ */ jsx35("span", { children: label })
1729
+ active && /* @__PURE__ */ jsxs30("div", { className: "hf-loading-overlay__veil", role: "status", children: [
1730
+ /* @__PURE__ */ jsx36(Spinner, { label, size: 28 }),
1731
+ /* @__PURE__ */ jsx36("span", { children: label })
1642
1732
  ] })
1643
1733
  ] });
1644
1734
  }
1645
1735
 
1646
- // src/forms/Select.tsx
1647
- import { forwardRef as forwardRef5, useEffect as useEffect7, useId as useId6, useRef as useRef4, useState as useState16 } from "react";
1648
- import { jsx as jsx36, jsxs as jsxs30 } from "react/jsx-runtime";
1649
- var Select = forwardRef5(function Select2({ id, label, hint, error, options, placeholder, className = "", value, defaultValue, onChange, disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, ...props }, forwardedRef) {
1650
- const generatedId = useId6();
1651
- const inputId = id ?? generatedId;
1652
- const triggerId = `${inputId}-trigger`;
1653
- const listboxId = `${inputId}-listbox`;
1654
- const descriptionId = `${inputId}-description`;
1655
- const [open, setOpen] = useState16(false);
1656
- const rootRef = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
1657
- const nativeRef = useRef4(null);
1658
- const [innerValue, setInnerValue] = useState16(() => String(defaultValue ?? (placeholder ? "" : options.find((option) => !option.disabled)?.value ?? "")));
1659
- const selectedValue = value === void 0 ? innerValue : String(value);
1660
- const selectedOption = options.find((option) => option.value === selectedValue);
1661
- const enabledIndices = options.map((option, index) => option.disabled ? -1 : index).filter((index) => index >= 0);
1662
- const selectedIndex = options.findIndex((option) => option.value === selectedValue);
1663
- const [activeIndex, setActiveIndex] = useState16(selectedIndex >= 0 ? selectedIndex : enabledIndices[0] ?? -1);
1664
- const assignRef = (node) => {
1665
- nativeRef.current = node;
1666
- if (typeof forwardedRef === "function") forwardedRef(node);
1667
- else if (forwardedRef) forwardedRef.current = node;
1668
- };
1669
- const handleNativeChange = (event) => {
1670
- if (value === void 0) setInnerValue(event.currentTarget.value);
1671
- onChange?.(event);
1672
- };
1673
- const choose = (nextValue) => {
1674
- const native = nativeRef.current;
1675
- if (!native) return;
1676
- Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, "value")?.set?.call(native, nextValue);
1677
- native.dispatchEvent(new Event("change", { bubbles: true }));
1678
- if (value === void 0) setInnerValue(nextValue);
1679
- setOpen(false);
1680
- window.requestAnimationFrame(() => document.getElementById(triggerId)?.focus());
1681
- };
1682
- useEffect7(() => {
1683
- if (selectedIndex >= 0) setActiveIndex(selectedIndex);
1684
- }, [selectedIndex]);
1685
- const move = (direction) => {
1686
- if (!enabledIndices.length) return;
1687
- const current = enabledIndices.indexOf(activeIndex);
1688
- const next = current < 0 ? 0 : (current + direction + enabledIndices.length) % enabledIndices.length;
1689
- setActiveIndex(enabledIndices[next]);
1690
- };
1691
- const handleKeyDown = (event) => {
1692
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
1693
- event.preventDefault();
1694
- if (!open) setOpen(true);
1695
- move(event.key === "ArrowDown" ? 1 : -1);
1696
- } else if ((event.key === "Enter" || event.key === " ") && open) {
1697
- event.preventDefault();
1698
- const option = options[activeIndex];
1699
- if (option && !option.disabled) choose(option.value);
1700
- } else if (event.key === "Escape" && open) {
1701
- event.preventDefault();
1702
- setOpen(false);
1703
- } else if (event.key === "Home" && open && enabledIndices.length) {
1704
- event.preventDefault();
1705
- setActiveIndex(enabledIndices[0]);
1706
- } else if (event.key === "End" && open && enabledIndices.length) {
1707
- event.preventDefault();
1708
- setActiveIndex(enabledIndices[enabledIndices.length - 1]);
1709
- } else if (event.key === "Tab") setOpen(false);
1710
- };
1711
- return /* @__PURE__ */ jsxs30("div", { className: `hf-field ${className}`.trim(), ref: rootRef, children: [
1712
- label && /* @__PURE__ */ jsx36("label", { className: "hf-field__label", htmlFor: triggerId, children: label }),
1713
- /* @__PURE__ */ jsxs30("div", { className: `hf-select-shell ${open ? "hf-select-shell--open" : ""} ${error ? "hf-select-shell--error" : ""}`, children: [
1714
- /* @__PURE__ */ jsxs30("select", { ref: assignRef, id: inputId, className: "hf-select-native", tabIndex: -1, "aria-hidden": "true", value: selectedValue, disabled, onChange: handleNativeChange, ...props, children: [
1715
- placeholder && /* @__PURE__ */ jsx36("option", { value: "", disabled: true, children: placeholder }),
1716
- options.map((option) => /* @__PURE__ */ jsx36("option", { value: option.value, disabled: option.disabled, children: typeof option.label === "string" ? option.label : option.value }, option.value))
1717
- ] }),
1718
- /* @__PURE__ */ jsxs30("button", { id: triggerId, type: "button", className: "hf-select", disabled, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": open ? listboxId : void 0, "aria-activedescendant": open && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : void 0, "aria-invalid": Boolean(error), "aria-describedby": hint || error ? descriptionId : void 0, onClick: () => {
1719
- setActiveIndex(selectedIndex >= 0 ? selectedIndex : enabledIndices[0] ?? -1);
1720
- setOpen((current) => !current);
1721
- }, onKeyDown: handleKeyDown, children: [
1722
- /* @__PURE__ */ jsx36("span", { className: !selectedOption ? "hf-select__placeholder" : "", children: selectedOption?.label ?? placeholder ?? "\u8BF7\u9009\u62E9" }),
1723
- /* @__PURE__ */ jsx36("svg", { className: "hf-select__chevron", viewBox: "0 0 16 16", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx36("path", { d: open ? "m4.5 9.75 3.5-3.5 3.5 3.5" : "m4.5 6.25 3.5 3.5 3.5-3.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
1724
- ] }),
1725
- open && /* @__PURE__ */ jsx36("div", { id: listboxId, className: "hf-select-menu", role: "listbox", "aria-labelledby": triggerId, children: options.map((option, index) => /* @__PURE__ */ jsxs30("button", { id: `${listboxId}-option-${index}`, type: "button", role: "option", "aria-selected": option.value === selectedValue, disabled: option.disabled, className: index === activeIndex ? "is-active" : "", onPointerMove: () => !option.disabled && setActiveIndex(index), onClick: () => choose(option.value), children: [
1726
- /* @__PURE__ */ jsx36("span", { children: option.label }),
1727
- option.value === selectedValue && /* @__PURE__ */ jsx36("svg", { viewBox: "0 0 16 16", width: "16", height: "16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx36("path", { d: "m3.5 8 3 3 6-6", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) })
1728
- ] }, option.value)) })
1729
- ] }),
1730
- (error || hint) && /* @__PURE__ */ jsx36("span", { id: descriptionId, className: `hf-field__hint ${error ? "hf-field__hint--error" : ""}`, children: error ?? hint })
1731
- ] });
1732
- });
1733
-
1734
1736
  // src/forms/MultiSelect.tsx
1735
1737
  import { useId as useId7, useState as useState17 } from "react";
1736
1738
  import { jsx as jsx37, jsxs as jsxs31 } from "react/jsx-runtime";
@@ -1758,7 +1760,7 @@ function MultiSelect({ label, options, value, onChange, placeholder = "\u8BF7\u9
1758
1760
  /* @__PURE__ */ jsx37("button", { type: "button", "aria-label": `\u79FB\u9664 ${String(option?.label)}`, onClick: (event) => {
1759
1761
  event.stopPropagation();
1760
1762
  toggle(item);
1761
- }, children: "\xD7" })
1763
+ }, children: /* @__PURE__ */ jsx37(Icon, { name: "close", size: 13 }) })
1762
1764
  ] }, item);
1763
1765
  }) : /* @__PURE__ */ jsx37("em", { children: placeholder }) }),
1764
1766
  /* @__PURE__ */ jsx37(Icon, { name: "chevron-down", size: 16, className: "hf-multiselect__chevron" })
@@ -2276,7 +2278,7 @@ function Combobox({ label, options, value = "", onChange, placeholder = "\u641C\
2276
2278
  setActive(0);
2277
2279
  setOpen(true);
2278
2280
  }, onKeyDown }),
2279
- /* @__PURE__ */ jsx45("button", { type: "button", "aria-label": open ? "\u5173\u95ED\u9009\u9879" : "\u6253\u5F00\u9009\u9879", disabled, onClick: () => setOpen((current) => !current), children: "\u2304" })
2281
+ /* @__PURE__ */ jsx45("button", { type: "button", "aria-label": open ? "\u5173\u95ED\u9009\u9879" : "\u6253\u5F00\u9009\u9879", disabled, onClick: () => setOpen((current) => !current), children: /* @__PURE__ */ jsx45(Icon, { name: "chevron-down", size: 16 }) })
2280
2282
  ] }),
2281
2283
  open && /* @__PURE__ */ jsx45("div", { id: `${id}-listbox`, className: "hf-combobox__menu", role: "listbox", children: filtered.length ? filtered.map((option, index) => /* @__PURE__ */ jsxs38("button", { type: "button", role: "option", "aria-selected": option.value === value, disabled: option.disabled, className: index === active ? "is-active" : "", onPointerMove: () => setActive(index), onClick: () => choose(option.value), children: [
2282
2284
  /* @__PURE__ */ jsx45("span", { children: option.label }),
@@ -2324,10 +2326,7 @@ function Cascader({ options, value = [], onChange, label }) {
2324
2326
  }
2325
2327
  return /* @__PURE__ */ jsxs40("div", { className: "hf-field hf-cascader", children: [
2326
2328
  label && /* @__PURE__ */ jsx47("span", { className: "hf-field__label", children: label }),
2327
- /* @__PURE__ */ jsx47("div", { children: levels.map((items, level) => /* @__PURE__ */ jsxs40("select", { "aria-label": `\u7B2C ${level + 1} \u7EA7`, value: value[level] ?? "", onChange: (event) => onChange([...value.slice(0, level), event.target.value]), children: [
2328
- /* @__PURE__ */ jsx47("option", { value: "", children: "\u8BF7\u9009\u62E9" }),
2329
- items.map((item) => /* @__PURE__ */ jsx47("option", { disabled: item.disabled, value: item.value, children: item.label }, item.value))
2330
- ] }, level)) })
2329
+ /* @__PURE__ */ jsx47("div", { children: levels.map((items, level) => /* @__PURE__ */ jsx47(Select, { "aria-label": `\u7B2C ${level + 1} \u7EA7`, className: "hf-cascader__level", value: value[level] ?? "", placeholder: "\u8BF7\u9009\u62E9", options: items.map((item) => ({ label: item.label, value: item.value, disabled: item.disabled })), onChange: (event) => onChange([...value.slice(0, level), event.target.value]) }, level)) })
2331
2330
  ] });
2332
2331
  }
2333
2332
  function TreeSelect({ options, value, onChange, label, placeholder = "\u9009\u62E9\u8282\u70B9" }) {
@@ -2337,8 +2336,8 @@ function TreeSelect({ options, value, onChange, label, placeholder = "\u9009\u62
2337
2336
  return /* @__PURE__ */ jsxs40("div", { className: "hf-field hf-tree-select", children: [
2338
2337
  label && /* @__PURE__ */ jsx47("span", { className: "hf-field__label", children: label }),
2339
2338
  /* @__PURE__ */ jsxs40("button", { type: "button", className: "hf-picker-trigger", "aria-expanded": open, onClick: () => setOpen(!open), children: [
2340
- all.find((item) => item.node.key === value)?.node.label ?? placeholder,
2341
- /* @__PURE__ */ jsx47("span", { children: "\u2304" })
2339
+ /* @__PURE__ */ jsx47("span", { children: all.find((item) => item.node.key === value)?.node.label ?? placeholder }),
2340
+ /* @__PURE__ */ jsx47(Icon, { className: "hf-picker-trigger__chevron", name: "chevron-down", size: 16 })
2342
2341
  ] }),
2343
2342
  open && /* @__PURE__ */ jsx47("div", { role: "listbox", children: all.map(({ node, depth }) => /* @__PURE__ */ jsx47("button", { type: "button", role: "option", "aria-selected": node.key === value, disabled: node.disabled, style: { paddingLeft: 12 + depth * 18 }, onClick: () => {
2344
2343
  onChange(node.key);
@@ -2391,7 +2390,7 @@ function SearchInput({ onSearch, loading, clearable = true, ...props }) {
2391
2390
  setValue(event.target.value);
2392
2391
  props.onChange?.(event);
2393
2392
  } }),
2394
- clearable && value && /* @__PURE__ */ jsx47("button", { type: "button", "aria-label": "\u6E05\u9664\u641C\u7D22", onClick: () => setValue(""), children: "\xD7" }),
2393
+ clearable && value && /* @__PURE__ */ jsx47("button", { type: "button", "aria-label": "\u6E05\u9664\u641C\u7D22", onClick: () => setValue(""), children: /* @__PURE__ */ jsx47(Icon, { name: "close", size: 14 }) }),
2395
2394
  /* @__PURE__ */ jsx47("button", { type: "submit", disabled: loading, children: loading ? "\u641C\u7D22\u4E2D" : "\u641C\u7D22" })
2396
2395
  ] });
2397
2396
  }
@@ -2407,7 +2406,7 @@ function Drawer({ open, title, children, onClose, footer, side = "right", size =
2407
2406
  return createPortal4(/* @__PURE__ */ jsx48("div", { className: "hf-drawer-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ jsxs41("div", { ref: drawerRef, className: `hf-drawer hf-drawer--${side} hf-drawer--${size}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [
2408
2407
  /* @__PURE__ */ jsxs41("header", { children: [
2409
2408
  /* @__PURE__ */ jsx48("h2", { id: titleId, children: title }),
2410
- /* @__PURE__ */ jsx48(Button, { variant: "quiet", size: "sm", onClick: onClose, "aria-label": "\u5173\u95ED\u62BD\u5C49", children: "\xD7" })
2409
+ /* @__PURE__ */ jsx48(Button, { variant: "quiet", size: "sm", iconOnly: true, leadingIcon: /* @__PURE__ */ jsx48(Icon, { name: "close", size: 16 }), onClick: onClose, "aria-label": "\u5173\u95ED\u62BD\u5C49" })
2411
2410
  ] }),
2412
2411
  /* @__PURE__ */ jsx48("div", { className: "hf-drawer__body", children }),
2413
2412
  footer && /* @__PURE__ */ jsx48("footer", { children: footer })
@@ -2492,7 +2491,7 @@ function Notification({ title, children, tone = "info", time, unread, action, on
2492
2491
  children && /* @__PURE__ */ jsx51("p", { children }),
2493
2492
  action && /* @__PURE__ */ jsx51("div", { className: "hf-notification__action", children: action })
2494
2493
  ] }),
2495
- onClose && /* @__PURE__ */ jsx51("button", { type: "button", "aria-label": "\u5173\u95ED\u901A\u77E5", onClick: onClose, children: "\xD7" })
2494
+ onClose && /* @__PURE__ */ jsx51("button", { type: "button", "aria-label": "\u5173\u95ED\u901A\u77E5", onClick: onClose, children: /* @__PURE__ */ jsx51(Icon, { name: "close", size: 15 }) })
2496
2495
  ] });
2497
2496
  }
2498
2497
  function Result({ status = "info", title, description, actions, extra }) {
@@ -2907,23 +2906,20 @@ function QueryBuilder({ fields, rules, onChange, conjunction = "and", onConjunct
2907
2906
  return /* @__PURE__ */ jsxs56("div", { className: "hf-query-builder", children: [
2908
2907
  /* @__PURE__ */ jsxs56("header", { children: [
2909
2908
  /* @__PURE__ */ jsx64("strong", { children: "\u6EE1\u8DB3" }),
2910
- /* @__PURE__ */ jsxs56("select", { "aria-label": "\u6761\u4EF6\u5173\u7CFB", value: conjunction, disabled, onChange: (event) => onConjunctionChange?.(event.target.value), children: [
2911
- /* @__PURE__ */ jsx64("option", { value: "and", children: "\u5168\u90E8\u6761\u4EF6" }),
2912
- /* @__PURE__ */ jsx64("option", { value: "or", children: "\u4EFB\u4E00\u6761\u4EF6" })
2913
- ] })
2909
+ /* @__PURE__ */ jsx64(Select, { className: "hf-query-builder__select", "aria-label": "\u6761\u4EF6\u5173\u7CFB", value: conjunction, disabled, options: [{ value: "and", label: "\u5168\u90E8\u6761\u4EF6" }, { value: "or", label: "\u4EFB\u4E00\u6761\u4EF6" }], onChange: (event) => onConjunctionChange?.(event.target.value) })
2914
2910
  ] }),
2915
2911
  /* @__PURE__ */ jsx64("div", { children: rules.map((rule, index) => {
2916
2912
  const field = fields.find((item) => item.key === rule.field) ?? fields[0];
2917
2913
  const operators = field?.operators ?? defaultOperators;
2918
2914
  return /* @__PURE__ */ jsxs56("div", { className: "hf-query-builder__rule", children: [
2919
2915
  /* @__PURE__ */ jsx64("span", { children: index + 1 }),
2920
- /* @__PURE__ */ jsx64("select", { "aria-label": `\u6761\u4EF6 ${index + 1} \u5B57\u6BB5`, value: rule.field, disabled, onChange: (event) => {
2916
+ /* @__PURE__ */ jsx64(Select, { className: "hf-query-builder__select", "aria-label": `\u6761\u4EF6 ${index + 1} \u5B57\u6BB5`, value: rule.field, disabled, options: fields.map((item) => ({ value: item.key, label: item.label })), onChange: (event) => {
2921
2917
  const next = fields.find((item) => item.key === event.target.value);
2922
2918
  update(rule.id, { field: next.key, operator: (next.operators ?? defaultOperators)[0]?.value ?? "equals", value: "" });
2923
- }, children: fields.map((item) => /* @__PURE__ */ jsx64("option", { value: item.key, children: item.label }, item.key)) }),
2924
- /* @__PURE__ */ jsx64("select", { "aria-label": `\u6761\u4EF6 ${index + 1} \u8FD0\u7B97\u7B26`, value: rule.operator, disabled, onChange: (event) => update(rule.id, { operator: event.target.value }), children: operators.map((item) => /* @__PURE__ */ jsx64("option", { value: item.value, children: item.label }, item.value)) }),
2919
+ } }),
2920
+ /* @__PURE__ */ jsx64(Select, { className: "hf-query-builder__select", "aria-label": `\u6761\u4EF6 ${index + 1} \u8FD0\u7B97\u7B26`, value: rule.operator, disabled, options: operators, onChange: (event) => update(rule.id, { operator: event.target.value }) }),
2925
2921
  /* @__PURE__ */ jsx64("input", { "aria-label": `\u6761\u4EF6 ${index + 1} \u503C`, type: field?.type ?? "text", value: rule.value, disabled, onChange: (event) => update(rule.id, { value: event.target.value }) }),
2926
- /* @__PURE__ */ jsx64("button", { type: "button", "aria-label": `\u5220\u9664\u6761\u4EF6 ${index + 1}`, disabled, onClick: () => onChange(rules.filter((item) => item.id !== rule.id)), children: "\xD7" })
2922
+ /* @__PURE__ */ jsx64("button", { type: "button", "aria-label": `\u5220\u9664\u6761\u4EF6 ${index + 1}`, disabled, onClick: () => onChange(rules.filter((item) => item.id !== rule.id)), children: /* @__PURE__ */ jsx64(Icon, { name: "close", size: 15 }) })
2927
2923
  ] }, rule.id);
2928
2924
  }) }),
2929
2925
  /* @__PURE__ */ jsx64("button", { type: "button", className: "hf-query-builder__add", disabled: disabled || !fields.length, onClick: add, children: "\uFF0B \u6DFB\u52A0\u6761\u4EF6" })
@@ -3071,12 +3067,9 @@ function FilterBuilder({ fields, value, onChange, disabled, addLabel = "\u6DFB\u
3071
3067
  /* @__PURE__ */ jsx66("div", { children: value.map((filter, index) => {
3072
3068
  const field = fields.find((item) => item.key === filter.field) ?? fields[0];
3073
3069
  return /* @__PURE__ */ jsxs58("div", { className: "hf-filter-builder__item", children: [
3074
- /* @__PURE__ */ jsx66("select", { "aria-label": `\u7B5B\u9009 ${index + 1} \u5B57\u6BB5`, value: filter.field, disabled, onChange: (event) => update(filter.id, { field: event.target.value, value: "" }), children: fields.map((item) => /* @__PURE__ */ jsx66("option", { value: item.key, children: item.label }, item.key)) }),
3075
- field?.options ? /* @__PURE__ */ jsxs58("select", { "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, value: filter.value, disabled, onChange: (event) => update(filter.id, { value: event.target.value }), children: [
3076
- /* @__PURE__ */ jsx66("option", { value: "", children: "\u8BF7\u9009\u62E9" }),
3077
- field.options.map((item) => /* @__PURE__ */ jsx66("option", { value: item.value, children: item.label }, item.value))
3078
- ] }) : /* @__PURE__ */ jsx66("input", { "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, type: field?.type ?? "text", value: filter.value, disabled, onChange: (event) => update(filter.id, { value: event.target.value }) }),
3079
- /* @__PURE__ */ jsx66("button", { type: "button", "aria-label": `\u5220\u9664\u7B5B\u9009 ${index + 1}`, disabled, onClick: () => onChange(value.filter((item) => item.id !== filter.id)), children: "\xD7" })
3070
+ /* @__PURE__ */ jsx66(Select, { className: "hf-filter-builder__select", "aria-label": `\u7B5B\u9009 ${index + 1} \u5B57\u6BB5`, value: filter.field, disabled, options: fields.map((item) => ({ value: item.key, label: item.label })), onChange: (event) => update(filter.id, { field: event.target.value, value: "" }) }),
3071
+ field?.options ? /* @__PURE__ */ jsx66(Select, { className: "hf-filter-builder__select", "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, value: filter.value, placeholder: "\u8BF7\u9009\u62E9", disabled, options: field.options, onChange: (event) => update(filter.id, { value: event.target.value }) }) : /* @__PURE__ */ jsx66("input", { "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, type: field?.type ?? "text", value: filter.value, disabled, onChange: (event) => update(filter.id, { value: event.target.value }) }),
3072
+ /* @__PURE__ */ jsx66("button", { type: "button", "aria-label": `\u5220\u9664\u7B5B\u9009 ${index + 1}`, disabled, onClick: () => onChange(value.filter((item) => item.id !== filter.id)), children: /* @__PURE__ */ jsx66(Icon, { name: "close", size: 15 }) })
3080
3073
  ] }, filter.id);
3081
3074
  }) }),
3082
3075
  /* @__PURE__ */ jsxs58("button", { type: "button", className: "hf-filter-builder__add", disabled: disabled || !fields.length, onClick: add, children: [