ropav 0.1.4 → 0.1.6

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 (138) hide show
  1. package/README.md +20 -0
  2. package/dist/accordion.js +11 -8
  3. package/dist/alert.css +18 -18
  4. package/dist/alert.js +27 -21
  5. package/dist/avatar.css +19 -19
  6. package/dist/avatar.js +16 -11
  7. package/dist/badge.css +16 -16
  8. package/dist/badge.js +14 -9
  9. package/dist/base.css +214 -69
  10. package/dist/button-group.js +1 -1
  11. package/dist/button-link.js +16 -14
  12. package/dist/button.css +37 -28
  13. package/dist/button.js +16 -14
  14. package/dist/{useButtonColor.js → button.scss_vue_type_style_index_0_src_true_lang.js} +8 -4
  15. package/dist/card.js +1 -1
  16. package/dist/checkbox.css +32 -32
  17. package/dist/checkbox.js +19 -11
  18. package/dist/chevron-right.js +12 -0
  19. package/dist/collapse.css +6 -6
  20. package/dist/collapse.js +4 -4
  21. package/dist/collectionNavigation.js +120 -0
  22. package/dist/color-input.css +19 -19
  23. package/dist/color-input.js +6 -5
  24. package/dist/color-picker.css +7 -7
  25. package/dist/color-picker.js +4 -5
  26. package/dist/color-swatch.js +1 -1
  27. package/dist/componentColors.js +135 -23
  28. package/dist/components/alert/types.d.ts +1 -0
  29. package/dist/components/alert/useAlertColor.d.ts +1 -1
  30. package/dist/components/avatar/types.d.ts +1 -0
  31. package/dist/components/avatar/useAvatarColor.d.ts +1 -1
  32. package/dist/components/badge/types.d.ts +1 -0
  33. package/dist/components/badge/useBadgeColor.d.ts +1 -1
  34. package/dist/components/button/types.d.ts +1 -0
  35. package/dist/components/button/useButtonColor.d.ts +1 -1
  36. package/dist/components/button-link/types.d.ts +1 -0
  37. package/dist/components/checkbox/types.d.ts +1 -0
  38. package/dist/components/checkbox/useCheckbox.d.ts +1 -1
  39. package/dist/components/color-input/color-input.d.ts +2 -2
  40. package/dist/components/color-input/useColorInput.d.ts +1 -1
  41. package/dist/components/dialog/dialog-core.d.ts +1 -1
  42. package/dist/components/dropdown-menu/dropdown-menu-content.d.ts +2 -2
  43. package/dist/components/dropdown-menu/dropdown-menu-primitive-core.d.ts +2 -1
  44. package/dist/components/dropdown-menu/dropdown-menu-sub-content.d.ts +2 -2
  45. package/dist/components/dropdown-menu/dropdown-menu-utils.d.ts +0 -2
  46. package/dist/components/dropdown-menu/dropdown-menu.d.ts +3 -3
  47. package/dist/components/dropdown-menu/index.d.ts +1 -0
  48. package/dist/components/dropdown-menu/types.d.ts +4 -0
  49. package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +3 -4
  50. package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +2 -1
  51. package/dist/components/dropdown-menu/useDropdownMenuNavigation.d.ts +1 -0
  52. package/dist/components/icon-button/types.d.ts +1 -0
  53. package/dist/components/input/useInput.d.ts +1 -1
  54. package/dist/components/number-input/useNumberInput.d.ts +1 -1
  55. package/dist/components/pagination/index.d.ts +4 -0
  56. package/dist/components/pagination/index.js +2 -0
  57. package/dist/components/pagination/pagination.d.ts +49 -0
  58. package/dist/components/pagination/types.d.ts +54 -0
  59. package/dist/components/pagination/usePagination.d.ts +19 -0
  60. package/dist/components/progress/useProgress.d.ts +1 -1
  61. package/dist/components/radio/types.d.ts +3 -0
  62. package/dist/components/radio/useRadio.d.ts +2 -2
  63. package/dist/components/scroll-area/scrollAreaCore.d.ts +5 -0
  64. package/dist/components/scroll-area/types.d.ts +4 -0
  65. package/dist/components/scroll-area/useScrollArea.d.ts +1 -0
  66. package/dist/components/scroll-area/useScrollAreaMetrics.d.ts +3 -0
  67. package/dist/components/scroll-area/useScrollAreaPresentation.d.ts +3 -0
  68. package/dist/components/select/useSelect.d.ts +3 -2
  69. package/dist/components/select/useSelectNativeValue.d.ts +1 -7
  70. package/dist/components/slider/range-slider-tooltip.d.ts +2 -0
  71. package/dist/components/slider/sliderCore.d.ts +2 -1
  72. package/dist/components/slider/types.d.ts +1 -1
  73. package/dist/components/slider/useRangeSlider.d.ts +3 -1
  74. package/dist/components/slider/useSlider.d.ts +3 -1
  75. package/dist/components/switch/useSwitch.d.ts +1 -1
  76. package/dist/components/textarea/useTextarea.d.ts +1 -1
  77. package/dist/components/toast/types.d.ts +2 -0
  78. package/dist/components/toast/useToastColor.d.ts +1 -1
  79. package/dist/components/tooltip/types.d.ts +1 -0
  80. package/dist/components/tooltip/useTooltip.d.ts +1 -1
  81. package/dist/composables/index.d.ts +2 -0
  82. package/dist/composables/index.js +2 -0
  83. package/dist/composables/useControllableValue.d.ts +14 -0
  84. package/dist/dialog.js +8 -5
  85. package/dist/dropdown-menu.js +98 -59
  86. package/dist/field.js +1 -1
  87. package/dist/floating.js +19 -7
  88. package/dist/icon-button.css +12 -169
  89. package/dist/icon-button.js +11 -7
  90. package/dist/index.d.ts +6 -4
  91. package/dist/index.js +8 -5
  92. package/dist/input.css +24 -24
  93. package/dist/input.js +6 -5
  94. package/dist/modal.js +11 -7
  95. package/dist/number-input.css +18 -18
  96. package/dist/number-input.js +8 -7
  97. package/dist/overlay.js +1 -1
  98. package/dist/pagination.css +140 -0
  99. package/dist/pagination.js +442 -0
  100. package/dist/popover.js +9 -6
  101. package/dist/progress.css +29 -21
  102. package/dist/progress.js +17 -10
  103. package/dist/radio.js +17 -7
  104. package/dist/scroll-area.css +10 -1
  105. package/dist/scroll-area.js +82 -25
  106. package/dist/select.css +45 -45
  107. package/dist/select.js +111 -70
  108. package/dist/slider.css +191 -191
  109. package/dist/slider.js +58 -46
  110. package/dist/switch.css +17 -17
  111. package/dist/switch.js +7 -6
  112. package/dist/tabs.css +3 -3
  113. package/dist/tabs.js +25 -15
  114. package/dist/textarea.css +26 -26
  115. package/dist/textarea.js +5 -4
  116. package/dist/toast.css +26 -26
  117. package/dist/toast.js +35 -23
  118. package/dist/tooltip.css +12 -12
  119. package/dist/tooltip.js +24 -16
  120. package/dist/unplugin-icons.js +38 -25
  121. package/dist/useCollapse.js +12 -7
  122. package/dist/useControlState.js +1 -1
  123. package/dist/useControllableValue.js +33 -0
  124. package/dist/useFloatingPosition.js +4 -1140
  125. package/dist/useFormControl.js +5 -29
  126. package/dist/useOverlayZIndex.js +1 -1
  127. package/dist/useRequiredInject.js +1 -1
  128. package/dist/utils/componentColors.d.ts +14 -1
  129. package/docs/public-composables-api.md +52 -0
  130. package/docs/public-styles-api.md +1 -1
  131. package/docs/public-tokens.md +648 -508
  132. package/package.json +49 -36
  133. package/src/styles/_mixins.scss +4 -0
  134. package/src/styles/_tokens.scss +460 -320
  135. package/src/styles/_variables.scss +1 -1
  136. package/src/styles/styles-manifest.json +1122 -2
  137. package/dist/button-link.css +0 -163
  138. /package/dist/{composables → internal/composables}/useOverlayLayer.d.ts +0 -0
