@zerodep-dev/vue-tsx-pro-ui 0.1.0 → 0.2.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.
Files changed (80) hide show
  1. package/dist/code-editor/CodeEditor.d.ts +18 -0
  2. package/dist/code-editor/CodeEditor.js +57 -0
  3. package/dist/code-editor/CodeEditor.js.map +1 -0
  4. package/dist/code-editor/editor.d.ts +52 -0
  5. package/dist/code-editor/editor.js +225 -0
  6. package/dist/code-editor/editor.js.map +1 -0
  7. package/dist/code-editor/index.d.ts +9 -0
  8. package/dist/code-editor/index.js +3 -0
  9. package/dist/config/lang/en-US.js +21 -3
  10. package/dist/config/lang/en-US.js.map +1 -1
  11. package/dist/config/lang/format.d.ts +2 -1
  12. package/dist/config/lang/format.js +9 -2
  13. package/dist/config/lang/format.js.map +1 -1
  14. package/dist/config/lang/lang.d.ts +19 -6
  15. package/dist/config/lang/lang.js +11 -2
  16. package/dist/config/lang/lang.js.map +1 -1
  17. package/dist/config/lang/zh-CN.js +21 -3
  18. package/dist/config/lang/zh-CN.js.map +1 -1
  19. package/dist/diagram/index.d.ts +2 -1
  20. package/dist/diagram/index.js +2 -1
  21. package/dist/diagram/layout.d.ts +57 -0
  22. package/dist/diagram/layout.js +50 -0
  23. package/dist/diagram/layout.js.map +1 -0
  24. package/dist/form/Field.d.ts +7 -0
  25. package/dist/form/Field.js +14 -3
  26. package/dist/form/Field.js.map +1 -1
  27. package/dist/form/useForm.d.ts +4 -1
  28. package/dist/form/useForm.js +35 -13
  29. package/dist/form/useForm.js.map +1 -1
  30. package/dist/index.d.ts +8 -5
  31. package/dist/index.js +8 -5
  32. package/dist/input/Combobox.js +1 -1
  33. package/dist/input/Combobox.js.map +1 -1
  34. package/dist/input/Mentions.js +1 -1
  35. package/dist/input/Mentions.js.map +1 -1
  36. package/dist/input/PeoplePickerPanel.js +11 -11
  37. package/dist/input/PeoplePickerPanel.js.map +1 -1
  38. package/dist/input/Select.js +1 -1
  39. package/dist/input/Select.js.map +1 -1
  40. package/dist/input/TreeSelect.js +1 -1
  41. package/dist/input/TreeSelect.js.map +1 -1
  42. package/dist/input/Upload.js +2 -1
  43. package/dist/input/Upload.js.map +1 -1
  44. package/dist/input/condition.d.ts +1 -1
  45. package/dist/input/condition.js +32 -14
  46. package/dist/input/condition.js.map +1 -1
  47. package/dist/input/people.d.ts +15 -14
  48. package/dist/input/people.js +5 -5
  49. package/dist/input/people.js.map +1 -1
  50. package/dist/input/remote-items.d.ts +4 -2
  51. package/dist/input/remote-items.js +7 -2
  52. package/dist/input/remote-items.js.map +1 -1
  53. package/dist/patterns/QueryTable.d.ts +3 -0
  54. package/dist/patterns/QueryTable.js +39 -14
  55. package/dist/patterns/QueryTable.js.map +1 -1
  56. package/dist/patterns/messages.d.ts +2 -0
  57. package/dist/patterns/messages.js +2 -0
  58. package/dist/patterns/messages.js.map +1 -1
  59. package/dist/utils/data/clone.d.ts +8 -0
  60. package/dist/utils/data/clone.js +21 -0
  61. package/dist/utils/data/clone.js.map +1 -0
  62. package/dist/utils/data/date.d.ts +10 -0
  63. package/dist/utils/data/date.js +13 -1
  64. package/dist/utils/data/date.js.map +1 -1
  65. package/dist/utils/data/numeric.d.ts +7 -0
  66. package/dist/utils/data/numeric.js +46 -1
  67. package/dist/utils/data/numeric.js.map +1 -1
  68. package/dist/utils/dom/download.d.ts +8 -1
  69. package/dist/utils/dom/download.js +19 -2
  70. package/dist/utils/dom/download.js.map +1 -1
  71. package/dist/utils/request/error-message.d.ts +17 -0
  72. package/dist/utils/request/error-message.js +50 -0
  73. package/dist/utils/request/error-message.js.map +1 -0
  74. package/dist/utils/request/http.d.ts +68 -4
  75. package/dist/utils/request/http.js +116 -23
  76. package/dist/utils/request/http.js.map +1 -1
  77. package/dist/utils/request/use-autosave.d.ts +35 -0
  78. package/dist/utils/request/use-autosave.js +69 -0
  79. package/dist/utils/request/use-autosave.js.map +1 -0
  80. package/package.json +57 -4
package/dist/index.d.ts CHANGED
@@ -207,7 +207,7 @@ import './config/theme/token-names';
207
207
  export { t } from './config/theme/tokens';
208
208
  export { enUS } from './config/lang/en-US';
209
209
  export { useFormat, type NumericFormat, type RelativeFormatOptions } from './config/lang/format';
210
- export { defineLang, type Directions, type HourCycles, type Lang, type LangMessages, } from './config/lang/lang';
210
+ export { defineLang, type Directions, type ErrorCodeText, type HourCycles, type Lang, type LangMessages, } from './config/lang/lang';
211
211
  export { useMessages, type MessageTable } from './config/lang/messages';
212
212
  export { zhCN } from './config/lang/zh-CN';
213
213
  export { applyStyleAttrs, dataAttrs, defaultLabelledBy, elementProps, hasContent, mergeAttrs, mergePartProps, mergeProps, type PartProps, type TriggerProps, } from './utils/props';
@@ -224,7 +224,7 @@ export { announce, type Politeness, type Politenesses } from './utils/dom/announ
224
224
  export { caretAnchor, caretRect } from './utils/dom/caret';
225
225
  export { useClipboard, type ClipboardOptions, type ClipboardState } from './utils/dom/clipboard';
226
226
  export { inlineArrows, isRtl, type InlineArrows } from './utils/dom/direction';
227
- export { downloadFile } from './utils/dom/download';
227
+ export { downloadFile, pickFile } from './utils/dom/download';
228
228
  export { toElement } from './utils/dom/element';
229
229
  export { useEventListener, type ListenerTarget } from './utils/dom/event-listener';
230
230
  export { anchoredPanelSx, anchorFloating, createAnchoredLayer, floatingStyles, pointAnchor, useAnchoredPopover, type Anchored, type AnchoredLayer, type AnchoredPopoverEvents, type AnchoredPopoverState, type FloatingAnchor, type FloatingOptions, type FloatingPlacement, type FloatingPlacements, type RestoreFocus, } from './utils/dom/floating';