@@ -5,6 +5,8 @@ declare const __VLS_export: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup
5
5
  props: import('vue').PublicProps & __VLS_PrettifyLocal<{
6
6
  arrow?: boolean;
7
7
  color?: TooltipColor;
8
+ autoContrast?: boolean;
9
+ contrastColor?: string;
8
10
  content: [string, string];
9
11
  ids: [string | undefined, string | undefined];
10
12
  mergedContent: string;
@@ -6,7 +6,8 @@ export interface SliderBounds {
6
6
  }
7
7
  interface SliderMarkStyleProperties {
8
8
  position: `--_rp-${string}`;
9
- colors: readonly `--_rp-${string}`[];
9
+ decorativeColors: readonly `--_rp-${string}`[];
10
+ foregroundColors: readonly `--_rp-${string}`[];
10
11
  }
11
12
  interface SliderThumbStyleProperties {
12
13
  size: `--${string}`;
@@ -23,7 +23,7 @@ export type RangeSliderEndpointValueText = string | SliderValueFormatter;
23
23
  export type RangeSliderAriaValueText = RangeSliderEndpointValueText | [RangeSliderEndpointValueText, RangeSliderEndpointValueText];
24
24
  export type RangeSliderValidationMessage = string | [string | undefined, string | undefined];
25
25
  export type SliderTooltipMode = 'hover' | 'always';
26
- type SliderTooltipBaseOptions = Pick<TooltipProps, 'id' | 'placement' | 'color' | 'offset' | 'openDelay' | 'arrow'>;
26
+ type SliderTooltipBaseOptions = Pick<TooltipProps, 'id' | 'placement' | 'color' | 'autoContrast' | 'contrastColor' | 'offset' | 'openDelay' | 'arrow'>;
27
27
  export type SliderTooltipAnchor = 'thumb' | 'pointer';
28
28
  export type SliderTooltipOptions = (SliderTooltipBaseOptions & {
29
29
  anchor?: 'thumb';
@@ -13,7 +13,7 @@ export declare function normalizeRangeSliderMinRange(minRange: number, min: numb
13
13
  export declare function normalizeRangeSliderValue(value: RangeSliderValue, min: number, max: number, step: number | 'any', minRange?: number): RangeSliderValue;
14
14
  export declare function getClosestRangeSliderThumb(value: number, range: RangeSliderValue, activeThumb?: RangeSliderThumb): RangeSliderThumb;
15
15
  export declare function useRangeSlider(props: RangeSliderStateProps, emitUpdate: (value: RangeSliderValue) => void, getValue?: () => RangeSliderValue): {
16
- control: import('../../composables/useControlState.js').ControlState;
16
+ control: import('../../internal/composables/useControlState.js').ControlState;
17
17
  nativeMin: import('vue').ComputedRef<RangeSliderValue>;
18
18
  nativeMax: import('vue').ComputedRef<RangeSliderValue>;
19
19
  nativeStep: import('vue').ComputedRef<number | "any">;
@@ -42,6 +42,8 @@ export declare function useRangeSlider(props: RangeSliderStateProps, emitUpdate:
42
42
  tooltipIds: import('vue').ComputedRef<[string | undefined, string | undefined]>;
43
43
  mergedTooltipId: import('vue').ComputedRef<string | undefined>;
44
44
  tooltipColor: import('vue').ComputedRef<import('../../utils/componentColors.js').ComponentColorValue | undefined>;
45
+ tooltipAutoContrast: import('vue').ComputedRef<boolean | undefined>;
46
+ tooltipContrastColor: import('vue').ComputedRef<string | undefined>;
45
47
  tooltipOffset: import('vue').ComputedRef<import('../floating/index.js').FloatingOffset | undefined>;
46
48
  tooltipOpenDelay: import('vue').ComputedRef<number>;
47
49
  tooltipArrow: import('vue').ComputedRef<boolean>;
@@ -10,7 +10,7 @@ type SliderStateProps = Readonly<SliderProps & {
10
10
  orientation: NonNullable<SliderProps['orientation']>;
11
11
  }>;
12
12
  export declare function useSlider(props: SliderStateProps, emitUpdate: (value: number) => void, getValue?: () => number): {
13
- control: import('../../composables/useControlState.js').ControlState;
13
+ control: import('../../internal/composables/useControlState.js').ControlState;
14
14
  nativeMin: import('vue').ComputedRef<number>;
15
15
  nativeMax: import('vue').ComputedRef<number>;
16
16
  nativeStep: import('vue').ComputedRef<number | "any">;
@@ -38,6 +38,8 @@ export declare function useSlider(props: SliderStateProps, emitUpdate: (value: n
38
38
  tooltipPlacement: import('vue').ComputedRef<import('../tooltip/index.js').TooltipPlacement>;
39
39
  tooltipId: import('vue').ComputedRef<string | undefined>;
40
40
  tooltipColor: import('vue').ComputedRef<import('../../utils/componentColors.js').ComponentColorValue | undefined>;
41
+ tooltipAutoContrast: import('vue').ComputedRef<boolean | undefined>;
42
+ tooltipContrastColor: import('vue').ComputedRef<string | undefined>;
41
43
  tooltipOffset: import('vue').ComputedRef<import('../floating/index.js').FloatingOffset | undefined>;
42
44
  tooltipOpenDelay: import('vue').ComputedRef<number>;
43
45
  tooltipArrow: import('vue').ComputedRef<boolean>;
@@ -2,7 +2,7 @@ import { CSSProperties } from 'vue';
2
2
  import { SwitchProps } from './types.js';
3
3
  export declare function useSwitch(props: Readonly<SwitchProps>, emitUpdate: (value: boolean) => void, getValue?: () => boolean): {
4
4
  inputRef: import('vue').Ref<HTMLInputElement | null, HTMLInputElement | null>;
5
- control: import('../../composables/useControlState.js').ControlState;
5
+ control: import('../../internal/composables/useControlState.js').ControlState;
6
6
  rootClass: import('vue').ComputedRef<string[]>;
7
7
  rootStyle: import('vue').ComputedRef<CSSProperties | undefined>;
8
8
  onChange: (e: Event) => void;
@@ -1,7 +1,7 @@
1
1
  import { TextareaProps } from './types.js';
2
2
  export declare function useTextarea(props: Readonly<TextareaProps>, emitUpdate: (value: string) => void, getValue?: () => string): {
3
3
  textareaRef: import('vue').Ref<HTMLTextAreaElement | null, HTMLTextAreaElement | null>;
4
- control: import('../../composables/useControlState.js').ControlState;
4
+ control: import('../../internal/composables/useControlState.js').ControlState;
5
5
  rootClass: import('vue').ComputedRef<string[]>;
6
6
  nativeRows: import('vue').ComputedRef<number | undefined>;
7
7
  onInput: (e: Event) => void;
@@ -27,6 +27,7 @@ export interface ToastProps extends StylesApiProps<ToastPart> {
27
27
  variant?: ToastVariant;
28
28
  color?: ToastColor;
29
29
  autoContrast?: boolean;
30
+ contrastColor?: string;
30
31
  radius?: ToastRadius;
31
32
  role?: ToastRole;
32
33
  duration?: number;
@@ -61,6 +62,7 @@ export interface ToastStoreOptions {
61
62
  variant?: ToastVariant;
62
63
  color?: ToastColor;
63
64
  autoContrast?: boolean;
65
+ contrastColor?: string;
64
66
  radius?: ToastRadius;
65
67
  role?: ToastRole;
66
68
  pauseOnHover?: boolean;
@@ -1,3 +1,3 @@
1
1
  import { CSSProperties } from 'vue';
2
2
  import { ToastColor, ToastVariant } from './types.js';
3
- export declare function getToastColorStyle(color: ToastColor | undefined, variant: ToastVariant | undefined, autoContrast: boolean | undefined): CSSProperties | undefined;
3
+ export declare function getToastColorStyle(color: ToastColor | undefined, variant: ToastVariant | undefined, autoContrast: boolean | undefined, contrastColor?: string): CSSProperties | undefined;
@@ -25,6 +25,7 @@ export interface TooltipProps extends FloatingPositionProps<TooltipPlacement>, S
25
25
  content?: string;
26
26
  color?: TooltipColor;
27
27
  autoContrast?: boolean;
28
+ contrastColor?: string;
28
29
  open?: boolean;
29
30
  openDelay?: number;
30
31
  disabled?: boolean;
@@ -2,7 +2,7 @@ import { CSSProperties } from 'vue';
2
2
  import { TooltipOffset, TooltipProps, TooltipTriggerProps } from './types.js';
3
3
  type TooltipBehaviorProps = Omit<TooltipProps, 'classNames' | 'styles'>;
4
4
  export declare function resolveTooltipOffsetStyle(offset: TooltipOffset | undefined): CSSProperties | undefined;
5
- export declare function resolveTooltipColorStyleWithContrast(color: TooltipProps['color'], autoContrast: TooltipProps['autoContrast']): CSSProperties | undefined;
5
+ export declare function resolveTooltipColorStyleWithContrast(color: TooltipProps['color'], autoContrast: TooltipProps['autoContrast'], contrastColor?: TooltipProps['contrastColor']): CSSProperties | undefined;
6
6
  export declare function useTooltip(props: Readonly<TooltipBehaviorProps>, emitOpenChange?: (open: boolean) => void): {
7
7
  rootRef: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
8
8
  contentRef: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
@@ -0,0 +1,2 @@
1
+ export { useControllableValue } from './useControllableValue.js';
2
+ export type { UseControllableValueOptions, UseControllableValueReturn, } from './useControllableValue.js';
@@ -0,0 +1,2 @@
1
+ import { t as useControllableValue } from "../useControllableValue.js";
2
+ export { useControllableValue };
@@ -0,0 +1,14 @@
1
+ import { ComputedRef } from 'vue';
2
+ export interface UseControllableValueOptions<T> {
3
+ modelValue: () => T | undefined;
4
+ defaultValue: () => T;
5
+ onChange: (value: T) => void;
6
+ }
7
+ export interface UseControllableValueReturn<T> {
8
+ initialValue: T;
9
+ isControlled: ComputedRef<boolean>;
10
+ value: ComputedRef<T>;
11
+ setValue: (value: T) => void;
12
+ resetValue: (value?: T) => void;
13
+ }
14
+ export declare function useControllableValue<T>(options: Readonly<UseControllableValueOptions<T>>): UseControllableValueReturn<T>;
package/dist/dialog.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as useControllableValue } from "./useControllableValue.js";
1
2
  import { t as useRequiredInject } from "./useRequiredInject.js";
2
3
  import { i as useOverlayLayerBranch, n as useOverlayZIndex, r as useOverlayLayer } from "./useOverlayZIndex.js";
3
4
  import { t as useFocusTrap } from "./useFocusTrap.js";
@@ -340,8 +341,12 @@ var dialog_root_default = /* @__PURE__ */ defineVaporComponent({
340
341
  const props = __props;
341
342
  const emit = __emit;
342
343
  const generatedId = useId();
343
- const uncontrolledOpen = ref(props.defaultOpen);
344
- const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
344
+ const controllableOpen = useControllableValue({
345
+ modelValue: () => props.open,
346
+ defaultValue: () => props.defaultOpen,
347
+ onChange: (value) => emit("update:open", value)
348
+ });
349
+ const isOpen = controllableOpen.value;
345
350
  const modal = computed(() => props.modal);
346
351
  const closeOnEscape = computed(() => props.closeOnEscape);
347
352
  const closeOnOutsideClick = computed(() => props.closeOnOutsideClick);
@@ -366,9 +371,7 @@ var dialog_root_default = /* @__PURE__ */ defineVaporComponent({
366
371
  })
367
372
  });
368
373
  function setOpen(value) {
369
- const previous = isOpen.value;
370
- if (props.open === void 0) uncontrolledOpen.value = value;
371
- if (previous !== value) emit("update:open", value);
374
+ if (isOpen.value !== value) controllableOpen.setValue(value);
372
375
  }
373
376
  function rememberFocus() {
374
377
  if (typeof document === "undefined" || restoreFocusTo) return;
@@ -1,11 +1,14 @@
1
1
  import './dropdown-menu.css';
2
- import { t as bem } from "./bem.js";
2
+ import { t as useControllableValue } from "./useControllableValue.js";
3
3
  import { n as useStylesApi, t as presence } from "./styles-api.js";
4
4
  import { t as useRequiredInject } from "./useRequiredInject.js";
5
+ import { t as bem } from "./bem.js";
5
6
  import { n as useOverlayZIndex, r as useOverlayLayer } from "./useOverlayZIndex.js";
6
7
  import { n as useFloatingPosition, r as useFloatingTarget, t as isElementReference } from "./useFloatingPosition.js";
7
8
  import { n as useTeleportPositioningKey, r as useTeleportTarget, t as provideTeleportTarget } from "./useTeleportTarget.js";
8
- import { VaporTeleport, VaporTransition, child, computed, createComponent, createComponentWithFallback, createDynamicComponent, createFor, createIf, createSlot, createTemplateRefSetter, defineVaporComponent, extend, isRef, markRaw, mergeProps, nextTick, onBeforeUnmount, onMounted, onUnmounted, provide, ref, renderEffect, resolveComponent, setAttr, setDynamicProps, setInsertionState, setStaticTemplateRef, setStyle, setTemplateRefBinding, setText, shallowRef, template, toDisplayString, txt, unref, useAttrs, useId, watch } from "vue";
9
+ import { n as getNextEnabledIndex, r as useTypeahead, t as getEnabledIndexes } from "./collectionNavigation.js";
10
+ import { t as chevron_right_default } from "./chevron-right.js";
11
+ import { VaporTeleport, VaporTransition, child, computed, createComponent, createComponentWithFallback, createDynamicComponent, createFor, createIf, createSlot, createTemplateRefSetter, defineVaporComponent, extend, isRef, mergeProps, nextTick, onBeforeUnmount, onMounted, onUnmounted, provide, ref, renderEffect, resolveComponent, setAttr, setDynamicProps, setInsertionState, setStaticTemplateRef, setStyle, setTemplateRefBinding, setText, shallowRef, template, toDisplayString, txt, unref, useAttrs, useId, watch } from "vue";
9
12
  //#region src/components/dropdown-menu/dropdown-menu-primitive-core.ts
10
13
  var rootKey = Symbol("dropdown-menu-root");
11
14
  var menuKey = Symbol("dropdown-menu-content");
@@ -156,6 +159,17 @@ function createMenuContext(options) {
156
159
  const item = enabledItems[((currentIndex < 0 ? direction === 1 ? -1 : 0 : currentIndex) + direction + enabledItems.length) % enabledItems.length];
157
160
  if (item) setActive(item.id);
158
161
  }
162
+ const typeahead = useTypeahead({
163
+ items: () => sortItems(items.value),
164
+ activeIndex: () => sortItems(items.value).findIndex((item) => item.id === activeId.value),
165
+ getKey: (item) => item.id,
166
+ getTextValue: (item) => item.textValue(),
167
+ isDisabled: (item) => item.disabled(),
168
+ onMatch: (item) => setActive(item.id)
169
+ });
170
+ watch(computed(() => options.parentSub?.isOpen.value ?? options.root.isOpen.value), (open) => {
171
+ if (!open) typeahead.reset();
172
+ }, { flush: "sync" });
159
173
  function onHorizontalKeydown(event, active) {
160
174
  if (options.parentSub && event.key === getCloseDirection(context)) {
161
175
  event.preventDefault();
@@ -169,6 +183,10 @@ function createMenuContext(options) {
169
183
  active.submenu.open("first");
170
184
  }
171
185
  function onKeydown(event) {
186
+ if (typeahead.handleKey(event)) {
187
+ event.stopPropagation();
188
+ return;
189
+ }
172
190
  const active = items.value.find((item) => item.id === activeId.value);
173
191
  switch (event.key) {
174
192
  case "ArrowDown":
@@ -249,6 +267,7 @@ function usePrimitiveItem(componentName, props, emitSelect, options) {
249
267
  return id.value;
250
268
  },
251
269
  element: () => element.value,
270
+ textValue: () => props.textValue ?? element.value?.textContent?.trim() ?? "",
252
271
  disabled: () => isDisabled.value,
253
272
  activate
254
273
  };
@@ -302,6 +321,7 @@ var dropdown_menu_checkbox_item_default = /* @__PURE__ */ defineVaporComponent({
302
321
  },
303
322
  id: {},
304
323
  as: { default: "button" },
324
+ textValue: {},
305
325
  disabled: {
306
326
  type: Boolean,
307
327
  default: false
@@ -320,14 +340,17 @@ var dropdown_menu_checkbox_item_default = /* @__PURE__ */ defineVaporComponent({
320
340
  const props = __props;
321
341
  const emit = __emit;
322
342
  const attrs = useAttrs();
323
- const uncontrolled = ref(props.defaultValue);
324
- const value = computed(() => props.modelValue ?? uncontrolled.value);
343
+ const controllable = useControllableValue({
344
+ modelValue: () => props.modelValue,
345
+ defaultValue: () => props.defaultValue,
346
+ onChange: (value) => emit("update:modelValue", value)
347
+ });
348
+ const value = controllable.value;
325
349
  const checked = computed(() => value.value === "indeterminate" ? "mixed" : value.value);
326
350
  const state = computed(() => value.value === "indeterminate" ? "indeterminate" : value.value ? "checked" : "unchecked");
327
351
  function toggleChecked() {
328
352
  const nextValue = value.value === "indeterminate" ? true : !value.value;
329
- if (props.modelValue === void 0) uncontrolled.value = nextValue;
330
- emit("update:modelValue", nextValue);
353
+ controllable.setValue(nextValue);
331
354
  }
332
355
  provide(checkedKey, {
333
356
  state,
@@ -569,7 +592,7 @@ function useDropdownMenuPrimitiveContent(props, attrs, events, submenu) {
569
592
  }
570
593
  //#endregion
571
594
  //#region src/components/dropdown-menu/dropdown-menu-content.vue?vue&type=script&setup=true&vapor=true&lang.ts
572
- var t0$3 = template("<span class=rp-dropdown-menu__arrow aria-hidden=true>");
595
+ var t0$2 = template("<span class=rp-dropdown-menu__arrow aria-hidden=true>");
573
596
  //#endregion
574
597
  //#region src/components/dropdown-menu/dropdown-menu-content.vue
575
598
  var dropdown_menu_content_default = /* @__PURE__ */ defineVaporComponent({
@@ -625,7 +648,7 @@ var dropdown_menu_content_default = /* @__PURE__ */ defineVaporComponent({
625
648
  return createIf(() => unref(shouldRender), () => {
626
649
  const n6 = createDynamicComponent(() => __props.as, { $: [() => unref(rootAttrs)] }, extend(() => {
627
650
  return [createIf(() => __props.arrow, () => {
628
- const n4 = t0$3();
651
+ const n4 = t0$2();
629
652
  _setTemplateRef(n4, arrowElement, null, "arrowElement");
630
653
  renderEffect(() => {
631
654
  setAttr(n4, "data-side", unref(placementSide));
@@ -746,7 +769,6 @@ var dropdown_menu_context_trigger_default = /* @__PURE__ */ defineVaporComponent
746
769
  const rootAttrs = computed(() => mergeProps(attrs, {
747
770
  id: id.value,
748
771
  "aria-controls": root.contentId.value,
749
- "aria-expanded": root.isOpen.value,
750
772
  "aria-haspopup": "menu",
751
773
  "aria-disabled": optionalAttr(isDisabled.value),
752
774
  "data-state": root.isOpen.value ? "open" : "closed",
@@ -781,6 +803,7 @@ var dropdown_menu_item_default = /* @__PURE__ */ defineVaporComponent({
781
803
  id: {},
782
804
  as: { default: "button" },
783
805
  value: {},
806
+ textValue: {},
784
807
  disabled: {
785
808
  type: Boolean,
786
809
  default: false
@@ -937,12 +960,17 @@ var dropdown_menu_radio_group_default = /* @__PURE__ */ defineVaporComponent({
937
960
  const emit = __emit;
938
961
  const attrs = useAttrs();
939
962
  useRequiredInject(menuKey, "RpDropdownMenuRadioGroup");
940
- const uncontrolled = ref(props.defaultValue);
941
- const value = computed(() => props.modelValue === void 0 ? uncontrolled.value : props.modelValue);
963
+ const controllable = useControllableValue({
964
+ modelValue: () => props.modelValue,
965
+ defaultValue: () => props.defaultValue,
966
+ onChange: (value) => {
967
+ if (value !== null) emit("update:modelValue", value);
968
+ }
969
+ });
970
+ const value = controllable.value;
942
971
  function select(nextValue) {
943
972
  if (value.value === nextValue) return;
944
- if (props.modelValue === void 0) uncontrolled.value = nextValue;
945
- emit("update:modelValue", nextValue);
973
+ controllable.setValue(nextValue);
946
974
  }
947
975
  provide(radioGroupKey, {
948
976
  value,
@@ -956,7 +984,7 @@ var dropdown_menu_radio_group_default = /* @__PURE__ */ defineVaporComponent({
956
984
  "aria-labelledby": props.ariaLabelledby
957
985
  }));
958
986
  return createDynamicComponent(() => __props.as, { $: [() => rootAttrs.value] }, extend(() => {
959
- return createSlot("default", { value: () => value.value });
987
+ return createSlot("default", { value: () => unref(value) });
960
988
  }, { _: 8 }), 1);
961
989
  }
962
990
  });
@@ -970,6 +998,7 @@ var dropdown_menu_radio_item_default = /* @__PURE__ */ defineVaporComponent({
970
998
  value: {},
971
999
  id: {},
972
1000
  as: { default: "button" },
1001
+ textValue: {},
973
1002
  disabled: {
974
1003
  type: Boolean,
975
1004
  default: false
@@ -1068,8 +1097,12 @@ var dropdown_menu_root_default = /* @__PURE__ */ defineVaporComponent({
1068
1097
  const emit = __emit;
1069
1098
  const generatedId = useId();
1070
1099
  const id = computed(() => props.id ?? `${generatedId}-dropdown-menu`);
1071
- const uncontrolledOpen = ref(props.defaultOpen);
1072
- const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
1100
+ const controllableOpen = useControllableValue({
1101
+ modelValue: () => props.open,
1102
+ defaultValue: () => props.defaultOpen,
1103
+ onChange: (nextOpen) => emit("update:open", nextOpen)
1104
+ });
1105
+ const isOpen = controllableOpen.value;
1073
1106
  const disabled = computed(() => props.disabled);
1074
1107
  const modal = computed(() => props.modal);
1075
1108
  const trigger = ref(null);
@@ -1094,9 +1127,7 @@ var dropdown_menu_root_default = /* @__PURE__ */ defineVaporComponent({
1094
1127
  });
1095
1128
  function setOpen(value) {
1096
1129
  if (value && disabled.value) return;
1097
- const previous = isOpen.value;
1098
- if (props.open === void 0) uncontrolledOpen.value = value;
1099
- if (previous !== value) emit("update:open", value);
1130
+ if (isOpen.value !== value) controllableOpen.setValue(value);
1100
1131
  }
1101
1132
  function rememberFocus() {
1102
1133
  if (typeof document === "undefined" || returnFocusElement) return;
@@ -1232,16 +1263,18 @@ var dropdown_menu_sub_default = /* @__PURE__ */ defineVaporComponent({
1232
1263
  const props = __props;
1233
1264
  const emit = __emit;
1234
1265
  const parentMenu = useRequiredInject(menuKey, "RpDropdownMenuSub");
1235
- const uncontrolled = ref(props.defaultOpen);
1236
- const isOpen = computed(() => props.open ?? uncontrolled.value);
1266
+ const controllableOpen = useControllableValue({
1267
+ modelValue: () => props.open,
1268
+ defaultValue: () => props.defaultOpen,
1269
+ onChange: (open) => emit("update:open", open)
1270
+ });
1271
+ const isOpen = controllableOpen.value;
1237
1272
  const trigger = ref(null);
1238
1273
  const contentId = ref();
1239
1274
  const actualPlacement = ref("right-start");
1240
1275
  const pendingFocus = ref(false);
1241
1276
  function setOpen(value) {
1242
- const previous = isOpen.value;
1243
- if (props.open === void 0) uncontrolled.value = value;
1244
- if (previous !== value) emit("update:open", value);
1277
+ if (isOpen.value !== value) controllableOpen.setValue(value);
1245
1278
  }
1246
1279
  const context = {
1247
1280
  isOpen,
@@ -1273,7 +1306,7 @@ var dropdown_menu_sub_default = /* @__PURE__ */ defineVaporComponent({
1273
1306
  });
1274
1307
  onBeforeUnmount(() => parentMenu.unregisterSub(context));
1275
1308
  return createSlot("default", {
1276
- isOpen: () => isOpen.value,
1309
+ isOpen: () => unref(isOpen),
1277
1310
  open: () => context.open,
1278
1311
  close: () => context.close
1279
1312
  });
@@ -1347,6 +1380,7 @@ var dropdown_menu_sub_trigger_default = /* @__PURE__ */ defineVaporComponent({
1347
1380
  props: {
1348
1381
  id: {},
1349
1382
  as: { default: "button" },
1383
+ textValue: {},
1350
1384
  disabled: {
1351
1385
  type: Boolean,
1352
1386
  default: false
@@ -1366,6 +1400,7 @@ var dropdown_menu_sub_trigger_default = /* @__PURE__ */ defineVaporComponent({
1366
1400
  return id.value;
1367
1401
  },
1368
1402
  element: () => sub.trigger.value,
1403
+ textValue: () => props.textValue ?? sub.trigger.value?.textContent?.trim() ?? "",
1369
1404
  disabled: () => isDisabled.value,
1370
1405
  activate: () => sub.open("first"),
1371
1406
  submenu: sub
@@ -1495,16 +1530,6 @@ var dropdown_menu_trigger_default = /* @__PURE__ */ defineVaporComponent({
1495
1530
  return n1;
1496
1531
  }
1497
1532
  });
1498
- //#endregion
1499
- //#region ~icons/lucide/chevron-right
1500
- var t0$2 = template("<svg viewBox=\"0 0 24 24\"width=1.2em height=1.2em><path fill=none stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2 d=\"m9 18l6-6l-6-6\">", 3, 1);
1501
- function render(_ctx) {
1502
- return t0$2();
1503
- }
1504
- var chevron_right_default = markRaw(defineVaporComponent({
1505
- name: "lucide-chevron-right",
1506
- render
1507
- }));
1508
1533
  var DEFAULT_FOCUS_TARGET = "first";
1509
1534
  function getOpenFocusTarget(options) {
1510
1535
  if (typeof options === "string") return options;
@@ -1552,19 +1577,6 @@ function hasMeasuredRect(rect) {
1552
1577
  function isPointInRect(point, rect, padding = 0) {
1553
1578
  return point.x >= rect.left - padding && point.x <= rect.right + padding && point.y >= rect.top - padding && point.y <= rect.bottom + padding;
1554
1579
  }
1555
- function getEnabledIndexes(items) {
1556
- return items.map((item, index) => item.disabled ? -1 : index).filter((index) => index >= 0);
1557
- }
1558
- function getNextEnabledIndex(items, index, direction) {
1559
- const enabledIndexes = getEnabledIndexes(items);
1560
- if (enabledIndexes.length === 0) return void 0;
1561
- if (direction === 1) return enabledIndexes.find((candidate) => candidate > index) ?? enabledIndexes[0];
1562
- for (let i = enabledIndexes.length - 1; i >= 0; i -= 1) {
1563
- const candidate = enabledIndexes[i];
1564
- if (candidate < index) return candidate;
1565
- }
1566
- return enabledIndexes[enabledIndexes.length - 1];
1567
- }
1568
1580
  //#endregion
1569
1581
  //#region src/components/dropdown-menu/dropdown-menu-item-row.vue?vue&type=script&setup=true&vapor=true&lang.ts
1570
1582
  var t0$1 = template("<div>");
@@ -1682,12 +1694,10 @@ var dropdown_menu_items_default = /* @__PURE__ */ defineVaporComponent({
1682
1694
  });
1683
1695
  //#endregion
1684
1696
  //#region src/components/dropdown-menu/useDropdownMenuDisclosure.ts
1685
- function useDropdownMenuDisclosure({ props, emit, rootRef, menuRef, targetRef, uncontrolledOpen, isDisabled, isOpen, isVisible, focusedPath, resetFocus, resetSubmenus, resetHoverIntent, focusItem, focusMenu, focusTrigger, layer }) {
1697
+ function useDropdownMenuDisclosure({ props, emit, rootRef, menuRef, targetRef, setControllableOpen, isDisabled, isOpen, isVisible, focusedPath, resetFocus, resetSubmenus, resetHoverIntent, focusItem, focusMenu, focusTrigger, layer }) {
1686
1698
  function setOpen(nextOpen) {
1687
1699
  if (nextOpen && isDisabled.value) return;
1688
- const previousOpen = isOpen.value;
1689
- if (props.open === void 0) uncontrolledOpen.value = nextOpen;
1690
- if (previousOpen !== nextOpen) emit.openChange?.(nextOpen);
1700
+ if (isOpen.value !== nextOpen) setControllableOpen(nextOpen);
1691
1701
  }
1692
1702
  function resetMenuFocus() {
1693
1703
  resetFocus();
@@ -1979,7 +1989,7 @@ function useDropdownMenuHoverIntent({ openSubmenuPath, getItemElement, getSubmen
1979
1989
  }
1980
1990
  //#endregion
1981
1991
  //#region src/components/dropdown-menu/useDropdownMenuInteractions.ts
1982
- function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, openSubmenuPath, getItemAtPath, focusItem, moveFocus, submenus, hoverIntent, disclosure, isSubmenuOpeningLeft }) {
1992
+ function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, openSubmenuPath, getItemAtPath, focusItem, moveFocus, handleTypeahead, submenus, hoverIntent, disclosure, isSubmenuOpeningLeft }) {
1983
1993
  function activateItem(item, path, event) {
1984
1994
  if (item.disabled) return;
1985
1995
  if (hasItemSubmenu(item)) {
@@ -2062,6 +2072,7 @@ function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, ope
2062
2072
  }
2063
2073
  function onMenuKeydown(event) {
2064
2074
  hoverIntent.resetHoverIntent();
2075
+ if (handleTypeahead(event)) return;
2065
2076
  switch (event.key) {
2066
2077
  case "ArrowDown":
2067
2078
  event.preventDefault();
@@ -2150,7 +2161,7 @@ function useDropdownMenuNavigation(items) {
2150
2161
  return getItemsAtPath(getParentPath(path))[path[path.length - 1]];
2151
2162
  }
2152
2163
  function focusItem(target, menuPath = []) {
2153
- const enabledIndexes = getEnabledIndexes(getItemsAtPath(menuPath));
2164
+ const enabledIndexes = getEnabledIndexes(getItemsAtPath(menuPath), (item) => Boolean(item.disabled));
2154
2165
  const index = target === "last" ? enabledIndexes[enabledIndexes.length - 1] : enabledIndexes[0];
2155
2166
  if (index === void 0) {
2156
2167
  if (menuPath.length === 0) focusedPath.value = [];
@@ -2162,13 +2173,19 @@ function useDropdownMenuNavigation(items) {
2162
2173
  function resetFocus() {
2163
2174
  focusedPath.value = [];
2164
2175
  }
2176
+ function setFocusedIndex(index, menuPath = []) {
2177
+ const item = getItemsAtPath(menuPath)[index];
2178
+ if (!item || item.disabled) return false;
2179
+ focusedPath.value = [...menuPath, index];
2180
+ return true;
2181
+ }
2165
2182
  function isItemFocused(indexOrPath) {
2166
2183
  return arePathsEqual(normalizePath(indexOrPath), focusedPath.value);
2167
2184
  }
2168
2185
  function moveFocus(direction) {
2169
2186
  const menuPath = getParentPath(focusedPath.value);
2170
2187
  const itemsAtPath = getItemsAtPath(menuPath);
2171
- const nextIndex = getNextEnabledIndex(itemsAtPath, focusedPath.value.length === 0 ? direction === 1 ? -1 : itemsAtPath.length : focusedPath.value[focusedPath.value.length - 1], direction);
2188
+ const nextIndex = getNextEnabledIndex(itemsAtPath, focusedPath.value.length === 0 ? direction === 1 ? -1 : itemsAtPath.length : focusedPath.value[focusedPath.value.length - 1], direction, (item) => Boolean(item.disabled));
2172
2189
  if (nextIndex === void 0) {
2173
2190
  focusedPath.value = [];
2174
2191
  return;
@@ -2183,6 +2200,7 @@ function useDropdownMenuNavigation(items) {
2183
2200
  getItemAtPath,
2184
2201
  focusItem,
2185
2202
  resetFocus,
2203
+ setFocusedIndex,
2186
2204
  isItemFocused,
2187
2205
  moveFocus
2188
2206
  };
@@ -2360,7 +2378,11 @@ function useDropdownMenu(props, emit = {}) {
2360
2378
  const rootRef = ref(null);
2361
2379
  const menuRef = ref(null);
2362
2380
  const arrowRef = ref(null);
2363
- const uncontrolledOpen = ref(false);
2381
+ const controllableOpen = useControllableValue({
2382
+ modelValue: () => props.open,
2383
+ defaultValue: () => false,
2384
+ onChange: (open) => emit.openChange?.(open)
2385
+ });
2364
2386
  const generatedId = useId();
2365
2387
  const menuId = computed(() => props.id ?? `${generatedId}-menu`);
2366
2388
  const placement = computed(() => props.placement ?? "bottom-start");
@@ -2371,7 +2393,7 @@ function useDropdownMenu(props, emit = {}) {
2371
2393
  const targetElement = computed(() => isElementReference(resolvedTarget.value) ? resolvedTarget.value : null);
2372
2394
  const visibleItems = computed(() => props.items ?? []);
2373
2395
  const isDisabled = computed(() => Boolean(props.disabled));
2374
- const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
2396
+ const isOpen = controllableOpen.value;
2375
2397
  const isVisible = computed(() => isOpen.value && !isDisabled.value);
2376
2398
  const layer = useOverlayLayer({
2377
2399
  active: isVisible,
@@ -2398,13 +2420,26 @@ function useDropdownMenu(props, emit = {}) {
2398
2420
  ]
2399
2421
  });
2400
2422
  const placementSide = computed(() => actualPlacement.value.split("-")[0]);
2401
- const { focusedPath, focusedIndex, getItemAtPath, focusItem, resetFocus, isItemFocused, moveFocus } = useDropdownMenuNavigation(visibleItems);
2423
+ const { focusedPath, focusedIndex, getItemsAtPath, getItemAtPath, focusItem, resetFocus, setFocusedIndex, isItemFocused, moveFocus } = useDropdownMenuNavigation(visibleItems);
2402
2424
  const submenus = useDropdownSubmenus({
2403
2425
  focusedPath,
2404
2426
  getItemAtPath,
2405
2427
  focusItem
2406
2428
  });
2407
2429
  const { openSubmenuPath, isSubmenuOpen } = submenus;
2430
+ const activeMenuPath = computed(() => getParentPath(focusedPath.value));
2431
+ const typeahead = useTypeahead({
2432
+ items: () => getItemsAtPath(activeMenuPath.value),
2433
+ activeIndex: () => focusedPath.value.at(-1) ?? -1,
2434
+ getKey: (item) => item.value,
2435
+ getTextValue: (item) => item.label,
2436
+ isDisabled: (item) => Boolean(item.disabled),
2437
+ scopeKey: () => activeMenuPath.value.join("/"),
2438
+ onMatch(_item, index) {
2439
+ const menuPath = activeMenuPath.value;
2440
+ if (setFocusedIndex(index, menuPath)) submenus.closeSubmenusAfter(menuPath);
2441
+ }
2442
+ });
2408
2443
  const { activeDescendantId, focusMenu, focusTrigger, getItemId, getSubmenuId, getItemElement, getSubmenuElement, isSubmenuOpeningLeft, getMenuActiveDescendant } = useDropdownMenuDom({
2409
2444
  menuId,
2410
2445
  rootRef,
@@ -2424,7 +2459,7 @@ function useDropdownMenu(props, emit = {}) {
2424
2459
  rootRef,
2425
2460
  menuRef,
2426
2461
  targetRef: targetElement,
2427
- uncontrolledOpen,
2462
+ setControllableOpen: controllableOpen.setValue,
2428
2463
  isDisabled,
2429
2464
  isOpen,
2430
2465
  isVisible,
@@ -2447,6 +2482,7 @@ function useDropdownMenu(props, emit = {}) {
2447
2482
  getItemAtPath,
2448
2483
  focusItem,
2449
2484
  moveFocus,
2485
+ handleTypeahead: typeahead.handleKey,
2450
2486
  submenus,
2451
2487
  hoverIntent,
2452
2488
  disclosure,
@@ -2510,6 +2546,9 @@ function useDropdownMenu(props, emit = {}) {
2510
2546
  target.removeEventListener("keydown", onTriggerKeydown);
2511
2547
  });
2512
2548
  }, { flush: "sync" });
2549
+ watch(isVisible, (visible) => {
2550
+ if (!visible) typeahead.reset();
2551
+ }, { flush: "sync" });
2513
2552
  watch([
2514
2553
  isExplicitTarget,
2515
2554
  targetElement,
package/dist/field.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import './field.css';
2
- import { t as bem } from "./bem.js";
3
2
  import { n as useStylesApi, t as presence } from "./styles-api.js";
3
+ import { t as bem } from "./bem.js";
4
4
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
5
5
  import { child, computed, createIf, createInvoker, createSlot, defineVaporComponent, delegateEvents, renderEffect, setDynamicProps, setInsertionState, setText, template, toDisplayString, unref, useId, useSlots } from "vue";
6
6
  //#region src/components/field/useField.ts