@@ -251,16 +251,17 @@ export { collectHeadings, useScrollSpy, type HeadingEntry, type ScrollSpyOptions
251
251
  export { useSortable, type SortableGhost, type SortableGroups, type SortableOptions, type SortableOrientations, type SortableState, type SortableTarget, } from './utils/dom/sortable';
252
252
  export { usePersistentState, type PersistentStateOptions } from './utils/dom/storage';
253
253
  export { createTypeahead, type Typeahead } from './utils/dom/typeahead';
254
+ export { cloneValue } from './utils/data/clone';
254
255
  export { createComparer, createMatcher, isDateValue, sortByValue, sortByValues, type SortKey, type SortValue, } from './utils/data/collation';
255
256
  export { CONTRAST_AA, contrastRatio, parseColor, readableText, toHex, withAlpha, } from './utils/data/color';
256
- export { calendarOf, clampDate, compareDates, daysBetween, fullIsoDay, isDateDisabled, isInRange, isoDayOfWeek, isOutOfRange, isOutsideDecade, isoWeekOf, isoWeeksInYear, isSameDate, lastIsoDay, monthGrid, monthsOfYear, orderedRange, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, presetIsoRange, presetRange, rangeDays, rangeHasUnavailable, relativeUnit, shiftIsoDate, todayIso, toDayOfWeek, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, truncateDate, weekdayNames, weekOfYear, yearsOfDecade, type DateLimits, type DateRange, type DateRangePreset, type DateRangePresets, type DateUnit, type DateUnits, type MonthGridOptions, type WeekdayFormats, type WeekOptions, } from './utils/data/date';
257
+ export { calendarOf, clampDate, compareDates, dayRangeBounds, daysBetween, fullIsoDay, isDateDisabled, isInRange, isoDayOfWeek, isOutOfRange, isOutsideDecade, isoWeekOf, isoWeeksInYear, isSameDate, lastIsoDay, monthGrid, monthsOfYear, orderedRange, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, presetIsoRange, presetRange, rangeDays, rangeHasUnavailable, relativeUnit, shiftIsoDate, todayIso, toDayOfWeek, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, truncateDate, weekdayNames, weekOfYear, yearsOfDecade, type DateLimits, type DateRange, type DateRangePreset, type DateRangePresets, type DateUnit, type DateUnits, type MonthGridOptions, type WeekdayFormats, type WeekOptions, } from './utils/data/date';
257
258
  export { diffFields, type FieldDiff } from './utils/data/diff';
258
259
  export { sameValue } from './utils/data/equality';
259
260
  export { createHistory, type History, type HistoryCommitOptions, type HistoryGesture, type HistoryOptions, } from './utils/data/history';
260
261
  export { cachedIntl } from './utils/data/intl-cache';
261
262
  export { normalizeNumber, parseNumber } from './utils/data/number-parse';
262
263
  export { clamp, snapToStep } from './utils/data/number';
263
- export { addNumeric, compareNumeric, isDecimal, isNumeric, isNumericText, multiplyNumeric, numericKind, numericText, sameNumeric, shiftDecimal, snapNumeric, toNumber, toNumericKind, type NumericKind, type NumericValue, } from './utils/data/numeric';
264
+ export { addNumeric, compareDecimalText, compareNumeric, decimalTextOf, isDecimal, isNumeric, isNumericText, multiplyNumeric, numericKind, numericText, sameNumeric, shiftDecimal, snapNumeric, toNumber, toNumericKind, type NumericKind, type NumericValue, } from './utils/data/numeric';
264
265
  export { paginationItems, type PaginationEllipsis, type PaginationOptions, } from './utils/data/pagination';
265
266
  export { selectedValues, toggleSelection, type MultipleSelectionProps, type SelectionModes, type SelectionOptions, type SelectionProps, type SingleSelectionProps, } from './utils/data/selection';
266
267
  export { createStatusMap, type StatusDefinition, type StatusMap } from './utils/data/status';
@@ -269,7 +270,9 @@ export { buildTree, checkedByStrategy, checkStates, filterTree, flattenTree, ind
269
270
  export { addWorkdays, createWorkCalendar, deadlineOf, useWorkCalendar, weekdayCalendar, workdaysBetween, type Deadline, type DeadlineInput, type DeadlineStates, type WorkCalendar, type WorkCalendarOptions, } from './utils/data/workdays';
270
271
  export { useVirtualizer, type UseVirtualizerOptions, type VirtualView, } from './utils/virtual/use-virtualizer';
271
272
  export { computeMeasurements, defaultRangeExtractor, findVisibleRange, isWindow, Virtualizer, type ExtractorRange, type ScrollAligns, type VirtualItem, type VirtualizerOptions, type VirtualScrollOptions, type VisibleRange, } from './utils/virtual/virtualizer';
272
- export { createHttpClient, HttpError, isAbortError, useHttp, type FetchClient, type HttpClient, type HttpClientOptions, type HttpErrorContext, type HttpMethod, type HttpRequest, type QueryValue, } from './utils/request/http';
273
+ export { codeText, errorCodeOf, errorCodeText, errorMessage, useErrorMessage, } from './utils/request/error-message';
274
+ export { createHttpClient, HTTP_ERROR_CODES, HttpError, isAbortError, OK_CODE, scopeHttp, useHttp, type ApiEnvelope, type ApiErrorDetail, type FetchClient, type HttpClient, type HttpClientOptions, type HttpErrorCode, type HttpErrorContext, type HttpMethod, type HttpRequest, type QueryValue, } from './utils/request/http';
275
+ export { useAutosave, type Autosave, type AutosaveOptions, type AutosaveStatus, } from './utils/request/use-autosave';
273
276
  export { useRequest, type RequestOptions, type RequestState } from './utils/request/use-request';
274
277
  export { fromWire, toWire, wireText, type WireReviveOptions, type WireScalar, type WireType, type WireTypes, } from './utils/request/wire';
275
278
  export { useActiveIndicator, type ActiveIndicatorOptions, type IndicatorAxes, } from './utils/motion/active-indicator';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { cachedIntl } from "./utils/data/intl-cache.js";
2
2
  import { clamp, snapToStep } from "./utils/data/number.js";
3
- import { addNumeric, compareNumeric, isDecimal, isNumeric, isNumericText, multiplyNumeric, numericKind, numericText, sameNumeric, shiftDecimal, snapNumeric, toNumber, toNumericKind } from "./utils/data/numeric.js";
3
+ import { addNumeric, compareDecimalText, compareNumeric, decimalTextOf, isDecimal, isNumeric, isNumericText, multiplyNumeric, numericKind, numericText, sameNumeric, shiftDecimal, snapNumeric, toNumber, toNumericKind } from "./utils/data/numeric.js";
4
4
  import { createComparer, createMatcher, isDateValue, sortByValue, sortByValues } from "./utils/data/collation.js";
5
5
  import { zhCN } from "./config/lang/zh-CN.js";
6
6
  import { t } from "./config/theme/tokens.js";
@@ -76,7 +76,7 @@ import { ViewportFill, viewportFillDynamicStyles, viewportFillStyles } from "./l
76
76
  import { selectedValues, toggleSelection } from "./utils/data/selection.js";
77
77
  import { Collapse, collapseStyles } from "./display/Collapse.js";
78
78
  import { Accordion, AccordionContext, AccordionItem, accordionStyles } from "./display/Accordion.js";
79
- import { calendarOf, clampDate, compareDates, daysBetween, fullIsoDay, isDateDisabled, isInRange, isOutOfRange, isOutsideDecade, isSameDate, isoDayOfWeek, isoWeekOf, isoWeeksInYear, lastIsoDay, monthGrid, monthsOfYear, orderedRange, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, presetIsoRange, presetRange, rangeDays, rangeHasUnavailable, relativeUnit, shiftIsoDate, toDayOfWeek, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, todayIso, truncateDate, weekOfYear, weekdayNames, yearsOfDecade } from "./utils/data/date.js";
79
+ import { calendarOf, clampDate, compareDates, dayRangeBounds, daysBetween, fullIsoDay, isDateDisabled, isInRange, isOutOfRange, isOutsideDecade, isSameDate, isoDayOfWeek, isoWeekOf, isoWeeksInYear, lastIsoDay, monthGrid, monthsOfYear, orderedRange, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, presetIsoRange, presetRange, rangeDays, rangeHasUnavailable, relativeUnit, shiftIsoDate, toDayOfWeek, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, todayIso, truncateDate, weekOfYear, weekdayNames, yearsOfDecade } from "./utils/data/date.js";
80
80
  import { useFormat } from "./config/lang/format.js";
81
81
  import { useSpring, useTween } from "./utils/motion/tween.js";
82
82
  import { AnimatedNumber, animatedNumberStyles } from "./display/AnimatedNumber.js";
@@ -170,7 +170,8 @@ import { NumberField } from "./input/NumberField.js";
170
170
  import { PageJump, pageJumpStyles } from "./navigation/PageJump.js";
171
171
  import { ListPopover, listPopoverStyles } from "./input/ListPopover.js";
172
172
  import { fromWire, toWire, wireText } from "./utils/request/wire.js";
173
- import { HttpError, createHttpClient, isAbortError, useHttp } from "./utils/request/http.js";
173
+ import { HTTP_ERROR_CODES, HttpError, OK_CODE, createHttpClient, isAbortError, scopeHttp, useHttp } from "./utils/request/http.js";
174
+ import { codeText, errorCodeOf, errorCodeText, errorMessage, useErrorMessage } from "./utils/request/error-message.js";
174
175
  import { useRequest } from "./utils/request/use-request.js";
175
176
  import { useRemoteItems } from "./input/remote-items.js";
176
177
  import { SelectedTags, selectedTagsStyles } from "./input/SelectedTags.js";
@@ -241,6 +242,7 @@ import { FormSection, formSectionColumnStyles, formSectionStyles } from "./form/
241
242
  import { createConstraints } from "./form/form-constraints.js";
242
243
  import { useLeaveConfirmation } from "./form/leave-confirmation.js";
243
244
  import { bigintSchema, decimalSchema, idCardSchema, isValidIdCard, phoneSchema } from "./form/schemas.js";
245
+ import { cloneValue } from "./utils/data/clone.js";
244
246
  import { useForm } from "./form/useForm.js";
245
247
  import { ColumnFilterButton, ColumnMenuButton, columnHeaderActionStyles } from "./table/ColumnHeaderActions.js";
246
248
  import { ColumnResizer } from "./table/ColumnResizer.js";
@@ -273,10 +275,11 @@ import { revealTransition } from "./utils/motion/reveal.js";
273
275
  import { createThemePreference } from "./config/theme/preference.js";
274
276
  import { enUS } from "./config/lang/en-US.js";
275
277
  import { useMessages } from "./config/lang/messages.js";
276
- import { downloadFile } from "./utils/dom/download.js";
278
+ import { downloadFile, pickFile } from "./utils/dom/download.js";
277
279
  import { useFullscreen } from "./utils/dom/fullscreen.js";
278
280
  import { backgroundOf, rasterizeSvg } from "./utils/dom/rasterize.js";
279
281
  import { createHistory } from "./utils/data/history.js";
280
282
  import { createStatusMap } from "./utils/data/status.js";
281
283
  import { addWorkdays, createWorkCalendar, deadlineOf, useWorkCalendar, weekdayCalendar, workdaysBetween } from "./utils/data/workdays.js";
282
- export { Accordion, AccordionContext, AccordionItem, Affix, Alert, AlertDialog, AnimatedNumber, AsideLayout, AttachedContext, Autocomplete, Avatar, AvatarGroup, AvatarGroupContext, BackTop, Badge, Banner, Blockquote, Breadcrumbs, Button, ButtonBase, ButtonGroup, ButtonGroupContext, COLUMN_FLEX_MIN_WIDTH, COLUMN_MIN_WIDTH, CONTRAST_AA, Calendar, CalendarBoard, CalendarView, Card, Cascader, CharacterCount, Checkbox, CheckboxGroup, CheckboxGroupContext, Checklist, ClearButton, CloseButton, Code, CodeBlock, Collapse, Collapsible, ColorField, ColumnFilterButton, ColumnMenuButton, ColumnResizer, ColumnSettings, ColumnTable, Combobox, CommandPalette, ConditionBuilder, ConfigContext, ConfigScope, Container, ContextMenu, ControlGroup, CopyButton, Countdown, DEFAULT_THEME_STORAGE_KEY, DataTable, DataTableDetailRow, DataTableRow, DataTableView, DateField, DatePicker, DateRangePicker, DateSegmentGroup, DateTime, Descriptions, Dialog, Drawer, Ellipsis, Em, Empty, Field, FieldCompare, FieldContext, FieldLayoutContext, FileDrop, Flex, FlexList, FlexOrderedList, Form, FormContext, FormErrorSummary, FormSection, FormValue, Gauge, Grid, GridItem, GridList, GridListItem, H1, H2, H3, H4, H5, H6, HoverCard, HttpError, Icon, IconButton, IconLinkButton, Image, ImageGroup, Indicator, ItemList, ItemListItem, Kbd, Label, Lightbox, Link, LinkButton, List, ListContext, ListItem, ListPopover, Listbox, ListboxView, LoadingBar, LoadingOverlay, Mark, Marquee, MentionText, Mentions, Menu, MenuCheckboxItem, MenuContext, MenuGroup, MenuItem, MenuLinkItem, MenuRadioGroup, MenuRadioGroupContext, MenuRadioItem, MenuSub, ModalCore, NavBar, NavCompactContext, NavGroup, NavGroupContext, NavItem, NavList, NavSection, NumberField, NumberRangeField, OrderedList, OtpField, OverlayScrollbar, PageJump, PageScrollbar, PageSizeSelect, Pager, Pagination, PaginationBar, Paragraph, PeoplePicker, PeoplePickerPanel, PivotTable, Popconfirm, Popover, Progress, ProportionBar, Prose, Provider, QuarterCalendar, Radio, RadioGroup, RadioGroupContext, RangeCalendar, Rating, RelativeTime, ResizeHandle, Result, SHIMMER_STAGGER, SYSTEM_THEME, ScrollArea, SegmentedField, Select, SelectedTags, SelectionBar, Separator, Skeleton, SkeletonText, SkipLink, Slider, Small, Sortable, Sparkline, Spinner, Splitter, Stat, StatGroup, StatusBadge, StatusDot, Steps, Strong, Switch, Tab, TabList, TabPanel, Table, TableBody, TableCaption, TableCell, TableContext, TableFoot, TableHead, TableHeaderCell, TableOfContents, TableRow, TableSectionContext, Tabs, TabsContext, Tag, TagsInput, Text, TextField, Textarea, TimeField, TimePicker, Timeline, ToastItem, Toaster, ToggleGroup, ToggleGroupContext, ToggleItem, Toolbar, ToolbarContext, Tooltip, Tour, Transfer, Tree, TreeDataTable, TreeSelect, TreeTransfer, Upload, ViewportFill, VirtualList, Virtualizer, VisuallyHidden, Watermark, accordionStyles, activeOptionId, addNumeric, addWorkdays, affixPositionStyles, affixStyles, afterTransitions, alertRecipe, anchorFloating, anchoredPanelSx, animatedNumberStyles, announce, applyStyleAttrs, ariaKeyShortcut, arrangeColumns, asideLayoutDynamicStyles, asideLayoutStyles, attachedStyles, avatarGroupStyles, avatarRecipe, backTopStyles, backgroundOf, badgeParts, badgeRecipe, bankCardFormat, bannerStyles, batchLayout, bigintSchema, blockquoteStyles, breadcrumbsStyles, buildTree, builtinThemeBootColors, builtinThemeLabel, builtinThemes, buttonBaseStyles, buttonContent, buttonGroupStyles, buttonPart, buttonRecipe, buttonStyles, buttonSx, cachedIntl, calendarBoardStyles, calendarOf, calendarStyles, cardEffectDynamicStyles, cardRecipe, caretAnchor, caretRect, cascaderStyles, characterCountStyles, checkStates, checkboxStyles, checkedByStrategy, checklistStatusStyles, checklistStyles, childNodes, choiceInputStyles, choiceParts, choiceRecipe, clamp, clampDate, clampPan, clickOnShell, codeBlockDynamicStyles, codeBlockStyles, codeStyles, coffeeColors, coffeeTheme, collapseStyles, collectHeadings, colorFieldDynamicStyles, colorFieldStyles, columnAlign, columnFilter, columnGapStyles, columnHeaderActionStyles, columnSettingsStyles, columnTableStyles, columnType, columnValue, comboboxStyles, commandPaletteStyles, compareDates, compareNumeric, computeMeasurements, conditionBuilderStyles, conditionOperators, containerPaddingStyles, containerSizeStyles, containerStyles, contrastRatio, controlAffix, controlClear, controlGroupStyles, controlIcon, controlParts, copyButtonStyles, countdownParts, countdownStyles, createAnchoredLayer, createComparer, createConstraints, createContainer, createFlex, createGrid, createGridItem, createGroupedFormat, createHeading, createHistory, createHoverGroup, createHttpClient, createLoadingBar, createMatcher, createPresetIconButton, createStatusMap, createText, createThemePreference, createToaster, createTypeahead, createUi, createWorkCalendar, cyberpunkColors, cyberpunkFonts, cyberpunkRadii, cyberpunkShadows, cyberpunkTheme, darkColors, darkShadows, darkTheme, dataAttrs, dataTableDynamicStyles, dataTableRecipe, dataTableRowToneStyles, dataTableStateStyles, datePickerStyles, dateRangePickerStyles, dateSegmentStyles, dateUnitOf, daysBetween, deadlineOf, decimalSchema, defaultConfig, defaultFonts, defaultLabelledBy, defaultRadii, defaultRangeExtractor, defineLang, defineTheme, describeCondition, descriptionsGridStyles, descriptionsStyles, dialogRecipe, diffFields, disclosureStyles, dismissOnBackdrop, displayPosition, documentStyles, downloadFile, drawerRecipe, elementProps, ellipsisStyles, emptyRecipe, enUS, existingUploadFile, externalLinkAttrs, festiveColors, festiveShadows, festiveTheme, fieldColumnStyles, fieldCompareStyles, fieldStyles, fieldsToIso, fileDropStyles, filterOptions, filterRows, filterTree, findVisibleRange, firstSegmentOf, fitCount, fitTransform, flattenTree, flexAlignStyles, flexJustifyStyles, flexStyles, floatingStyles, focusAfterRemoval, focusCalendar, focusControl, focusFirst, focusOnShell, focusOrigin, focusRingStyles, fontSizeStyles, fontWeightStyles, forestColors, forestShadows, forestTheme, formErrorSummaryStyles, formSectionColumnStyles, formSectionStyles, formValueText, formatCell, formatConditionValue, formatHotkey, formatSorts, fromWire, fullIsoDay, gapStyles, gaugeStyles, gridAlignStyles, gridDynamicStyles, gridFlowStyles, gridFocus, gridItemDynamicStyles, gridItemStyles, gridJustifyStyles, gridStyles, handleCalendarKeydown, handleListKeydown, handleSegmentKeydown, hasContent, hasTimeOf, headerLayout, headingMarker, headingStyles, highContrastColors, highContrastRadii, highContrastShadows, highContrastTheme, hoverCardStyles, iconMarkup, iconStyles, idCardFormat, idCardSchema, imageDynamicStyles, imageFitStyles, imageGroupStyles, imageStyles, indexTree, indicatorRecipe, initials, inlineArrows, inputRecipe, interactionTransitions, isAbortError, isApplePlatform, isCellEditable, isComposingKey, isConditionGroup, isDateDisabled, isDateValue, isDecimal, isEditable, isExpandable, isInRange, isNumeric, isNumericText, isOutOfRange, isOutsideDecade, isPeriodDisabled, isRtl, isRuleComplete, isSameDate, isTimeGranularity, isValidIdCard, isWindow, isoDayOfWeek, isoToFields, isoToValue, isoWeekOf, isoWeeksInYear, itemListStyles, itemStyles, kbdStyles, labelStyles, lastIsoDay, lemonColors, lemonRadii, lemonShadows, lemonTheme, lightColors, lightShadows, lightTheme, lightboxDynamicStyles, lightboxStyles, lineClampStyles, linkRecipe, listPopoverStyles, listRole, listStyles, listStylesProse, listboxPositionStyles, listboxStyles, loadingBarScaleStyles, loadingBarStyles, loadingOverlayStyles, localPeopleSource, lockScroll, machineDateTime, markStyles, marqueeDynamicStyles, marqueeStyles, marqueeTrailStyles, matchesAccept, matchesCondition, matchesHotkey, mentionSegments, mentionStyles, mentionedValues, menuItemContent, menuItemDescribedBy, menuItemSx, menuStyles, mergeAttrs, mergeDefaults, mergePartProps, mergeProps, mergeStyles, midnightColors, midnightTheme, modalPartStyles, monthGrid, monthsOfYear, moveNode, multiplyNumeric, navBarStyles, navListStyles, needsValue, nextSort, nextSorts, normalizeNumber, numberRangeFieldStyles, numericKind, numericText, oceanColors, oceanRadii, oceanShadows, oceanTheme, openModalDialog, openSetter, operatorLabel, operatorsOf, orderedRange, otpFieldStyles, paddingInlineStyles, pageJumpStyles, pageScrollbarStyles, pageSizeSelectStyles, pagerStyles, paginationBarStyles, paginationItems, paginationStyles, paperColors, paperFonts, paperShadows, paperTheme, parseColor, parseCsv, parseDuration, parseHotkey, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, parseLineSpec, parseNumber, parseSorts, partAttrs, peopleKey, peoplePickerPanelDynamicStyles, peoplePickerPanelStyles, phoneFormat, phoneSchema, pickerPresetStyles, pivot, pivotTableStyles, plainText, pointAnchor, popconfirmStyles, popoverStyles, presenceStyles, presetIsoRange, presetRange, progressRecipe, progressTargetPositionStyles, progressWidthStyles, proportionBarDynamicStyles, proportionBarStyles, proseStyles, provideFieldLayout, provideGridColumns, providerStyles, queryCodecs, radioStyles, radiusStyles, rangeDays, rangeHasUnavailable, rasterizeSvg, ratingClipStyles, ratingStyles, ratingToneStyles, readCsvFile, readToken, readableText, readonlyChoiceHandlers, relativeFontSizeStyles, relativeUnit, renderPickerPresets, repeatedRowSpans, resizeHandleStyles, resolveTheme, resultRecipe, returnFocus, revealTransition, rippleHostStyles, ripplePlacementStyles, rippleStyles, rovingFocus, rowGapStyles, rowLabel, sakuraColors, sakuraRadii, sakuraShadows, sakuraTheme, sameNumeric, sameStickyOffsets, sameValue, scrollAreaBarStyles, scrollAreaStyles, segmentFields, segmentedFieldStyles, selectStyles, selectedTagsStyles, selectedValues, selectionBarStyles, separatorStyles, sheetFromMatrix, shiftDecimal, shiftIsoDate, shimmerStyles, shouldRouteClick, skeletonStyles, skeletonTextStyles, skeletonVariantStyles, skipLinkStyles, sliderPositionStyles, sliderStyles, snapNumeric, snapToStep, sortByValue, sortByValues, sortList, sortRows, sortableStyles, sparklineStyles, spinnerStyles, splitterDynamicStyles, splitterStyles, startMove, startRipple, statGroupDynamicStyles, statGroupStyles, statStyles, statusDotDynamicStyles, statusDotStyles, statusDotToneStyles, statusIcons, statusToneBorderStyles, statusToneStyles, statusToneSx, stepsStateStyles, stepsStyles, stickyOffsets, sumColumn, swatchStyles, switchStyles, syncChecked, t, tabListStyles, tabPanelStyles, tabRecipe, tableDynamicStyles, tableMinWidth, tableOfContentsStyles, tableParams, tableRecipe, tableToCsv, tabsStyles, tagStyles, tagsInputStyles, textAlignStyles, textComponentStyles, textStyles, textWrapStyles, textareaRowStyles, textareaStyles, themeAttrs, themeBootScript, themeTransition, themeTransitionOrInstant, themeVariables, timePickerStyles, timelineStyles, timelineToneStyles, toDateLimits, toDayOfWeek, toElement, toHex, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, toListboxOption, toNumber, toNumericKind, toPeopleValue, toText, toTime, toWire, toastCountdownStyles, toastPlacementStyles, toastStackStyles, toastStyles, todayIso, toggleChecked, toggleGroupStyles, toggleSelection, tokenValue, toneFillStyles, toneStyles, toolbarStyles, tooltipStyles, topModal, tourDynamicStyles, tourStyles, trackModal, transferStyles, transitions, trapFocus, treeDataTableIndentStyles, treeDataTableStyles, treeDynamicStyles, treePath, treeSelectStyles, treeStyles, truncateDate, uploadDynamicStyles, uploadStyles, useActiveIndicator, useAnchoredPopover, useAnimate, useButtonAppearance, useButtonBehavior, useCalendarState, useChoiceAppearance, useClipboard, useColumnDisplay, useConfig, useConfirm, useControlAppearance, useDateLocale, useDateSegments, useDefaults, useDelayedLoading, useDetachedDialog, useDetachedOverlay, useDialog, useDismissible, useDrawer, useEventListener, useFieldControl, useFieldSegments, useForm, useFormReset, useFormat, useFullscreen, useHotkeys, useHoverIntent, useHoverLayer, useHttp, useIntersectionObserver, useLang, useLayoutAnimation, useLazyContent, useLeaveConfirmation, useListState, useMediaQuery, useMenuItem, useMenuItemContentIds, useMessages, useNow, useOverflowItems, usePageVisible, usePanZoom, usePersistentState, usePickerPopover, usePointer, usePrefersDark, usePresence, useQueryState, useQueryStates, useRecipe, useReducedMotion, useRemoteItems, useRequest, useResizeObserver, useResultAnnouncement, useRipple, useRouterLink, useScrollSpy, useSelectedOptions, useSortable, useSpring, useTableQuery, useTextMatcher, useTreeExpansion, useTween, useVirtualizer, useWorkCalendar, valueShape, valueToIso, viewportFillDynamicStyles, viewportFillStyles, virtualListSizeStyles, virtualListStyles, visuallyHiddenStyles, watermarkStyles, watermarkTileStyles, weekOfYear, weekdayCalendar, weekdayNames, wireText, withAlpha, workdaysBetween, writeDateLike, yearsOfDecade, zhCN, zoomAround };
284
+ import { useAutosave } from "./utils/request/use-autosave.js";
285
+ export { Accordion, AccordionContext, AccordionItem, Affix, Alert, AlertDialog, AnimatedNumber, AsideLayout, AttachedContext, Autocomplete, Avatar, AvatarGroup, AvatarGroupContext, BackTop, Badge, Banner, Blockquote, Breadcrumbs, Button, ButtonBase, ButtonGroup, ButtonGroupContext, COLUMN_FLEX_MIN_WIDTH, COLUMN_MIN_WIDTH, CONTRAST_AA, Calendar, CalendarBoard, CalendarView, Card, Cascader, CharacterCount, Checkbox, CheckboxGroup, CheckboxGroupContext, Checklist, ClearButton, CloseButton, Code, CodeBlock, Collapse, Collapsible, ColorField, ColumnFilterButton, ColumnMenuButton, ColumnResizer, ColumnSettings, ColumnTable, Combobox, CommandPalette, ConditionBuilder, ConfigContext, ConfigScope, Container, ContextMenu, ControlGroup, CopyButton, Countdown, DEFAULT_THEME_STORAGE_KEY, DataTable, DataTableDetailRow, DataTableRow, DataTableView, DateField, DatePicker, DateRangePicker, DateSegmentGroup, DateTime, Descriptions, Dialog, Drawer, Ellipsis, Em, Empty, Field, FieldCompare, FieldContext, FieldLayoutContext, FileDrop, Flex, FlexList, FlexOrderedList, Form, FormContext, FormErrorSummary, FormSection, FormValue, Gauge, Grid, GridItem, GridList, GridListItem, H1, H2, H3, H4, H5, H6, HTTP_ERROR_CODES, HoverCard, HttpError, Icon, IconButton, IconLinkButton, Image, ImageGroup, Indicator, ItemList, ItemListItem, Kbd, Label, Lightbox, Link, LinkButton, List, ListContext, ListItem, ListPopover, Listbox, ListboxView, LoadingBar, LoadingOverlay, Mark, Marquee, MentionText, Mentions, Menu, MenuCheckboxItem, MenuContext, MenuGroup, MenuItem, MenuLinkItem, MenuRadioGroup, MenuRadioGroupContext, MenuRadioItem, MenuSub, ModalCore, NavBar, NavCompactContext, NavGroup, NavGroupContext, NavItem, NavList, NavSection, NumberField, NumberRangeField, OK_CODE, OrderedList, OtpField, OverlayScrollbar, PageJump, PageScrollbar, PageSizeSelect, Pager, Pagination, PaginationBar, Paragraph, PeoplePicker, PeoplePickerPanel, PivotTable, Popconfirm, Popover, Progress, ProportionBar, Prose, Provider, QuarterCalendar, Radio, RadioGroup, RadioGroupContext, RangeCalendar, Rating, RelativeTime, ResizeHandle, Result, SHIMMER_STAGGER, SYSTEM_THEME, ScrollArea, SegmentedField, Select, SelectedTags, SelectionBar, Separator, Skeleton, SkeletonText, SkipLink, Slider, Small, Sortable, Sparkline, Spinner, Splitter, Stat, StatGroup, StatusBadge, StatusDot, Steps, Strong, Switch, Tab, TabList, TabPanel, Table, TableBody, TableCaption, TableCell, TableContext, TableFoot, TableHead, TableHeaderCell, TableOfContents, TableRow, TableSectionContext, Tabs, TabsContext, Tag, TagsInput, Text, TextField, Textarea, TimeField, TimePicker, Timeline, ToastItem, Toaster, ToggleGroup, ToggleGroupContext, ToggleItem, Toolbar, ToolbarContext, Tooltip, Tour, Transfer, Tree, TreeDataTable, TreeSelect, TreeTransfer, Upload, ViewportFill, VirtualList, Virtualizer, VisuallyHidden, Watermark, accordionStyles, activeOptionId, addNumeric, addWorkdays, affixPositionStyles, affixStyles, afterTransitions, alertRecipe, anchorFloating, anchoredPanelSx, animatedNumberStyles, announce, applyStyleAttrs, ariaKeyShortcut, arrangeColumns, asideLayoutDynamicStyles, asideLayoutStyles, attachedStyles, avatarGroupStyles, avatarRecipe, backTopStyles, backgroundOf, badgeParts, badgeRecipe, bankCardFormat, bannerStyles, batchLayout, bigintSchema, blockquoteStyles, breadcrumbsStyles, buildTree, builtinThemeBootColors, builtinThemeLabel, builtinThemes, buttonBaseStyles, buttonContent, buttonGroupStyles, buttonPart, buttonRecipe, buttonStyles, buttonSx, cachedIntl, calendarBoardStyles, calendarOf, calendarStyles, cardEffectDynamicStyles, cardRecipe, caretAnchor, caretRect, cascaderStyles, characterCountStyles, checkStates, checkboxStyles, checkedByStrategy, checklistStatusStyles, checklistStyles, childNodes, choiceInputStyles, choiceParts, choiceRecipe, clamp, clampDate, clampPan, clickOnShell, cloneValue, codeBlockDynamicStyles, codeBlockStyles, codeStyles, codeText, coffeeColors, coffeeTheme, collapseStyles, collectHeadings, colorFieldDynamicStyles, colorFieldStyles, columnAlign, columnFilter, columnGapStyles, columnHeaderActionStyles, columnSettingsStyles, columnTableStyles, columnType, columnValue, comboboxStyles, commandPaletteStyles, compareDates, compareDecimalText, compareNumeric, computeMeasurements, conditionBuilderStyles, conditionOperators, containerPaddingStyles, containerSizeStyles, containerStyles, contrastRatio, controlAffix, controlClear, controlGroupStyles, controlIcon, controlParts, copyButtonStyles, countdownParts, countdownStyles, createAnchoredLayer, createComparer, createConstraints, createContainer, createFlex, createGrid, createGridItem, createGroupedFormat, createHeading, createHistory, createHoverGroup, createHttpClient, createLoadingBar, createMatcher, createPresetIconButton, createStatusMap, createText, createThemePreference, createToaster, createTypeahead, createUi, createWorkCalendar, cyberpunkColors, cyberpunkFonts, cyberpunkRadii, cyberpunkShadows, cyberpunkTheme, darkColors, darkShadows, darkTheme, dataAttrs, dataTableDynamicStyles, dataTableRecipe, dataTableRowToneStyles, dataTableStateStyles, datePickerStyles, dateRangePickerStyles, dateSegmentStyles, dateUnitOf, dayRangeBounds, daysBetween, deadlineOf, decimalSchema, decimalTextOf, defaultConfig, defaultFonts, defaultLabelledBy, defaultRadii, defaultRangeExtractor, defineLang, defineTheme, describeCondition, descriptionsGridStyles, descriptionsStyles, dialogRecipe, diffFields, disclosureStyles, dismissOnBackdrop, displayPosition, documentStyles, downloadFile, drawerRecipe, elementProps, ellipsisStyles, emptyRecipe, enUS, errorCodeOf, errorCodeText, errorMessage, existingUploadFile, externalLinkAttrs, festiveColors, festiveShadows, festiveTheme, fieldColumnStyles, fieldCompareStyles, fieldStyles, fieldsToIso, fileDropStyles, filterOptions, filterRows, filterTree, findVisibleRange, firstSegmentOf, fitCount, fitTransform, flattenTree, flexAlignStyles, flexJustifyStyles, flexStyles, floatingStyles, focusAfterRemoval, focusCalendar, focusControl, focusFirst, focusOnShell, focusOrigin, focusRingStyles, fontSizeStyles, fontWeightStyles, forestColors, forestShadows, forestTheme, formErrorSummaryStyles, formSectionColumnStyles, formSectionStyles, formValueText, formatCell, formatConditionValue, formatHotkey, formatSorts, fromWire, fullIsoDay, gapStyles, gaugeStyles, gridAlignStyles, gridDynamicStyles, gridFlowStyles, gridFocus, gridItemDynamicStyles, gridItemStyles, gridJustifyStyles, gridStyles, handleCalendarKeydown, handleListKeydown, handleSegmentKeydown, hasContent, hasTimeOf, headerLayout, headingMarker, headingStyles, highContrastColors, highContrastRadii, highContrastShadows, highContrastTheme, hoverCardStyles, iconMarkup, iconStyles, idCardFormat, idCardSchema, imageDynamicStyles, imageFitStyles, imageGroupStyles, imageStyles, indexTree, indicatorRecipe, initials, inlineArrows, inputRecipe, interactionTransitions, isAbortError, isApplePlatform, isCellEditable, isComposingKey, isConditionGroup, isDateDisabled, isDateValue, isDecimal, isEditable, isExpandable, isInRange, isNumeric, isNumericText, isOutOfRange, isOutsideDecade, isPeriodDisabled, isRtl, isRuleComplete, isSameDate, isTimeGranularity, isValidIdCard, isWindow, isoDayOfWeek, isoToFields, isoToValue, isoWeekOf, isoWeeksInYear, itemListStyles, itemStyles, kbdStyles, labelStyles, lastIsoDay, lemonColors, lemonRadii, lemonShadows, lemonTheme, lightColors, lightShadows, lightTheme, lightboxDynamicStyles, lightboxStyles, lineClampStyles, linkRecipe, listPopoverStyles, listRole, listStyles, listStylesProse, listboxPositionStyles, listboxStyles, loadingBarScaleStyles, loadingBarStyles, loadingOverlayStyles, localPeopleSource, lockScroll, machineDateTime, markStyles, marqueeDynamicStyles, marqueeStyles, marqueeTrailStyles, matchesAccept, matchesCondition, matchesHotkey, mentionSegments, mentionStyles, mentionedValues, menuItemContent, menuItemDescribedBy, menuItemSx, menuStyles, mergeAttrs, mergeDefaults, mergePartProps, mergeProps, mergeStyles, midnightColors, midnightTheme, modalPartStyles, monthGrid, monthsOfYear, moveNode, multiplyNumeric, navBarStyles, navListStyles, needsValue, nextSort, nextSorts, normalizeNumber, numberRangeFieldStyles, numericKind, numericText, oceanColors, oceanRadii, oceanShadows, oceanTheme, openModalDialog, openSetter, operatorLabel, operatorsOf, orderedRange, otpFieldStyles, paddingInlineStyles, pageJumpStyles, pageScrollbarStyles, pageSizeSelectStyles, pagerStyles, paginationBarStyles, paginationItems, paginationStyles, paperColors, paperFonts, paperShadows, paperTheme, parseColor, parseCsv, parseDuration, parseHotkey, parseIsoDate, parseIsoDateTime, parseIsoRange, parseIsoTime, parseLineSpec, parseNumber, parseSorts, partAttrs, peopleKey, peoplePickerPanelDynamicStyles, peoplePickerPanelStyles, phoneFormat, phoneSchema, pickFile, pickerPresetStyles, pivot, pivotTableStyles, plainText, pointAnchor, popconfirmStyles, popoverStyles, presenceStyles, presetIsoRange, presetRange, progressRecipe, progressTargetPositionStyles, progressWidthStyles, proportionBarDynamicStyles, proportionBarStyles, proseStyles, provideFieldLayout, provideGridColumns, providerStyles, queryCodecs, radioStyles, radiusStyles, rangeDays, rangeHasUnavailable, rasterizeSvg, ratingClipStyles, ratingStyles, ratingToneStyles, readCsvFile, readToken, readableText, readonlyChoiceHandlers, relativeFontSizeStyles, relativeUnit, renderPickerPresets, repeatedRowSpans, resizeHandleStyles, resolveTheme, resultRecipe, returnFocus, revealTransition, rippleHostStyles, ripplePlacementStyles, rippleStyles, rovingFocus, rowGapStyles, rowLabel, sakuraColors, sakuraRadii, sakuraShadows, sakuraTheme, sameNumeric, sameStickyOffsets, sameValue, scopeHttp, scrollAreaBarStyles, scrollAreaStyles, segmentFields, segmentedFieldStyles, selectStyles, selectedTagsStyles, selectedValues, selectionBarStyles, separatorStyles, sheetFromMatrix, shiftDecimal, shiftIsoDate, shimmerStyles, shouldRouteClick, skeletonStyles, skeletonTextStyles, skeletonVariantStyles, skipLinkStyles, sliderPositionStyles, sliderStyles, snapNumeric, snapToStep, sortByValue, sortByValues, sortList, sortRows, sortableStyles, sparklineStyles, spinnerStyles, splitterDynamicStyles, splitterStyles, startMove, startRipple, statGroupDynamicStyles, statGroupStyles, statStyles, statusDotDynamicStyles, statusDotStyles, statusDotToneStyles, statusIcons, statusToneBorderStyles, statusToneStyles, statusToneSx, stepsStateStyles, stepsStyles, stickyOffsets, sumColumn, swatchStyles, switchStyles, syncChecked, t, tabListStyles, tabPanelStyles, tabRecipe, tableDynamicStyles, tableMinWidth, tableOfContentsStyles, tableParams, tableRecipe, tableToCsv, tabsStyles, tagStyles, tagsInputStyles, textAlignStyles, textComponentStyles, textStyles, textWrapStyles, textareaRowStyles, textareaStyles, themeAttrs, themeBootScript, themeTransition, themeTransitionOrInstant, themeVariables, timePickerStyles, timelineStyles, timelineToneStyles, toDateLimits, toDayOfWeek, toElement, toHex, toInstant, toIsoDate, toIsoDateTime, toIsoQuarter, toIsoRange, toIsoTime, toIsoWeek, toListboxOption, toNumber, toNumericKind, toPeopleValue, toText, toTime, toWire, toastCountdownStyles, toastPlacementStyles, toastStackStyles, toastStyles, todayIso, toggleChecked, toggleGroupStyles, toggleSelection, tokenValue, toneFillStyles, toneStyles, toolbarStyles, tooltipStyles, topModal, tourDynamicStyles, tourStyles, trackModal, transferStyles, transitions, trapFocus, treeDataTableIndentStyles, treeDataTableStyles, treeDynamicStyles, treePath, treeSelectStyles, treeStyles, truncateDate, uploadDynamicStyles, uploadStyles, useActiveIndicator, useAnchoredPopover, useAnimate, useAutosave, useButtonAppearance, useButtonBehavior, useCalendarState, useChoiceAppearance, useClipboard, useColumnDisplay, useConfig, useConfirm, useControlAppearance, useDateLocale, useDateSegments, useDefaults, useDelayedLoading, useDetachedDialog, useDetachedOverlay, useDialog, useDismissible, useDrawer, useErrorMessage, useEventListener, useFieldControl, useFieldSegments, useForm, useFormReset, useFormat, useFullscreen, useHotkeys, useHoverIntent, useHoverLayer, useHttp, useIntersectionObserver, useLang, useLayoutAnimation, useLazyContent, useLeaveConfirmation, useListState, useMediaQuery, useMenuItem, useMenuItemContentIds, useMessages, useNow, useOverflowItems, usePageVisible, usePanZoom, usePersistentState, usePickerPopover, usePointer, usePrefersDark, usePresence, useQueryState, useQueryStates, useRecipe, useReducedMotion, useRemoteItems, useRequest, useResizeObserver, useResultAnnouncement, useRipple, useRouterLink, useScrollSpy, useSelectedOptions, useSortable, useSpring, useTableQuery, useTextMatcher, useTreeExpansion, useTween, useVirtualizer, useWorkCalendar, valueShape, valueToIso, viewportFillDynamicStyles, viewportFillStyles, virtualListSizeStyles, virtualListStyles, visuallyHiddenStyles, watermarkStyles, watermarkTileStyles, weekOfYear, weekdayCalendar, weekdayNames, wireText, withAlpha, workdaysBetween, writeDateLike, yearsOfDecade, zhCN, zoomAround };
@@ -270,7 +270,7 @@ var Combobox = /*#__PURE__*/ _component((_props, _ctx) => {
270
270
  list,
271
271
  id: listId,
272
272
  renderOption: children.value,
273
- empty: remote.error() ? lang.listLoadFailed : empty.value
273
+ empty: remote.failure() ?? empty.value
274
274
  },
275
275
  "propsListbox": propsListbox.value,
276
276
  "propsPopover": propsPopover.value
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_childrenProp","_vtp_restProps","_vue_ref","_vue_shallowRef","_createVNode","_Fragment","_mergeProps","_withDirectives","_vModelText"],"sources":["../../src/input/Combobox.tsx"],"sourcesContent":["/**\n * 组合框(WAI-ARIA Combobox,aria-autocomplete=\"list\"):边输入边从列表里选,或者只当带建议的输入框用。\n *\n * <Field label=\"城市\"><Combobox items={cities} _value={city} /></Field>\n * <Combobox items={results} filter={false} loading={searching} _inputValue={keyword} aria-label=\"搜索用户\" />\n *\n * 组合已有的部件:外壳同 TextField(controlParts),弹出层用 useAnchoredPopover(与外壳同宽),列表是 ListboxView。\n * 焦点一直在输入框里,高亮项经 aria-activedescendant 告诉读屏。\n *\n * - 过滤:默认本地按显示文字包含输入(Intl.Collator,忽略大小写与重音);filter={false} 时不过滤,\n * 由调用方按 inputValue 换 items(异步搜索,配合 loading)。给 load 时组件自己请求:打开时与输入停下 300 ms 后\n * 按输入请求,只采用最后一次(remote-items.ts,同 Select)。\n * - 中文输入法:输入经 v-model 写回,组合输入期间 inputValue 不变,所以不会拿拼音去过滤。\n * - 选中后输入框显示选项文字;失焦时如果文字不是某个选项(且没开 allowCustomValue),恢复成已选项的文字,清空则取消选择。\n * - 键盘:↓ 打开、↑↓ / Page Up / Down 移动,Enter 选中,Esc 关闭(关闭时再按 Esc 清空);Home / End 照常移动光标。\n *\n * 部件:Root(外壳)、Input(主元素)、Clear、Chevron(切换按钮)、Popover、Listbox。\n */\nimport { ChevronDown } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport type { PresetIconButtonProps } from '../base/CloseButton';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { isComposingKey } from '../utils/dom/hotkeys';\nimport { useAnchoredPopover, type FloatingPlacement } from '../utils/dom/floating';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { ListPopover } from './ListPopover';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport {\n controlClear,\n controlParts,\n focusOnShell,\n controlIcon,\n useControlAppearance,\n type ControlIconOptions,\n type ControlOptions,\n} from './control';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { disclosureStyles } from '../utils/style/transitions';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport {\n handleListKeydown,\n useListState,\n useResultAnnouncement,\n useSelectedOptions,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\n\n/** 角色、展开状态、值与可用性由组件管理 */\nexport type ComboboxManaged =\n | 'value'\n | 'role'\n | 'size'\n | 'disabled'\n | 'readonly'\n | 'required'\n | 'autocomplete'\n | 'aria-autocomplete'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-activedescendant'\n | 'aria-invalid'\n | 'aria-describedby';\n\n/** Combobox 除 toOption 外的属性;未声明的属性落到 input(主元素)上,外壳用 propsRoot */\nexport interface ComboboxBaseProps<T>\n extends PartProps<'input', ComboboxManaged>, ControlOptions, ControlIconOptions, OpenChangeProps {\n /** 数据:ListboxOption、字符串,或任意数据加 toOption;有 load 时是第一次加载之前的选项(编辑页放上已选的那一项) */\n items?: readonly T[];\n /** 选中项的值:父级写 _value={x};没有选中时是 null */\n _value?: string | null;\n /** 输入框里的文字:父级可以写 _inputValue={x}(异步搜索时据此取数据) */\n _inputValue?: string;\n /** 是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 过滤:默认按显示文字包含输入(忽略大小写与重音);函数自定义;false 不过滤(异步搜索) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 远程选项:打开时与输入停下 300 ms 后按输入调用,结果代替 items;只采用最后一次,被顶掉的请求 signal 中止 */\n load?: OptionsLoader<T>;\n /** 允许输入不在选项里的文字:失焦时保留,value 为 null */\n allowCustomValue?: boolean;\n /**\n * 显示右侧的展开按钮;只当带建议的输入框用时(Autocomplete)关掉,列表随输入出现\n * @default true\n */\n showToggle?: boolean;\n /** 没有可选的项时不弹出列表(不显示“没有匹配的选项”):只当带建议的输入框用时(Autocomplete) */\n hideEmpty?: boolean;\n /** 正在取选项(异步搜索):没有选项时列表里是骨架行,已有选项时顶部显示进度条 */\n loading?: boolean;\n /** 弹出位置,默认 bottom-start */\n placement?: FloatingPlacement;\n /** 有内容时显示清空按钮 */\n clearable?: boolean;\n /** 表单提交时的 name(用隐藏的 input 提交 value) */\n name?: string;\n /** 不可用 */\n disabled?: boolean;\n /** 只读 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 自定义选项内容:`{(item, { selected, active }) => …}`,拿到 items 里的原始数据 */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配的选项时列表里显示的内容 */\n empty?: VNodeChild;\n /** 外壳的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 清空按钮的部件属性 */\n propsClear?: Partial<PresetIconButtonProps>;\n /** 切换按钮(下拉箭头)的部件属性 */\n propsChevron?: Partial<IconButtonProps>;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 组合框的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type ComboboxProps<T = ListboxOption> = ComboboxBaseProps<T> & OptionMapping<T>;\n\n/** Combobox 的样式:chevronOpen */\nexport const comboboxStyles = css.create({\n chevronOpen: { rotate: '180deg' },\n});\n\n/** 组合框:输入框 + 过滤后的选项列表 */\nexport const Combobox = _component(\n <T,>({\n items = [],\n toOption,\n _value: value = _bindable<string | null>(null),\n _inputValue: inputValue = _bindable(''),\n _open: open = _bindable(false),\n onOpenChange,\n filter,\n load,\n allowCustomValue = false,\n showToggle = true,\n hideEmpty = false,\n loading = false,\n placement = 'bottom-start',\n clearable = false,\n name,\n variant,\n size,\n radius,\n disabled,\n readonly,\n required,\n invalid,\n id,\n children,\n empty,\n propsRoot,\n icon,\n propsIcon,\n propsClear,\n propsChevron,\n propsPopover,\n propsListbox,\n ...rest\n }: ComboboxProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({ variant, size, radius }));\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n // 用户输入的过滤词:选中、用箭头打开时清空(显示全部选项)\n let query = _state('');\n // 组件自己改 inputValue(选中后写入选项文字)时,不当作用户输入\n let writing = false;\n let shell = _state.raw<HTMLElement | null>(null);\n let input = _state.raw<HTMLInputElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const optionOf = (item: T) => toListboxOption(item, toOption);\n\n function matches(item: T, text: string) {\n if (!text) return true;\n return filter ? filter(item, text) : textMatcher()(optionOf(item).label, text);\n }\n\n const remote = useRemoteItems({\n load: () => load,\n query: () => query,\n open: () => open,\n items: () => items,\n });\n const list = useListState({\n // 有 load 或 filter={false} 时由服务端按输入过滤\n items: () =>\n load || filter === false\n ? remote.items()\n : remote.items().filter((item) => matches(item, query)),\n toOption: optionOf,\n selected: () => (value != null ? [value] : []),\n mode: () => 'single',\n // 再选已选的项不取消\n required: () => true,\n onChange: (next) => (value = next[0] ?? null),\n });\n\n // 已选项的文字:远程搜索换了 items 之后,仍按之前见过的文字显示\n const selectedOf = useSelectedOptions({ items: remote.items, toOption: optionOf });\n const selectedLabel = () => (value == null ? '' : selectedOf([value])[0]!.label);\n\n function setText(text: string) {\n if (inputValue === text) return;\n writing = true;\n inputValue = text;\n }\n\n useResultAnnouncement(() => ({ query, count: list.options.length }));\n\n // 用户输入(含输入法组合结束):打开并按输入过滤,高亮第一项\n watch(\n () => inputValue,\n (text) => {\n if (writing) {\n writing = false;\n return;\n }\n query = text;\n // 只在输入框聚焦时打开:父级把 inputValue 改掉(重置成空)不该弹出列表\n if (!control().readonly && document.activeElement === input) setOpen(true, 'trigger');\n list.move('first');\n },\n );\n\n // 父级改了 value,或选项后到(编辑页先拿到值、再拿到选项):输入框跟着显示它的文字;用户正在输入时不打断\n watch(\n () => [value, selectedLabel()],\n () => {\n if (query) return;\n if (!allowCustomValue || value != null) setText(selectedLabel());\n },\n { immediate: true },\n );\n\n function pick(choice: string, event?: Event) {\n value = choice;\n setText(selectedLabel());\n query = '';\n setOpen(false, 'select', event);\n }\n\n function show(event?: Event) {\n query = '';\n list.activateDefault();\n setOpen(true, 'trigger', event);\n }\n\n // 失焦:文字不是选项时恢复(或清空选择)\n function commit(event: FocusEvent) {\n setOpen(false, 'focus', event);\n if (allowCustomValue) {\n if (inputValue !== selectedLabel()) value = null;\n return;\n }\n if (!inputValue) value = null;\n else setText(selectedLabel());\n query = '';\n }\n\n function onKeydown(event: KeyboardEvent) {\n const state = control();\n if (state.disabled || state.readonly || isComposingKey(event)) return;\n if (event.key === 'Escape') {\n // 打开时交给原生 popover 关闭;关闭时清空\n if (!open && inputValue) {\n event.preventDefault();\n setText('');\n value = null;\n }\n return;\n }\n if (!open) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n show(event);\n }\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, (choice) => pick(choice, event)))\n event.preventDefault();\n }\n\n // 列表是否真的弹出:hideEmpty 时没有可选的项(也不在加载)就不弹\n const shown = () =>\n open && (!hideEmpty || list.options.length > 0 || loading || remote.loading());\n\n // 弹层贴着外壳、与它同宽;焦点一直在输入框上,关闭时不用归还\n const { onToggle } = useAnchoredPopover(\n () => ({\n open: shown(),\n anchor: shell,\n panel,\n floating: { placement, matchWidth: true, fitHeight: true },\n restoreFocus: false,\n }),\n { close: (reason, event) => setOpen(false, reason, event) },\n );\n\n return () => {\n const state = control();\n const s = controlParts(appearance(), state);\n const editable = !state.disabled && !state.readonly;\n return (\n <>\n <div\n {...mergeAttrs<'div'>(s.root, propsRoot, {\n ref: _toRef(shell),\n onPointerdown: focusOnShell(() => input),\n })}\n data-state={open ? 'open' : 'closed'}\n data-invalid={state.invalid || undefined}\n data-disabled={state.disabled || undefined}\n >\n {controlIcon(s, icon, propsIcon)}\n {/* _bind 编译为 v-model:输入法组合期间不写回 */}\n <input\n {...mergeAttrs<'input'>(s.input, rest, {\n ref: _toRef(input),\n id: state.id,\n role: 'combobox',\n autocomplete: 'off',\n disabled: state.disabled,\n readonly: state.readonly,\n required: state.required,\n 'aria-autocomplete': 'list',\n 'aria-expanded': shown(),\n 'aria-controls': listId,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n 'aria-invalid': state.invalid || undefined,\n 'aria-describedby': state.describedBy,\n onKeydown,\n onBlur: commit,\n })}\n _value={inputValue}\n />\n {clearable &&\n inputValue &&\n editable &&\n controlClear(s, propsClear, () => {\n setText('');\n value = null;\n input?.focus();\n })}\n {showToggle && (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n {\n ...s.button,\n sx: [s.button.sx, disclosureStyles.icon, open && comboboxStyles.chevronOpen],\n radius: 'full',\n icon: ChevronDown,\n 'aria-label': lang.comboboxToggle,\n },\n propsChevron,\n {\n tabindex: -1,\n disabled: !editable,\n 'aria-expanded': shown(),\n 'aria-controls': listId,\n // 不让输入框失焦(失焦会提交并关闭)\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onClick: (event: MouseEvent) => {\n if (open) setOpen(false, 'trigger', event);\n else show(event);\n input?.focus();\n },\n },\n )}\n />\n )}\n <FormValue name={name} value={value} disabled={state.disabled} />\n </div>\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onToggle}\n size={appearance().size}\n labelledBy={state.labelledBy}\n label={rest['aria-label']}\n loading={loading || remote.loading()}\n onPick={(choice) => pick(choice)}\n listbox={{\n list,\n id: listId,\n renderOption: children,\n empty: remote.error() ? lang.listLoadFailed : empty,\n }}\n propsListbox={propsListbox}\n propsPopover={propsPopover}\n />\n </>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_childrenProp","_vtp_restProps","_vue_ref","_vue_shallowRef","_createVNode","_Fragment","_mergeProps","_withDirectives","_vModelText"],"sources":["../../src/input/Combobox.tsx"],"sourcesContent":["/**\n * 组合框(WAI-ARIA Combobox,aria-autocomplete=\"list\"):边输入边从列表里选,或者只当带建议的输入框用。\n *\n * <Field label=\"城市\"><Combobox items={cities} _value={city} /></Field>\n * <Combobox items={results} filter={false} loading={searching} _inputValue={keyword} aria-label=\"搜索用户\" />\n *\n * 组合已有的部件:外壳同 TextField(controlParts),弹出层用 useAnchoredPopover(与外壳同宽),列表是 ListboxView。\n * 焦点一直在输入框里,高亮项经 aria-activedescendant 告诉读屏。\n *\n * - 过滤:默认本地按显示文字包含输入(Intl.Collator,忽略大小写与重音);filter={false} 时不过滤,\n * 由调用方按 inputValue 换 items(异步搜索,配合 loading)。给 load 时组件自己请求:打开时与输入停下 300 ms 后\n * 按输入请求,只采用最后一次(remote-items.ts,同 Select)。\n * - 中文输入法:输入经 v-model 写回,组合输入期间 inputValue 不变,所以不会拿拼音去过滤。\n * - 选中后输入框显示选项文字;失焦时如果文字不是某个选项(且没开 allowCustomValue),恢复成已选项的文字,清空则取消选择。\n * - 键盘:↓ 打开、↑↓ / Page Up / Down 移动,Enter 选中,Esc 关闭(关闭时再按 Esc 清空);Home / End 照常移动光标。\n *\n * 部件:Root(外壳)、Input(主元素)、Clear、Chevron(切换按钮)、Popover、Listbox。\n */\nimport { ChevronDown } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport type { PresetIconButtonProps } from '../base/CloseButton';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { isComposingKey } from '../utils/dom/hotkeys';\nimport { useAnchoredPopover, type FloatingPlacement } from '../utils/dom/floating';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { ListPopover } from './ListPopover';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport {\n controlClear,\n controlParts,\n focusOnShell,\n controlIcon,\n useControlAppearance,\n type ControlIconOptions,\n type ControlOptions,\n} from './control';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { disclosureStyles } from '../utils/style/transitions';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport {\n handleListKeydown,\n useListState,\n useResultAnnouncement,\n useSelectedOptions,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\n\n/** 角色、展开状态、值与可用性由组件管理 */\nexport type ComboboxManaged =\n | 'value'\n | 'role'\n | 'size'\n | 'disabled'\n | 'readonly'\n | 'required'\n | 'autocomplete'\n | 'aria-autocomplete'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-activedescendant'\n | 'aria-invalid'\n | 'aria-describedby';\n\n/** Combobox 除 toOption 外的属性;未声明的属性落到 input(主元素)上,外壳用 propsRoot */\nexport interface ComboboxBaseProps<T>\n extends PartProps<'input', ComboboxManaged>, ControlOptions, ControlIconOptions, OpenChangeProps {\n /** 数据:ListboxOption、字符串,或任意数据加 toOption;有 load 时是第一次加载之前的选项(编辑页放上已选的那一项) */\n items?: readonly T[];\n /** 选中项的值:父级写 _value={x};没有选中时是 null */\n _value?: string | null;\n /** 输入框里的文字:父级可以写 _inputValue={x}(异步搜索时据此取数据) */\n _inputValue?: string;\n /** 是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 过滤:默认按显示文字包含输入(忽略大小写与重音);函数自定义;false 不过滤(异步搜索) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 远程选项:打开时与输入停下 300 ms 后按输入调用,结果代替 items;只采用最后一次,被顶掉的请求 signal 中止 */\n load?: OptionsLoader<T>;\n /** 允许输入不在选项里的文字:失焦时保留,value 为 null */\n allowCustomValue?: boolean;\n /**\n * 显示右侧的展开按钮;只当带建议的输入框用时(Autocomplete)关掉,列表随输入出现\n * @default true\n */\n showToggle?: boolean;\n /** 没有可选的项时不弹出列表(不显示“没有匹配的选项”):只当带建议的输入框用时(Autocomplete) */\n hideEmpty?: boolean;\n /** 正在取选项(异步搜索):没有选项时列表里是骨架行,已有选项时顶部显示进度条 */\n loading?: boolean;\n /** 弹出位置,默认 bottom-start */\n placement?: FloatingPlacement;\n /** 有内容时显示清空按钮 */\n clearable?: boolean;\n /** 表单提交时的 name(用隐藏的 input 提交 value) */\n name?: string;\n /** 不可用 */\n disabled?: boolean;\n /** 只读 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 自定义选项内容:`{(item, { selected, active }) => …}`,拿到 items 里的原始数据 */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配的选项时列表里显示的内容 */\n empty?: VNodeChild;\n /** 外壳的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 清空按钮的部件属性 */\n propsClear?: Partial<PresetIconButtonProps>;\n /** 切换按钮(下拉箭头)的部件属性 */\n propsChevron?: Partial<IconButtonProps>;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 组合框的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type ComboboxProps<T = ListboxOption> = ComboboxBaseProps<T> & OptionMapping<T>;\n\n/** Combobox 的样式:chevronOpen */\nexport const comboboxStyles = css.create({\n chevronOpen: { rotate: '180deg' },\n});\n\n/** 组合框:输入框 + 过滤后的选项列表 */\nexport const Combobox = _component(\n <T,>({\n items = [],\n toOption,\n _value: value = _bindable<string | null>(null),\n _inputValue: inputValue = _bindable(''),\n _open: open = _bindable(false),\n onOpenChange,\n filter,\n load,\n allowCustomValue = false,\n showToggle = true,\n hideEmpty = false,\n loading = false,\n placement = 'bottom-start',\n clearable = false,\n name,\n variant,\n size,\n radius,\n disabled,\n readonly,\n required,\n invalid,\n id,\n children,\n empty,\n propsRoot,\n icon,\n propsIcon,\n propsClear,\n propsChevron,\n propsPopover,\n propsListbox,\n ...rest\n }: ComboboxProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({ variant, size, radius }));\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n // 用户输入的过滤词:选中、用箭头打开时清空(显示全部选项)\n let query = _state('');\n // 组件自己改 inputValue(选中后写入选项文字)时,不当作用户输入\n let writing = false;\n let shell = _state.raw<HTMLElement | null>(null);\n let input = _state.raw<HTMLInputElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const optionOf = (item: T) => toListboxOption(item, toOption);\n\n function matches(item: T, text: string) {\n if (!text) return true;\n return filter ? filter(item, text) : textMatcher()(optionOf(item).label, text);\n }\n\n const remote = useRemoteItems({\n load: () => load,\n query: () => query,\n open: () => open,\n items: () => items,\n });\n const list = useListState({\n // 有 load 或 filter={false} 时由服务端按输入过滤\n items: () =>\n load || filter === false\n ? remote.items()\n : remote.items().filter((item) => matches(item, query)),\n toOption: optionOf,\n selected: () => (value != null ? [value] : []),\n mode: () => 'single',\n // 再选已选的项不取消\n required: () => true,\n onChange: (next) => (value = next[0] ?? null),\n });\n\n // 已选项的文字:远程搜索换了 items 之后,仍按之前见过的文字显示\n const selectedOf = useSelectedOptions({ items: remote.items, toOption: optionOf });\n const selectedLabel = () => (value == null ? '' : selectedOf([value])[0]!.label);\n\n function setText(text: string) {\n if (inputValue === text) return;\n writing = true;\n inputValue = text;\n }\n\n useResultAnnouncement(() => ({ query, count: list.options.length }));\n\n // 用户输入(含输入法组合结束):打开并按输入过滤,高亮第一项\n watch(\n () => inputValue,\n (text) => {\n if (writing) {\n writing = false;\n return;\n }\n query = text;\n // 只在输入框聚焦时打开:父级把 inputValue 改掉(重置成空)不该弹出列表\n if (!control().readonly && document.activeElement === input) setOpen(true, 'trigger');\n list.move('first');\n },\n );\n\n // 父级改了 value,或选项后到(编辑页先拿到值、再拿到选项):输入框跟着显示它的文字;用户正在输入时不打断\n watch(\n () => [value, selectedLabel()],\n () => {\n if (query) return;\n if (!allowCustomValue || value != null) setText(selectedLabel());\n },\n { immediate: true },\n );\n\n function pick(choice: string, event?: Event) {\n value = choice;\n setText(selectedLabel());\n query = '';\n setOpen(false, 'select', event);\n }\n\n function show(event?: Event) {\n query = '';\n list.activateDefault();\n setOpen(true, 'trigger', event);\n }\n\n // 失焦:文字不是选项时恢复(或清空选择)\n function commit(event: FocusEvent) {\n setOpen(false, 'focus', event);\n if (allowCustomValue) {\n if (inputValue !== selectedLabel()) value = null;\n return;\n }\n if (!inputValue) value = null;\n else setText(selectedLabel());\n query = '';\n }\n\n function onKeydown(event: KeyboardEvent) {\n const state = control();\n if (state.disabled || state.readonly || isComposingKey(event)) return;\n if (event.key === 'Escape') {\n // 打开时交给原生 popover 关闭;关闭时清空\n if (!open && inputValue) {\n event.preventDefault();\n setText('');\n value = null;\n }\n return;\n }\n if (!open) {\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n show(event);\n }\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, (choice) => pick(choice, event)))\n event.preventDefault();\n }\n\n // 列表是否真的弹出:hideEmpty 时没有可选的项(也不在加载)就不弹\n const shown = () =>\n open && (!hideEmpty || list.options.length > 0 || loading || remote.loading());\n\n // 弹层贴着外壳、与它同宽;焦点一直在输入框上,关闭时不用归还\n const { onToggle } = useAnchoredPopover(\n () => ({\n open: shown(),\n anchor: shell,\n panel,\n floating: { placement, matchWidth: true, fitHeight: true },\n restoreFocus: false,\n }),\n { close: (reason, event) => setOpen(false, reason, event) },\n );\n\n return () => {\n const state = control();\n const s = controlParts(appearance(), state);\n const editable = !state.disabled && !state.readonly;\n return (\n <>\n <div\n {...mergeAttrs<'div'>(s.root, propsRoot, {\n ref: _toRef(shell),\n onPointerdown: focusOnShell(() => input),\n })}\n data-state={open ? 'open' : 'closed'}\n data-invalid={state.invalid || undefined}\n data-disabled={state.disabled || undefined}\n >\n {controlIcon(s, icon, propsIcon)}\n {/* _bind 编译为 v-model:输入法组合期间不写回 */}\n <input\n {...mergeAttrs<'input'>(s.input, rest, {\n ref: _toRef(input),\n id: state.id,\n role: 'combobox',\n autocomplete: 'off',\n disabled: state.disabled,\n readonly: state.readonly,\n required: state.required,\n 'aria-autocomplete': 'list',\n 'aria-expanded': shown(),\n 'aria-controls': listId,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n 'aria-invalid': state.invalid || undefined,\n 'aria-describedby': state.describedBy,\n onKeydown,\n onBlur: commit,\n })}\n _value={inputValue}\n />\n {clearable &&\n inputValue &&\n editable &&\n controlClear(s, propsClear, () => {\n setText('');\n value = null;\n input?.focus();\n })}\n {showToggle && (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n {\n ...s.button,\n sx: [s.button.sx, disclosureStyles.icon, open && comboboxStyles.chevronOpen],\n radius: 'full',\n icon: ChevronDown,\n 'aria-label': lang.comboboxToggle,\n },\n propsChevron,\n {\n tabindex: -1,\n disabled: !editable,\n 'aria-expanded': shown(),\n 'aria-controls': listId,\n // 不让输入框失焦(失焦会提交并关闭)\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onClick: (event: MouseEvent) => {\n if (open) setOpen(false, 'trigger', event);\n else show(event);\n input?.focus();\n },\n },\n )}\n />\n )}\n <FormValue name={name} value={value} disabled={state.disabled} />\n </div>\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onToggle}\n size={appearance().size}\n labelledBy={state.labelledBy}\n label={rest['aria-label']}\n loading={loading || remote.loading()}\n onPick={(choice) => pick(choice)}\n listbox={{\n list,\n id: listId,\n renderOption: children,\n empty: remote.failure() ?? empty,\n }}\n propsListbox={propsListbox}\n propsPopover={propsPopover}\n />\n </>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -254,7 +254,7 @@ var Mentions = /*#__PURE__*/ _component((_props2, _ctx2) => {
254
254
  list,
255
255
  id: listId,
256
256
  renderOption: children.value,
257
- empty: remote.error() ? lang.listLoadFailed : empty.value ?? lang.mentionsEmpty
257
+ empty: remote.failure() ?? empty.value ?? lang.mentionsEmpty
258
258
  },
259
259
  "propsListbox": propsListbox.value,
260
260
  "propsPopover": mergePartProps({ sx: mentionStyles.panel }, propsPopover.value)
@@ -1 +1 @@
1
- {"version":3,"file":"Mentions.js","names":["_vtp_readonlyProp","_vtp_restProps","_createVNode","_vtp_bindable","_vtp_childrenProp","_vue_shallowRef","_vue_ref","_Fragment","_mergeProps"],"sources":["../../src/input/Mentions.tsx"],"sourcesContent":["/**\n * 提及:多行文本框里输入 @ 弹出人员(或岗位、群组)列表,选中后写成“@名字 ”。留言、审批意见、协商回复里通知相关的人。\n *\n * <Field label=\"留言\"><Mentions _value={text} items={people} _mentions={notified} /></Field>\n * <Mentions _value={text} load={(query, signal) => api.searchUsers(query, { signal })} toOption={…} />\n *\n * 值仍是文字;mentions 是文字里提到的选项的值(工号、岗位编号),随文字增删——删掉“@名字”就不再算提及。\n * 显示提及过的文字用 MentionText(提及高亮),拆分用 mentionSegments。\n *\n * - 弹出:@ 在开头或前面不是字母数字(邮箱里的 @ 不算),@ 与光标之间没有空白;列表贴在 @ 的位置(caretAnchor)。\n * - 过滤:本地按显示文字包含 @ 后面的文字;给 load 时按它远程搜索(同 Combobox)。\n * - 键盘:↑↓ 移动、Enter 或 Tab 选中、Esc 关闭(这个 @ 不再弹出,直到重新输入);焦点一直在文本框里,\n * 高亮项经 aria-activedescendant 告诉读屏,结果数量播报。中文输入法组合期间不弹出、不过滤。\n *\n * 外壳与自动增高同 Textarea。部件:Root(外壳)、Textarea、Popover、Listbox。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, useId, watch, type VNodeChild } from 'vue';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { caretAnchor } from '../utils/dom/caret';\nimport { useAnchoredPopover } from '../utils/dom/floating';\nimport { isComposingKey } from '../utils/dom/hotkeys';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport { ListPopover } from './ListPopover';\nimport {\n handleListKeydown,\n toListboxOption,\n useListState,\n useResultAnnouncement,\n type ListboxOption,\n type OptionMapping,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\nimport { Textarea, type TextareaProps } from './Textarea';\n\n/** 提及的弹出列表由组件管理 */\nexport type MentionsManaged = 'aria-autocomplete' | 'aria-controls' | 'aria-activedescendant';\n\n/** Mentions 除 toOption 外的属性;未声明的属性落到 textarea 上(同 Textarea) */\nexport interface MentionsBaseProps<T>\n extends Omit<TextareaProps, MentionsManaged>, OpenChangeProps {\n /** 可以提及的人(ListboxOption、字符串,或任意数据加 toOption);有 load 时是第一次结果之前的选项 */\n items?: readonly T[];\n /** 远程搜索:按 @ 后面的文字调用,停下 300 ms 后请求,只采用最后一次 */\n load?: OptionsLoader<T>;\n /** 文字里提到的选项的值:父级写 _mentions={x},随文字更新 */\n _mentions?: string[];\n /** 触发的字符,默认 '@' */\n prefix?: string;\n /** 过滤:默认按显示文字包含 @ 后面的文字;false 不过滤(由调用方换 items) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 列表是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 正在取选项 */\n loading?: boolean;\n /** 自定义选项内容:`{(item, { active }) => …}`(头像、部门) */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配的人时列表里显示的内容 */\n empty?: VNodeChild;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 提及输入框的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type MentionsProps<T = ListboxOption> = MentionsBaseProps<T> & OptionMapping<T>;\n\n/** 拆开的一段文字:普通文字,或提及(带它的选项) */\nexport interface MentionSegment {\n /** 这一段的文字(提及时含 @) */\n text: string;\n /** 提及的选项;普通文字没有 */\n mention?: ListboxOption;\n}\n\n/** @ 前面是这些字符时不算提及(邮箱 name@example.com) */\nconst WORD_BEFORE = /[A-Za-z0-9_.]/;\n\n/**\n * 把文字拆成普通文字与提及:“@名字”里的名字是 options 里某一项的显示文字(有多个能匹配时取最长的)。\n * 提及的显示(MentionText)与找出提到了谁(mentionedValues)都用它\n */\nexport function mentionSegments(\n text: string,\n options: readonly ListboxOption[],\n prefix = '@',\n): MentionSegment[] {\n const byLength = options\n .filter((option) => option.label)\n .toSorted((a, b) => b.label.length - a.label.length);\n const segments: MentionSegment[] = [];\n let plain = '';\n let index = 0;\n while (index < text.length) {\n const mention =\n text.startsWith(prefix, index) && !WORD_BEFORE.test(text[index - 1] ?? '')\n ? byLength.find((option) => text.startsWith(option.label, index + prefix.length))\n : undefined;\n if (!mention) {\n plain += text[index];\n index += 1;\n continue;\n }\n if (plain) segments.push({ text: plain });\n plain = '';\n const length = prefix.length + mention.label.length;\n segments.push({ text: text.slice(index, index + length), mention });\n index += length;\n }\n if (plain) segments.push({ text: plain });\n return segments;\n}\n\n/** 文字里提到了哪些选项(值,按第一次出现的顺序,不重复) */\nexport function mentionedValues(\n text: string,\n options: readonly ListboxOption[],\n prefix = '@',\n): string[] {\n const values = mentionSegments(text, options, prefix).flatMap((segment) =>\n segment.mention ? [segment.mention.value] : [],\n );\n return [...new Set(values)];\n}\n\n/** MentionText 与 Mentions 的样式:mention、text、panel */\nexport const mentionStyles = css.create({\n // 提及:强调色的文字,浅底\n mention: {\n color: '_accentText',\n backgroundColor: '_accentSoft',\n borderRadius: '_sm',\n paddingInline: '0.125em',\n fontWeight: '_medium',\n },\n text: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' },\n // 弹层贴着光标、不跟文本框同宽:给个合适的宽度\n panel: { width: '16em' },\n});\n\n/** 未声明的属性落到 span 上 */\nexport interface MentionTextProps extends PartProps<'span'> {\n /** 文字 */\n text: string;\n /** 能被提及的选项:“@显示文字”高亮 */\n options: readonly ListboxOption[];\n /** 触发的字符,默认 '@' */\n prefix?: string;\n /** 提及的部件属性,可以按选项计算(做成链接、悬停卡片时用 renderMention) */\n propsMention?: PartProps<'span'> | ((mention: ListboxOption) => PartProps<'span'>);\n /** 自己渲染一个提及(链接到个人页、HoverCard);不写时是高亮的文字 */\n renderMention?: (mention: ListboxOption, text: string) => VNodeChild;\n}\n\n/** 带提及的文字:“@名字”高亮,换行照常(pre-wrap) */\nexport const MentionText = _component(\n ({ text, options, prefix = '@', propsMention, renderMention, ...rest }: MentionTextProps) =>\n () => (\n <span {...mergeAttrs<'span'>({ sx: mentionStyles.text }, rest)}>\n {mentionSegments(text, options, prefix).map((segment) => {\n if (!segment.mention) return segment.text;\n if (renderMention) return renderMention(segment.mention, segment.text);\n const own =\n typeof propsMention === 'function' ? propsMention(segment.mention) : propsMention;\n return (\n <span {...mergeAttrs<'span'>({ sx: mentionStyles.mention }, own)}>{segment.text}</span>\n );\n })}\n </span>\n ),\n);\n\n/** 提及输入框:多行文本框 + 跟着 @ 弹出的人员列表 */\nexport const Mentions = _component(\n <T,>({\n _value: value = _bindable(''),\n _mentions: mentions = _bindable<string[]>([]),\n items = [],\n toOption,\n load,\n prefix = '@',\n filter,\n _open: open = _bindable(false),\n onOpenChange,\n loading = false,\n children,\n empty,\n propsRoot,\n propsPopover,\n propsListbox,\n ...rest\n }: MentionsProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n let shell = _state.raw<HTMLElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n // 正在提及:@ 在文字里的位置,与 @ 到光标之间的文字(过滤词)\n let trigger = _state<number | null>(null);\n let query = _state('');\n // 按 Esc 关掉的那个 @:光标还在它后面时不再弹出\n let dismissed: number | null = null;\n // 见过的选项(远程搜索换掉 items 之后,已提及的人仍能认出来)\n const known = new Map<string, ListboxOption>();\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const textarea = () => shell?.querySelector('textarea') ?? null;\n\n const remote = useRemoteItems({\n load: () => load,\n query: () => query,\n open: () => open,\n items: () => items,\n });\n const list = useListState({\n items: () =>\n load || filter === false\n ? remote.items()\n : remote\n .items()\n .filter((item) =>\n !query\n ? true\n : filter\n ? filter(item, query)\n : textMatcher()(optionOf(item).label, query),\n ),\n toOption: optionOf,\n selected: () => [],\n mode: () => 'single',\n onChange: () => {},\n });\n useResultAnnouncement(() => ({\n query: open ? query || prefix : '',\n count: list.options.length,\n }));\n\n // 文字里提到的人:随文字与见过的选项更新\n watch(\n () => [value, remote.items()] as const,\n ([text, current]) => {\n for (const item of current) {\n const option = optionOf(item);\n known.set(option.value, option);\n }\n const next = mentionedValues(text, [...known.values()], prefix);\n if (next.join('\\n') !== mentions.join('\\n')) mentions = next;\n },\n { immediate: true },\n );\n\n // 远程结果后到:打开着又没有高亮项时高亮第一项(Enter 才能直接选中)\n watch(\n () => list.options.length,\n () => {\n if (open && list.active === undefined) list.move('first');\n },\n );\n\n /** 看光标前面是不是正在写的提及:是就按 @ 后面的文字过滤并打开,不是就关闭 */\n function detect(event?: Event) {\n const element = textarea();\n if (!element || rest.readonly || rest.disabled) return;\n const caret = element.selectionStart;\n const before = element.value.slice(0, caret);\n const at = before.lastIndexOf(prefix);\n const typed = at < 0 ? '' : before.slice(at + prefix.length);\n const mentioning =\n at >= 0 &&\n element.selectionEnd === caret &&\n !WORD_BEFORE.test(before[at - 1] ?? '') &&\n !/\\s/.test(typed) &&\n typed.length <= 30;\n if (!mentioning || at === dismissed) {\n if (!mentioning) dismissed = null;\n trigger = null;\n if (open) setOpen(false, 'focus', event);\n return;\n }\n const opening = trigger !== at || !open;\n trigger = at;\n query = typed;\n if (opening) setOpen(true, 'trigger', event);\n list.move('first');\n }\n\n /** 选中一项:把“@过滤词”换成“@名字 ”,光标放在后面 */\n function pick(choice: string, event?: Event) {\n const element = textarea();\n const option = list.options.find((entry) => entry.value === choice);\n if (!element || trigger === null || !option) return;\n known.set(option.value, option);\n const inserted = `${prefix}${option.label} `;\n const caret = element.selectionStart;\n const start = trigger;\n value = element.value.slice(0, start) + inserted + element.value.slice(caret);\n trigger = null;\n setOpen(false, 'select', event);\n void nextTick(() => {\n element.focus();\n element.setSelectionRange(start + inserted.length, start + inserted.length);\n });\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (!open || isComposingKey(event)) return;\n if (event.key === 'Escape') {\n event.preventDefault();\n dismissed = trigger;\n setOpen(false, 'escape', event);\n return;\n }\n if (event.key === 'Tab' && list.active !== undefined) {\n event.preventDefault();\n pick(list.active, event);\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, (choice) => pick(choice, event)))\n event.preventDefault();\n }\n\n // 移动光标(方向键、Home / End)后重新判断;↑↓ 在列表打开时是移动高亮,不算\n function onKeyup(event: KeyboardEvent) {\n if (event.isComposing) return;\n if (open && (event.key === 'ArrowUp' || event.key === 'ArrowDown')) return;\n if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key) || !open) detect(event);\n }\n\n const { onToggle } = useAnchoredPopover(\n () => {\n const element = textarea();\n return {\n open,\n anchor: element && caretAnchor(element, () => trigger ?? element.selectionStart),\n panel,\n floating: { placement: 'bottom-start', fitHeight: true },\n restoreFocus: false,\n };\n },\n {\n close: (reason, event) => {\n if (reason === 'escape') dismissed = trigger;\n setOpen(false, reason, event);\n },\n },\n );\n\n return () => (\n <>\n <Textarea\n {...mergePartProps<TextareaProps>(\n { propsRoot: mergePartProps<PartProps<'div'>>({}, propsRoot, { ref: _toRef(shell) }) },\n rest,\n {\n 'aria-autocomplete': 'list',\n 'aria-controls': open ? listId : undefined,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n onInput: (event: Event) => !(event as InputEvent).isComposing && detect(event),\n onCompositionend: (event: CompositionEvent) => detect(event),\n onClick: (event: MouseEvent) => detect(event),\n onKeydown,\n onKeyup,\n onBlur: (event: FocusEvent) => open && setOpen(false, 'focus', event),\n },\n )}\n _value={value}\n />\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onToggle}\n size={rest.size}\n label={lang.mentionsList}\n loading={loading || remote.loading()}\n onPick={(choice) => pick(choice)}\n listbox={{\n list,\n id: listId,\n renderOption: children,\n empty: remote.error() ? lang.listLoadFailed : (empty ?? lang.mentionsEmpty),\n }}\n propsListbox={propsListbox}\n propsPopover={mergePartProps<PartProps<'div', 'id' | 'popover'>>(\n { sx: mentionStyles.panel },\n propsPopover,\n )}\n />\n </>\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Mentions.js","names":["_vtp_readonlyProp","_vtp_restProps","_createVNode","_vtp_bindable","_vtp_childrenProp","_vue_shallowRef","_vue_ref","_Fragment","_mergeProps"],"sources":["../../src/input/Mentions.tsx"],"sourcesContent":["/**\n * 提及:多行文本框里输入 @ 弹出人员(或岗位、群组)列表,选中后写成“@名字 ”。留言、审批意见、协商回复里通知相关的人。\n *\n * <Field label=\"留言\"><Mentions _value={text} items={people} _mentions={notified} /></Field>\n * <Mentions _value={text} load={(query, signal) => api.searchUsers(query, { signal })} toOption={…} />\n *\n * 值仍是文字;mentions 是文字里提到的选项的值(工号、岗位编号),随文字增删——删掉“@名字”就不再算提及。\n * 显示提及过的文字用 MentionText(提及高亮),拆分用 mentionSegments。\n *\n * - 弹出:@ 在开头或前面不是字母数字(邮箱里的 @ 不算),@ 与光标之间没有空白;列表贴在 @ 的位置(caretAnchor)。\n * - 过滤:本地按显示文字包含 @ 后面的文字;给 load 时按它远程搜索(同 Combobox)。\n * - 键盘:↑↓ 移动、Enter 或 Tab 选中、Esc 关闭(这个 @ 不再弹出,直到重新输入);焦点一直在文本框里,\n * 高亮项经 aria-activedescendant 告诉读屏,结果数量播报。中文输入法组合期间不弹出、不过滤。\n *\n * 外壳与自动增高同 Textarea。部件:Root(外壳)、Textarea、Popover、Listbox。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, useId, watch, type VNodeChild } from 'vue';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { caretAnchor } from '../utils/dom/caret';\nimport { useAnchoredPopover } from '../utils/dom/floating';\nimport { isComposingKey } from '../utils/dom/hotkeys';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport { ListPopover } from './ListPopover';\nimport {\n handleListKeydown,\n toListboxOption,\n useListState,\n useResultAnnouncement,\n type ListboxOption,\n type OptionMapping,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\nimport { Textarea, type TextareaProps } from './Textarea';\n\n/** 提及的弹出列表由组件管理 */\nexport type MentionsManaged = 'aria-autocomplete' | 'aria-controls' | 'aria-activedescendant';\n\n/** Mentions 除 toOption 外的属性;未声明的属性落到 textarea 上(同 Textarea) */\nexport interface MentionsBaseProps<T>\n extends Omit<TextareaProps, MentionsManaged>, OpenChangeProps {\n /** 可以提及的人(ListboxOption、字符串,或任意数据加 toOption);有 load 时是第一次结果之前的选项 */\n items?: readonly T[];\n /** 远程搜索:按 @ 后面的文字调用,停下 300 ms 后请求,只采用最后一次 */\n load?: OptionsLoader<T>;\n /** 文字里提到的选项的值:父级写 _mentions={x},随文字更新 */\n _mentions?: string[];\n /** 触发的字符,默认 '@' */\n prefix?: string;\n /** 过滤:默认按显示文字包含 @ 后面的文字;false 不过滤(由调用方换 items) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 列表是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 正在取选项 */\n loading?: boolean;\n /** 自定义选项内容:`{(item, { active }) => …}`(头像、部门) */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配的人时列表里显示的内容 */\n empty?: VNodeChild;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 提及输入框的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type MentionsProps<T = ListboxOption> = MentionsBaseProps<T> & OptionMapping<T>;\n\n/** 拆开的一段文字:普通文字,或提及(带它的选项) */\nexport interface MentionSegment {\n /** 这一段的文字(提及时含 @) */\n text: string;\n /** 提及的选项;普通文字没有 */\n mention?: ListboxOption;\n}\n\n/** @ 前面是这些字符时不算提及(邮箱 name@example.com) */\nconst WORD_BEFORE = /[A-Za-z0-9_.]/;\n\n/**\n * 把文字拆成普通文字与提及:“@名字”里的名字是 options 里某一项的显示文字(有多个能匹配时取最长的)。\n * 提及的显示(MentionText)与找出提到了谁(mentionedValues)都用它\n */\nexport function mentionSegments(\n text: string,\n options: readonly ListboxOption[],\n prefix = '@',\n): MentionSegment[] {\n const byLength = options\n .filter((option) => option.label)\n .toSorted((a, b) => b.label.length - a.label.length);\n const segments: MentionSegment[] = [];\n let plain = '';\n let index = 0;\n while (index < text.length) {\n const mention =\n text.startsWith(prefix, index) && !WORD_BEFORE.test(text[index - 1] ?? '')\n ? byLength.find((option) => text.startsWith(option.label, index + prefix.length))\n : undefined;\n if (!mention) {\n plain += text[index];\n index += 1;\n continue;\n }\n if (plain) segments.push({ text: plain });\n plain = '';\n const length = prefix.length + mention.label.length;\n segments.push({ text: text.slice(index, index + length), mention });\n index += length;\n }\n if (plain) segments.push({ text: plain });\n return segments;\n}\n\n/** 文字里提到了哪些选项(值,按第一次出现的顺序,不重复) */\nexport function mentionedValues(\n text: string,\n options: readonly ListboxOption[],\n prefix = '@',\n): string[] {\n const values = mentionSegments(text, options, prefix).flatMap((segment) =>\n segment.mention ? [segment.mention.value] : [],\n );\n return [...new Set(values)];\n}\n\n/** MentionText 与 Mentions 的样式:mention、text、panel */\nexport const mentionStyles = css.create({\n // 提及:强调色的文字,浅底\n mention: {\n color: '_accentText',\n backgroundColor: '_accentSoft',\n borderRadius: '_sm',\n paddingInline: '0.125em',\n fontWeight: '_medium',\n },\n text: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere' },\n // 弹层贴着光标、不跟文本框同宽:给个合适的宽度\n panel: { width: '16em' },\n});\n\n/** 未声明的属性落到 span 上 */\nexport interface MentionTextProps extends PartProps<'span'> {\n /** 文字 */\n text: string;\n /** 能被提及的选项:“@显示文字”高亮 */\n options: readonly ListboxOption[];\n /** 触发的字符,默认 '@' */\n prefix?: string;\n /** 提及的部件属性,可以按选项计算(做成链接、悬停卡片时用 renderMention) */\n propsMention?: PartProps<'span'> | ((mention: ListboxOption) => PartProps<'span'>);\n /** 自己渲染一个提及(链接到个人页、HoverCard);不写时是高亮的文字 */\n renderMention?: (mention: ListboxOption, text: string) => VNodeChild;\n}\n\n/** 带提及的文字:“@名字”高亮,换行照常(pre-wrap) */\nexport const MentionText = _component(\n ({ text, options, prefix = '@', propsMention, renderMention, ...rest }: MentionTextProps) =>\n () => (\n <span {...mergeAttrs<'span'>({ sx: mentionStyles.text }, rest)}>\n {mentionSegments(text, options, prefix).map((segment) => {\n if (!segment.mention) return segment.text;\n if (renderMention) return renderMention(segment.mention, segment.text);\n const own =\n typeof propsMention === 'function' ? propsMention(segment.mention) : propsMention;\n return (\n <span {...mergeAttrs<'span'>({ sx: mentionStyles.mention }, own)}>{segment.text}</span>\n );\n })}\n </span>\n ),\n);\n\n/** 提及输入框:多行文本框 + 跟着 @ 弹出的人员列表 */\nexport const Mentions = _component(\n <T,>({\n _value: value = _bindable(''),\n _mentions: mentions = _bindable<string[]>([]),\n items = [],\n toOption,\n load,\n prefix = '@',\n filter,\n _open: open = _bindable(false),\n onOpenChange,\n loading = false,\n children,\n empty,\n propsRoot,\n propsPopover,\n propsListbox,\n ...rest\n }: MentionsProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n let shell = _state.raw<HTMLElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n // 正在提及:@ 在文字里的位置,与 @ 到光标之间的文字(过滤词)\n let trigger = _state<number | null>(null);\n let query = _state('');\n // 按 Esc 关掉的那个 @:光标还在它后面时不再弹出\n let dismissed: number | null = null;\n // 见过的选项(远程搜索换掉 items 之后,已提及的人仍能认出来)\n const known = new Map<string, ListboxOption>();\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const textarea = () => shell?.querySelector('textarea') ?? null;\n\n const remote = useRemoteItems({\n load: () => load,\n query: () => query,\n open: () => open,\n items: () => items,\n });\n const list = useListState({\n items: () =>\n load || filter === false\n ? remote.items()\n : remote\n .items()\n .filter((item) =>\n !query\n ? true\n : filter\n ? filter(item, query)\n : textMatcher()(optionOf(item).label, query),\n ),\n toOption: optionOf,\n selected: () => [],\n mode: () => 'single',\n onChange: () => {},\n });\n useResultAnnouncement(() => ({\n query: open ? query || prefix : '',\n count: list.options.length,\n }));\n\n // 文字里提到的人:随文字与见过的选项更新\n watch(\n () => [value, remote.items()] as const,\n ([text, current]) => {\n for (const item of current) {\n const option = optionOf(item);\n known.set(option.value, option);\n }\n const next = mentionedValues(text, [...known.values()], prefix);\n if (next.join('\\n') !== mentions.join('\\n')) mentions = next;\n },\n { immediate: true },\n );\n\n // 远程结果后到:打开着又没有高亮项时高亮第一项(Enter 才能直接选中)\n watch(\n () => list.options.length,\n () => {\n if (open && list.active === undefined) list.move('first');\n },\n );\n\n /** 看光标前面是不是正在写的提及:是就按 @ 后面的文字过滤并打开,不是就关闭 */\n function detect(event?: Event) {\n const element = textarea();\n if (!element || rest.readonly || rest.disabled) return;\n const caret = element.selectionStart;\n const before = element.value.slice(0, caret);\n const at = before.lastIndexOf(prefix);\n const typed = at < 0 ? '' : before.slice(at + prefix.length);\n const mentioning =\n at >= 0 &&\n element.selectionEnd === caret &&\n !WORD_BEFORE.test(before[at - 1] ?? '') &&\n !/\\s/.test(typed) &&\n typed.length <= 30;\n if (!mentioning || at === dismissed) {\n if (!mentioning) dismissed = null;\n trigger = null;\n if (open) setOpen(false, 'focus', event);\n return;\n }\n const opening = trigger !== at || !open;\n trigger = at;\n query = typed;\n if (opening) setOpen(true, 'trigger', event);\n list.move('first');\n }\n\n /** 选中一项:把“@过滤词”换成“@名字 ”,光标放在后面 */\n function pick(choice: string, event?: Event) {\n const element = textarea();\n const option = list.options.find((entry) => entry.value === choice);\n if (!element || trigger === null || !option) return;\n known.set(option.value, option);\n const inserted = `${prefix}${option.label} `;\n const caret = element.selectionStart;\n const start = trigger;\n value = element.value.slice(0, start) + inserted + element.value.slice(caret);\n trigger = null;\n setOpen(false, 'select', event);\n void nextTick(() => {\n element.focus();\n element.setSelectionRange(start + inserted.length, start + inserted.length);\n });\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (!open || isComposingKey(event)) return;\n if (event.key === 'Escape') {\n event.preventDefault();\n dismissed = trigger;\n setOpen(false, 'escape', event);\n return;\n }\n if (event.key === 'Tab' && list.active !== undefined) {\n event.preventDefault();\n pick(list.active, event);\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, (choice) => pick(choice, event)))\n event.preventDefault();\n }\n\n // 移动光标(方向键、Home / End)后重新判断;↑↓ 在列表打开时是移动高亮,不算\n function onKeyup(event: KeyboardEvent) {\n if (event.isComposing) return;\n if (open && (event.key === 'ArrowUp' || event.key === 'ArrowDown')) return;\n if (['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key) || !open) detect(event);\n }\n\n const { onToggle } = useAnchoredPopover(\n () => {\n const element = textarea();\n return {\n open,\n anchor: element && caretAnchor(element, () => trigger ?? element.selectionStart),\n panel,\n floating: { placement: 'bottom-start', fitHeight: true },\n restoreFocus: false,\n };\n },\n {\n close: (reason, event) => {\n if (reason === 'escape') dismissed = trigger;\n setOpen(false, reason, event);\n },\n },\n );\n\n return () => (\n <>\n <Textarea\n {...mergePartProps<TextareaProps>(\n { propsRoot: mergePartProps<PartProps<'div'>>({}, propsRoot, { ref: _toRef(shell) }) },\n rest,\n {\n 'aria-autocomplete': 'list',\n 'aria-controls': open ? listId : undefined,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n onInput: (event: Event) => !(event as InputEvent).isComposing && detect(event),\n onCompositionend: (event: CompositionEvent) => detect(event),\n onClick: (event: MouseEvent) => detect(event),\n onKeydown,\n onKeyup,\n onBlur: (event: FocusEvent) => open && setOpen(false, 'focus', event),\n },\n )}\n _value={value}\n />\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onToggle}\n size={rest.size}\n label={lang.mentionsList}\n loading={loading || remote.loading()}\n onPick={(choice) => pick(choice)}\n listbox={{\n list,\n id: listId,\n renderOption: children,\n empty: remote.failure() ?? empty ?? lang.mentionsEmpty,\n }}\n propsListbox={propsListbox}\n propsPopover={mergePartProps<PartProps<'div', 'id' | 'popover'>>(\n { sx: mentionStyles.panel },\n propsPopover,\n )}\n />\n </>\n );\n },\n);\n"],"mappings":"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"}
@@ -20,7 +20,7 @@ import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
20
20
  import { BriefcaseBusiness, Building, ChevronRight, Search, X } from "@lucide/icons";
21
21
  //#region src/input/PeoplePickerPanel.tsx
22
22
  /**
23
- * 人员与组织选择面板:左边按组织架构一层层找(面包屑回到上层),或搜索、看岗位与最近选过的,勾选;右边是已选的,可以移除、清空。
23
+ * 人员与组织选择面板:左边按组织架构一层层找(面包屑回到上层),或搜索、看角色与最近选过的,勾选;右边是已选的,可以移除、清空。
24
24
  * PeoplePicker 把它放进对话框;也可以直接放在页面、抽屉里。数据见 people.ts(source)。
25
25
  *
26
26
  * <PeoplePickerPanel source={source} _value={members} types={['user', 'department']} recentKey="project-members" />
@@ -129,29 +129,29 @@ var PeoplePickerPanel = /*#__PURE__*/ _component((_props, _ctx) => {
129
129
  keepPrevious: false,
130
130
  enabled: searching
131
131
  });
132
- const positions = useRequest((_, signal) => source.value.positions(signal), { immediate: false });
132
+ const roles = useRequest((_, signal) => source.value.roles(signal), { immediate: false });
133
133
  watch(() => page.value, (next) => {
134
- if (next === "positions" && positions.data == null && !positions.loading) positions.refresh();
134
+ if (next === "roles" && roles.data == null && !roles.loading) roles.refresh();
135
135
  });
136
136
  const pages = () => [
137
137
  "org",
138
- ...source.value.positions ? ["positions"] : [],
138
+ ...source.value.roles ? ["roles"] : [],
139
139
  ...key ? ["recent"] : []
140
140
  ];
141
141
  const pageLabel = {
142
142
  org: () => lang.peopleOrg,
143
- positions: () => lang.peoplePositions,
143
+ roles: () => lang.peopleRoles,
144
144
  recent: () => lang.peopleRecent
145
145
  };
146
146
  /** 现在列出的:搜索结果,或当前页 */
147
147
  const shown = () => {
148
148
  if (searching()) return {
149
149
  items: found.data ?? [],
150
- loading: found.loading
150
+ loading: found.loading || found.data === void 0 && !found.error
151
151
  };
152
- if (page.value === "positions") return {
153
- items: positions.data ?? [],
154
- loading: positions.loading
152
+ if (page.value === "roles") return {
153
+ items: roles.data ?? [],
154
+ loading: roles.loading
155
155
  };
156
156
  if (page.value === "recent") return {
157
157
  items: recent.value,
@@ -205,7 +205,7 @@ var PeoplePickerPanel = /*#__PURE__*/ _component((_props, _ctx) => {
205
205
  if (pickable(entry)) toggle(entry);
206
206
  else if (drillable(entry)) open(entry);
207
207
  }
208
- /** 行首的圆形标记:人员是头像,部门、岗位是图标 */
208
+ /** 行首的圆形标记:人员是头像,部门、角色是图标 */
209
209
  const badge = (entry) => entry.type === "user" ? createVNode(Avatar, {
210
210
  "name": entry.name,
211
211
  "src": entry.avatar,
@@ -274,7 +274,7 @@ var PeoplePickerPanel = /*#__PURE__*/ _component((_props, _ctx) => {
274
274
  key: "",
275
275
  label: lang.peopleRoot
276
276
  }, ...path.value.map((department) => ({
277
- key: department.id,
277
+ key: peopleKey(department),
278
278
  label: department.name
279
279
  }))],
280
280
  "onNavigate": _cache[2] || (_cache[2] = (_, index) => path.value = path.value.slice(0, index))