ropav 0.3.1 → 0.4.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 (44) hide show
  1. package/dist/components/avatar/avatar-image.js +13 -2
  2. package/dist/components/avatar/avatar.types.d.ts +7 -1
  3. package/dist/components/calendar/calendar-header.js +1 -1
  4. package/dist/components/color-field/index.d.ts +2 -2
  5. package/dist/components/date-picker/index.d.ts +3 -2
  6. package/dist/components/date-picker/index.js +2 -2
  7. package/dist/components/date-range-picker/index.d.ts +3 -2
  8. package/dist/components/date-range-picker/index.js +2 -2
  9. package/dist/components/dropdown/dropdown-menu.js +2 -1
  10. package/dist/components/dropdown/dropdown.types.d.ts +3 -3
  11. package/dist/components/index.d.ts +1 -0
  12. package/dist/components/input/index.d.ts +10 -4
  13. package/dist/components/input/input-root.d.ts +5 -2
  14. package/dist/components/input/input-root.js +43 -5
  15. package/dist/components/input/input.types.d.ts +6 -0
  16. package/dist/components/list-box/list-box-root.js +9 -5
  17. package/dist/components/menu/index.d.ts +2 -0
  18. package/dist/components/menu/menu-root.js +4 -1
  19. package/dist/components/menu/menu.types.d.ts +2 -0
  20. package/dist/components/pagination/index.d.ts +2 -0
  21. package/dist/components/pagination/pagination-root.js +8 -3
  22. package/dist/components/pagination/pagination.types.d.ts +8 -0
  23. package/dist/components/popover/popover-trigger.js +14 -7
  24. package/dist/components/range-calendar/range-calendar-header.js +1 -1
  25. package/dist/components/scroll-shadow/scroll-shadow-root.js +7 -1
  26. package/dist/components/separator/separator-root.js +11 -5
  27. package/dist/components/separator/separator.context.d.ts +7 -0
  28. package/dist/components/tabs/tabs-panel.js +5 -1
  29. package/dist/components/tabs/tabs-tab.js +1 -1
  30. package/dist/components/textarea/index.d.ts +10 -4
  31. package/dist/components/textarea/textarea-root.d.ts +5 -2
  32. package/dist/components/textarea/textarea-root.js +37 -5
  33. package/dist/components/textarea/textarea.types.d.ts +6 -0
  34. package/dist/components/toggle-button-group/toggle-button-group-root.js +3 -3
  35. package/dist/components/toolbar/toolbar-root.js +3 -3
  36. package/dist/components/tooltip/tooltip-trigger.js +13 -5
  37. package/dist/composables/use-menu.d.ts +10 -0
  38. package/dist/composables/use-menu.js +22 -0
  39. package/dist/composables/use-select.js +0 -1
  40. package/dist/composables/use-tab-list-state.d.ts +10 -0
  41. package/dist/composables/use-tab-list-state.js +11 -1
  42. package/dist/index.js +7 -1
  43. package/dist/version.js +1 -1
  44. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import { composeSlotClassName } from "../../utils/compose.js";
2
2
  import { useAvatarContext } from "./avatar.context.js";
3
3
  import { useImageLoadingStatus } from "../../composables/use-image-loading-status.js";
4
- import { createIf, defineVaporComponent, on, renderEffect, setClass, setProp, template, unref, watch } from "vue";
4
+ import { createIf, createTemplateRefSetter, defineVaporComponent, on, renderEffect, setClass, setProp, shallowRef, template, unref, watch } from "vue";
5
5
  //#region src/components/avatar/avatar-image.vue?vue&type=script&setup=true&vapor=true&lang.ts
6
6
  var t0 = template("<img>", 1);
7
7
  var avatar_image_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
@@ -40,13 +40,23 @@ var avatar_image_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__P
40
40
  setImageStatus(value);
41
41
  emit("loadingStatusChange", value);
42
42
  }, { immediate: true });
43
+ /**
44
+ * `alt` is set by hand because an empty one cannot be bound.
45
+ *
46
+ * Vapor routes it through `setDOMProp`, which returns early when the new value equals what the
47
+ * element already reports - and an `img` carrying no `alt` attribute already reports `""`. So the
48
+ * empty default never reaches the DOM, and the attribute stays missing altogether, which is the
49
+ * one state that is always wrong.
50
+ */
51
+ const image = shallowRef(null);
52
+ watch([image, () => props.alt], ([element, alt]) => element?.setAttribute("alt", alt ?? ""), { flush: "post" });
53
+ const _setTemplateRef = createTemplateRefSetter();
43
54
  return createIf(() => unref(status) === "loaded", () => {
44
55
  const n2 = t0();
45
56
  on(n2, "error", ($event) => emit("error", $event));
46
57
  on(n2, "load", ($event) => emit("load", $event));
47
58
  renderEffect(() => {
48
59
  const _props = props;
49
- setProp(n2, "alt", _props.alt);
50
60
  setClass(n2, unref(composeSlotClassName)(unref(slots).image, _props.class));
51
61
  setProp(n2, "crossorigin", _props.crossOrigin);
52
62
  setProp(n2, "loading", _props.loading);
@@ -54,6 +64,7 @@ var avatar_image_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__P
54
64
  setProp(n2, "sizes", _props.sizes);
55
65
  setProp(n2, "src", _props.src);
56
66
  setProp(n2, "srcset", _props.srcSet);
67
+ _setTemplateRef(n2, (element) => image.value = element);
57
68
  });
58
69
  return n2;
59
70
  });
@@ -10,7 +10,13 @@ export interface AvatarRootProps {
10
10
  }
11
11
  export interface AvatarImageProps {
12
12
  class?: string;
13
- /** Alternative text, forwarded to the rendered `img`. */
13
+ /**
14
+ * Alternative text, forwarded to the rendered `img`.
15
+ *
16
+ * Defaults to empty, which marks the image decorative: an avatar sits beside the name it
17
+ * belongs to, and the fallback carries the initials, so a description here usually repeats
18
+ * what is already on the page. Omitting the attribute altogether is never right.
19
+ */
14
20
  alt?: string;
15
21
  /** Forwarded to the probe image so the request matches the rendered one. */
16
22
  crossOrigin?: "" | "anonymous" | "use-credentials";
@@ -1,7 +1,7 @@
1
1
  import { useCalendarContext } from "./calendar.context.js";
2
2
  import { computed, createSlot, defineVaporComponent, renderEffect, setClass, setInsertionState, template } from "vue";
3
3
  //#region src/components/calendar/calendar-header.vue?vue&type=script&setup=true&vapor=true&lang.ts
4
- var t0 = template("<header data-slot=calendar-header>", 1);
4
+ var t0 = template("<div data-slot=calendar-header>", 1);
5
5
  var calendar_header_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
6
6
  __name: "calendar-header",
7
7
  props: { class: {} },
@@ -45,7 +45,7 @@ export declare const ColorField: ((__VLS_props: NonNullable<Awaited<typeof __VLS
45
45
  Group: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>['props'], __VLS_ctx?: {
46
46
  attrs: any;
47
47
  slots: {
48
- default?: (props: import("../color-input-group/index.js").ColorInputGroupRootSlotProps) => unknown;
48
+ default?: (props: import("../index.js").ColorInputGroupRootSlotProps) => unknown;
49
49
  };
50
50
  emit: {};
51
51
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
@@ -61,7 +61,7 @@ export declare const ColorField: ((__VLS_props: NonNullable<Awaited<typeof __VLS
61
61
  expose: (exposed: {}) => void;
62
62
  attrs: any;
63
63
  slots: {
64
- default?: (props: import("../color-input-group/index.js").ColorInputGroupRootSlotProps) => unknown;
64
+ default?: (props: import("../index.js").ColorInputGroupRootSlotProps) => unknown;
65
65
  };
66
66
  emit: {};
67
67
  }>) => import('vue').VNode & {
@@ -190,7 +190,8 @@ export declare const DatePicker: ((__VLS_props: NonNullable<Awaited<typeof __VLS
190
190
  export { DatePickerPopover, DatePickerRoot, DatePickerTrigger, DatePickerTriggerIndicator };
191
191
  export { DateInputGroupInput as DatePickerInput, DateInputGroupInputContainer as DatePickerInputContainer, DateInputGroupPrefix as DatePickerPrefix, DateInputGroupRoot as DatePickerGroup, DateInputGroupSegment as DatePickerSegment, DateInputGroupSuffix as DatePickerSuffix, };
192
192
  export type { DatePickerPopoverProps, DatePickerRootProps, DatePickerRootProps as DatePickerProps, DatePickerRootSlotProps, DatePickerTriggerIndicatorProps, DatePickerTriggerProps, } from "./date-picker.types.js";
193
+ export type { DateInputGroupInputContainerProps as DatePickerInputContainerProps, DateInputGroupInputProps as DatePickerInputProps, DateInputGroupInputSlotProps as DatePickerInputSlotProps, DateInputGroupPrefixProps as DatePickerPrefixProps, DateInputGroupRootProps as DatePickerGroupProps, DateInputGroupRootSlotProps as DatePickerGroupSlotProps, DateInputGroupSegmentProps as DatePickerSegmentProps, DateInputGroupSuffixProps as DatePickerSuffixProps, } from "../date-input-group/index.js";
193
194
  export { provideDatePickerContext, useDatePickerContext } from "./date-picker.context.js";
194
195
  export type { DatePickerContext } from "./date-picker.context.js";
195
- export { datePickerVariants } from "@ropav/styles";
196
- export type { DatePickerVariants } from "@ropav/styles";
196
+ export { dateInputGroupVariants, datePickerVariants } from "@ropav/styles";
197
+ export type { DateInputGroupVariants, DatePickerVariants } from "@ropav/styles";
@@ -9,7 +9,7 @@ import date_picker_popover_default from "./date-picker-popover.js";
9
9
  import date_picker_root_default from "./date-picker-root.js";
10
10
  import date_picker_trigger_indicator_default from "./date-picker-trigger-indicator.js";
11
11
  import date_picker_trigger_default from "./date-picker-trigger.js";
12
- import { datePickerVariants } from "@ropav/styles";
12
+ import { dateInputGroupVariants, datePickerVariants } from "@ropav/styles";
13
13
  //#region src/components/date-picker/index.ts
14
14
  var DatePicker = Object.assign(date_picker_root_default, {
15
15
  Popover: date_picker_popover_default,
@@ -18,4 +18,4 @@ var DatePicker = Object.assign(date_picker_root_default, {
18
18
  TriggerIndicator: date_picker_trigger_indicator_default
19
19
  });
20
20
  //#endregion
21
- export { DatePicker, date_input_group_root_default as DatePickerGroup, date_input_group_input_default as DatePickerInput, date_input_group_input_container_default as DatePickerInputContainer, date_picker_popover_default as DatePickerPopover, date_input_group_prefix_default as DatePickerPrefix, date_picker_root_default as DatePickerRoot, date_input_group_segment_default as DatePickerSegment, date_input_group_suffix_default as DatePickerSuffix, date_picker_trigger_default as DatePickerTrigger, date_picker_trigger_indicator_default as DatePickerTriggerIndicator, datePickerVariants, provideDatePickerContext, useDatePickerContext };
21
+ export { DatePicker, date_input_group_root_default as DatePickerGroup, date_input_group_input_default as DatePickerInput, date_input_group_input_container_default as DatePickerInputContainer, date_picker_popover_default as DatePickerPopover, date_input_group_prefix_default as DatePickerPrefix, date_picker_root_default as DatePickerRoot, date_input_group_segment_default as DatePickerSegment, date_input_group_suffix_default as DatePickerSuffix, date_picker_trigger_default as DatePickerTrigger, date_picker_trigger_indicator_default as DatePickerTriggerIndicator, dateInputGroupVariants, datePickerVariants, provideDatePickerContext, useDatePickerContext };
@@ -214,7 +214,8 @@ export declare const DateRangePicker: ((__VLS_props: NonNullable<Awaited<typeof
214
214
  export { DateRangePickerPopover, DateRangePickerRangeSeparator, DateRangePickerRoot, DateRangePickerTrigger, DateRangePickerTriggerIndicator, };
215
215
  export { DateInputGroupInput as DateRangePickerInput, DateInputGroupInputContainer as DateRangePickerInputContainer, DateInputGroupPrefix as DateRangePickerPrefix, DateInputGroupRoot as DateRangePickerGroup, DateInputGroupSegment as DateRangePickerSegment, DateInputGroupSuffix as DateRangePickerSuffix, };
216
216
  export type { DateRangePickerPopoverProps, DateRangePickerRangeSeparatorProps, DateRangePickerRootProps, DateRangePickerRootProps as DateRangePickerProps, DateRangePickerRootSlotProps, DateRangePickerTriggerIndicatorProps, DateRangePickerTriggerProps, } from "./date-range-picker.types.js";
217
+ export type { DateInputGroupInputContainerProps as DateRangePickerInputContainerProps, DateInputGroupInputProps as DateRangePickerInputProps, DateInputGroupInputSlotProps as DateRangePickerInputSlotProps, DateInputGroupPrefixProps as DateRangePickerPrefixProps, DateInputGroupRootProps as DateRangePickerGroupProps, DateInputGroupRootSlotProps as DateRangePickerGroupSlotProps, DateInputGroupSegmentProps as DateRangePickerSegmentProps, DateInputGroupSuffixProps as DateRangePickerSuffixProps, } from "../date-input-group/index.js";
217
218
  export { provideDateRangePickerContext, useDateRangePickerContext, } from "./date-range-picker.context.js";
218
219
  export type { DateRangePickerContext } from "./date-range-picker.context.js";
219
- export { dateRangePickerVariants } from "@ropav/styles";
220
- export type { DateRangePickerVariants } from "@ropav/styles";
220
+ export { dateInputGroupVariants, dateRangePickerVariants } from "@ropav/styles";
221
+ export type { DateInputGroupVariants, DateRangePickerVariants } from "@ropav/styles";
@@ -10,7 +10,7 @@ import date_range_picker_range_separator_default from "./date-range-picker-range
10
10
  import date_range_picker_root_default from "./date-range-picker-root.js";
11
11
  import date_range_picker_trigger_indicator_default from "./date-range-picker-trigger-indicator.js";
12
12
  import date_range_picker_trigger_default from "./date-range-picker-trigger.js";
13
- import { dateRangePickerVariants } from "@ropav/styles";
13
+ import { dateInputGroupVariants, dateRangePickerVariants } from "@ropav/styles";
14
14
  //#region src/components/date-range-picker/index.ts
15
15
  var DateRangePicker = Object.assign(date_range_picker_root_default, {
16
16
  Popover: date_range_picker_popover_default,
@@ -20,4 +20,4 @@ var DateRangePicker = Object.assign(date_range_picker_root_default, {
20
20
  TriggerIndicator: date_range_picker_trigger_indicator_default
21
21
  });
22
22
  //#endregion
23
- export { DateRangePicker, date_input_group_root_default as DateRangePickerGroup, date_input_group_input_default as DateRangePickerInput, date_input_group_input_container_default as DateRangePickerInputContainer, date_range_picker_popover_default as DateRangePickerPopover, date_input_group_prefix_default as DateRangePickerPrefix, date_range_picker_range_separator_default as DateRangePickerRangeSeparator, date_range_picker_root_default as DateRangePickerRoot, date_input_group_segment_default as DateRangePickerSegment, date_input_group_suffix_default as DateRangePickerSuffix, date_range_picker_trigger_default as DateRangePickerTrigger, date_range_picker_trigger_indicator_default as DateRangePickerTriggerIndicator, dateRangePickerVariants, provideDateRangePickerContext, useDateRangePickerContext };
23
+ export { DateRangePicker, date_input_group_root_default as DateRangePickerGroup, date_input_group_input_default as DateRangePickerInput, date_input_group_input_container_default as DateRangePickerInputContainer, date_range_picker_popover_default as DateRangePickerPopover, date_input_group_prefix_default as DateRangePickerPrefix, date_range_picker_range_separator_default as DateRangePickerRangeSeparator, date_range_picker_root_default as DateRangePickerRoot, date_input_group_segment_default as DateRangePickerSegment, date_input_group_suffix_default as DateRangePickerSuffix, date_range_picker_trigger_default as DateRangePickerTrigger, date_range_picker_trigger_indicator_default as DateRangePickerTriggerIndicator, dateInputGroupVariants, dateRangePickerVariants, provideDateRangePickerContext, useDateRangePickerContext };
@@ -3,7 +3,7 @@ import { useMenu } from "../../composables/use-menu.js";
3
3
  import { useDropdownContext, useDropdownPopoverTarget } from "./dropdown.context.js";
4
4
  import { computed, createIf, createSlot, defineVaporComponent, on, renderEffect, setDynamicProps, setInsertionState, setTemplateRefBinding, template, unref, useSlots } from "vue";
5
5
  //#region src/components/dropdown/dropdown-menu.vue?vue&type=script&setup=true&vapor=true&lang.ts
6
- var t0 = template("<div role=presentation>");
6
+ var t0 = template("<div>");
7
7
  var t1 = template("<div>", 1);
8
8
  var dropdown_menu_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
9
9
  __name: "dropdown-menu",
@@ -69,6 +69,7 @@ var dropdown_menu_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__
69
69
  setInsertionState(n5);
70
70
  createIf(() => hasEmptySlot.value && unref(menu).isEmpty.value, () => {
71
71
  const n3 = t0();
72
+ renderEffect(() => setDynamicProps(n3, [unref(menu).emptyAttributes.value]));
72
73
  setInsertionState(n3);
73
74
  createSlot("empty");
74
75
  return n3;
@@ -36,7 +36,7 @@ export interface DropdownPopoverProps {
36
36
  isKeyboardDismissDisabled?: boolean;
37
37
  }
38
38
  /**
39
- * The menu inside a dropdown. Everything a standalone menu takes, minus the ids and the focus
40
- * strategy, which the trigger decides.
39
+ * The menu inside a dropdown. Everything a standalone menu takes, minus the naming, the ids and the
40
+ * focus strategy, all of which the trigger decides.
41
41
  */
42
- export type DropdownMenuProps = Omit<MenuRootProps, "ariaLabelledby" | "autoFocus" | "id">;
42
+ export type DropdownMenuProps = Omit<MenuRootProps, "ariaLabel" | "ariaLabelledby" | "autoFocus" | "id">;
@@ -16,6 +16,7 @@ export * from "./chip/index.js";
16
16
  export * from "./close-button/index.js";
17
17
  export * from "./color-area/index.js";
18
18
  export * from "./color-field/index.js";
19
+ export * from "./color-input-group/index.js";
19
20
  export * from "./color-picker/index.js";
20
21
  export * from "./color-slider/index.js";
21
22
  export * from "./color-swatch/index.js";
@@ -2,40 +2,46 @@ import InputRoot from "./input-root.js";
2
2
  export declare const Input: ((__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>['props'], __VLS_ctx?: {
3
3
  attrs: any;
4
4
  slots: {};
5
- emit: {};
5
+ emit: ((evt: "change", value: string) => void) & ((evt: "update:value", value: string) => void);
6
6
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
7
7
  props: import('vue').PublicProps & {
8
8
  class?: string;
9
+ value?: string;
9
10
  variant?: import("@ropav/styles").InputVariants["variant"];
10
11
  fullWidth?: boolean;
11
12
  placeholder?: string;
13
+ onChange?: ((value: string) => any) | undefined;
14
+ "onUpdate:value"?: ((value: string) => any) | undefined;
12
15
  } & (typeof globalThis extends {
13
16
  __VLS_PROPS_FALLBACK: infer P;
14
17
  } ? P : {});
15
18
  expose: (exposed: {}) => void;
16
19
  attrs: any;
17
20
  slots: {};
18
- emit: {};
21
+ emit: ((evt: "change", value: string) => void) & ((evt: "update:value", value: string) => void);
19
22
  }>) => import('vue').VNode & {
20
23
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
21
24
  }) & {
22
25
  Root: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>['props'], __VLS_ctx?: {
23
26
  attrs: any;
24
27
  slots: {};
25
- emit: {};
28
+ emit: ((evt: "change", value: string) => void) & ((evt: "update:value", value: string) => void);
26
29
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
27
30
  props: import('vue').PublicProps & {
28
31
  class?: string;
32
+ value?: string;
29
33
  variant?: import("@ropav/styles").InputVariants["variant"];
30
34
  fullWidth?: boolean;
31
35
  placeholder?: string;
36
+ onChange?: ((value: string) => any) | undefined;
37
+ "onUpdate:value"?: ((value: string) => any) | undefined;
32
38
  } & (typeof globalThis extends {
33
39
  __VLS_PROPS_FALLBACK: infer P;
34
40
  } ? P : {});
35
41
  expose: (exposed: {}) => void;
36
42
  attrs: any;
37
43
  slots: {};
38
- emit: {};
44
+ emit: ((evt: "change", value: string) => void) & ((evt: "update:value", value: string) => void);
39
45
  }>) => import('vue').VNode & {
40
46
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
41
47
  };
@@ -1,12 +1,15 @@
1
1
  import type { InputRootProps } from "./input.types.js";
2
2
  declare const __VLS_export: (__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>['props'], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, 'attrs' | 'emit' | 'slots'>>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
3
- props: import('vue').PublicProps & __VLS_PrettifyLocal<InputRootProps> & (typeof globalThis extends {
3
+ props: import('vue').PublicProps & __VLS_PrettifyLocal<InputRootProps & {
4
+ onChange?: ((value: string) => any) | undefined;
5
+ "onUpdate:value"?: ((value: string) => any) | undefined;
6
+ }> & (typeof globalThis extends {
4
7
  __VLS_PROPS_FALLBACK: infer P;
5
8
  } ? P : {});
6
9
  expose: (exposed: {}) => void;
7
10
  attrs: any;
8
11
  slots: {};
9
- emit: {};
12
+ emit: ((evt: "change", value: string) => void) & ((evt: "update:value", value: string) => void);
10
13
  }>) => import('vue').VNode & {
11
14
  __ctx?: NonNullable<Awaited<typeof __VLS_setup>>;
12
15
  };
@@ -1,8 +1,9 @@
1
1
  import { dataAttr } from "../../utils/assertion.js";
2
2
  import { useInteractionStates } from "../../composables/use-interaction-states.js";
3
+ import { setFormValue } from "../../utils/form-value.js";
3
4
  import { useTextFieldControlContext } from "../../composables/use-text-field.js";
4
5
  import { useTextFieldContext } from "../textfield/textfield.context.js";
5
- import { computed, createTemplateRefSetter, defineVaporComponent, on, renderEffect, setDynamicProps, template, unref } from "vue";
6
+ import { computed, createTemplateRefSetter, defineVaporComponent, on, renderEffect, setDynamicProps, shallowRef, template, unref, watch } from "vue";
6
7
  import { inputVariants } from "@ropav/styles";
7
8
  //#region src/components/input/input-root.vue?vue&type=script&setup=true&vapor=true&lang.ts
8
9
  var t0 = template("<input>", 1);
@@ -10,6 +11,7 @@ var input_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
10
11
  __name: "input-root",
11
12
  props: {
12
13
  class: {},
14
+ value: {},
13
15
  variant: { default: void 0 },
14
16
  fullWidth: {
15
17
  type: Boolean,
@@ -17,12 +19,16 @@ var input_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
17
19
  },
18
20
  placeholder: {}
19
21
  },
20
- setup(__props) {
22
+ emits: ["change", "update:value"],
23
+ setup(__props, { emit: __emit }) {
21
24
  const props = __props;
25
+ const emit = __emit;
22
26
  const control = useTextFieldControlContext();
23
27
  const textField = useTextFieldContext();
24
- const setElement = (element) => {
25
- control?.registerElement(element instanceof HTMLInputElement ? element : null);
28
+ const element = shallowRef(null);
29
+ const setElement = (next) => {
30
+ element.value = next instanceof HTMLInputElement ? next : null;
31
+ control?.registerElement(element.value);
26
32
  };
27
33
  const resolvedVariant = computed(() => props.variant ?? textField?.variant.value);
28
34
  const styles = computed(() => inputVariants({
@@ -33,9 +39,41 @@ var input_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
33
39
  const attrs = computed(() => {
34
40
  const merged = { ...control?.attrs.value };
35
41
  if (props.placeholder !== void 0) merged["placeholder"] = props.placeholder;
42
+ if (props.value !== void 0) merged["value"] = props.value;
36
43
  return merged;
37
44
  });
38
45
  const interaction = useInteractionStates({ isDisabled: () => control?.isDisabled.value });
46
+ const inputCount = shallowRef(0);
47
+ const onInput = (event) => {
48
+ control?.handlers.onInput(event);
49
+ const next = event.currentTarget.value;
50
+ emit("change", next);
51
+ emit("update:value", next);
52
+ if (props.value !== void 0) inputCount.value++;
53
+ };
54
+ /**
55
+ * Put the text back to what the caller holds, reset source included. A `value` set on the control
56
+ * makes the caller the owner of it, and a caller that keeps it unchanged means the typing is
57
+ * rejected — but the browser has already moved the text, and Vapor skips writing `value` when the
58
+ * bound value has not changed, so nothing would put it back.
59
+ *
60
+ * Post-flush, because the value only settles once the listener that heard the change has updated
61
+ * whatever holds it. `immediate`, and with the element in the dependencies, because the reset
62
+ * source has to be there before a reset rather than after the first keystroke — `inputCount` alone
63
+ * never fires on a control nobody has typed into. See {@link setFormValue}.
64
+ */
65
+ watch([
66
+ element,
67
+ () => props.value,
68
+ inputCount
69
+ ], ([el, pinned]) => {
70
+ if (pinned === void 0) return;
71
+ setFormValue(el, pinned);
72
+ }, {
73
+ flush: "post",
74
+ immediate: true
75
+ });
76
+ watch(() => props.value !== void 0, (owned) => control?.setValueOwned(owned), { immediate: true });
39
77
  const onFocus = (event) => {
40
78
  interaction.onFocus();
41
79
  control?.handlers.onFocus(event);
@@ -48,7 +86,7 @@ var input_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
48
86
  const n0 = t0();
49
87
  on(n0, "blur", onBlur);
50
88
  on(n0, "focus", onFocus);
51
- on(n0, "input", (e) => unref(control)?.handlers.onInput(e));
89
+ on(n0, "input", onInput);
52
90
  on(n0, "keydown", (e) => unref(control)?.handlers.onKeydown(e));
53
91
  on(n0, "keyup", (e) => unref(control)?.handlers.onKeyup(e));
54
92
  on(n0, "pointerdown", (e) => unref(interaction).onPointerdown(e));
@@ -1,6 +1,12 @@
1
1
  import type { InputVariants } from "@ropav/styles";
2
2
  export interface InputRootProps {
3
3
  class?: string;
4
+ /**
5
+ * Text in the control. Set here it takes the control over from the surrounding field, so the
6
+ * caller owns the value even inside a `TextField` — exactly as a `value` prop does in React.
7
+ * Without a listener to go with it the text is pinned.
8
+ */
9
+ value?: string;
4
10
  /** Visual variant. Taken from the surrounding field when unset. @default "primary" */
5
11
  variant?: InputVariants["variant"];
6
12
  /** Whether the control stretches to fill its container. */
@@ -18,8 +18,9 @@ import { provideSeparatorContext } from "../separator/separator.context.js";
18
18
  import { computed, createComponent, createFor, createIf, createSlot, defineVaporComponent, extend, on, onScopeDispose, renderEffect, setAttr, setClass, setInsertionState, setProp, setStaticTemplateRef, setStyle, shallowRef, template, toValue, unref, useSlots } from "vue";
19
19
  import { listboxVariants } from "@ropav/styles";
20
20
  //#region src/components/list-box/list-box-root.vue?vue&type=script&setup=true&vapor=true&lang.ts
21
- var t0 = template("<div role=presentation>");
22
- var t1 = template("<div aria-orientation=vertical data-layout=stack data-orientation=vertical data-slot=list-box role=listbox>", 1);
21
+ var t0 = template("<div aria-disabled=true role=option>");
22
+ var t1 = template("<div role=presentation>");
23
+ var t2 = template("<div aria-orientation=vertical data-layout=stack data-orientation=vertical data-slot=list-box role=listbox>", 1);
23
24
  /** Stands in while a virtualized listbox has no data yet, so the layout has something to read. */
24
25
  var list_box_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
25
26
  __name: "list-box-root",
@@ -243,7 +244,10 @@ var list_box_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__
243
244
  const rendersDropIndicators = computed(() => isVirtualized.value && dropState != null);
244
245
  /** The gap after the last item, which no item's own "before" indicator covers. */
245
246
  const lastItemKey = computed(() => collection.getLastKey());
246
- provideSeparatorContext({ elementType: "div" });
247
+ provideSeparatorContext({
248
+ elementType: "div",
249
+ role: "presentation"
250
+ });
247
251
  const typeahead = useTypeahead({
248
252
  focusedKey: () => selection.focusedKey.value,
249
253
  getKeyForSearch: keyboard.getKeyForSearch,
@@ -289,7 +293,7 @@ var list_box_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__
289
293
  };
290
294
  const isEmpty = computed(() => collection.size.value === 0);
291
295
  const hasEmptySlot = computed(() => Boolean(callerSlots["empty"]));
292
- const n19 = t1();
296
+ const n19 = t2();
293
297
  renderEffect(() => {
294
298
  const _selection = unref(selection);
295
299
  const _dataAttr = unref(dataAttr);
@@ -313,7 +317,7 @@ var list_box_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__
313
317
  });
314
318
  setInsertionState(n19, 1);
315
319
  createIf(() => isVirtualized.value, () => {
316
- const n16 = t0();
320
+ const n16 = t1();
317
321
  renderEffect(() => setStyle(n16, unref(scroll)?.contentStyle.value));
318
322
  setInsertionState(n16);
319
323
  createFor(() => unref(virtualizer)?.visibleViews.value, (_for_item0) => {
@@ -11,6 +11,7 @@ export declare const Menu: ((__VLS_props: NonNullable<Awaited<typeof __VLS_setup
11
11
  class?: string;
12
12
  id?: string;
13
13
  ariaLabelledby?: string;
14
+ ariaLabel?: string;
14
15
  selectionMode?: import("../../index.js").SelectionMode;
15
16
  selectionBehavior?: import("../../index.js").SelectionBehavior;
16
17
  selectedKeys?: "all" | Iterable<import("../../index.js").CollectionKey>;
@@ -49,6 +50,7 @@ export declare const Menu: ((__VLS_props: NonNullable<Awaited<typeof __VLS_setup
49
50
  class?: string;
50
51
  id?: string;
51
52
  ariaLabelledby?: string;
53
+ ariaLabel?: string;
52
54
  selectionMode?: import("../../index.js").SelectionMode;
53
55
  selectionBehavior?: import("../../index.js").SelectionBehavior;
54
56
  selectedKeys?: "all" | Iterable<import("../../index.js").CollectionKey>;
@@ -3,7 +3,7 @@ import { useMenu } from "../../composables/use-menu.js";
3
3
  import { computed, createIf, createSlot, defineVaporComponent, on, renderEffect, setDynamicProps, setInsertionState, setTemplateRefBinding, template, unref, useSlots } from "vue";
4
4
  import { menuVariants } from "@ropav/styles";
5
5
  //#region src/components/menu/menu-root.vue?vue&type=script&setup=true&vapor=true&lang.ts
6
- var t0 = template("<div role=presentation>");
6
+ var t0 = template("<div>");
7
7
  var t1 = template("<div>", 1);
8
8
  var menu_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
9
9
  __name: "menu-root",
@@ -11,6 +11,7 @@ var menu_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE
11
11
  class: {},
12
12
  id: {},
13
13
  ariaLabelledby: {},
14
+ ariaLabel: {},
14
15
  selectionMode: {},
15
16
  selectionBehavior: {},
16
17
  selectedKeys: {},
@@ -46,6 +47,7 @@ var menu_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE
46
47
  disabledKeys: () => props.disabledKeys,
47
48
  disallowEmptySelection: () => props.disallowEmptySelection,
48
49
  id: () => props.id,
50
+ label: () => props.ariaLabel,
49
51
  labelledBy: () => props.ariaLabelledby,
50
52
  onAction: (key) => emit("action", key),
51
53
  onClose: () => emit("close"),
@@ -70,6 +72,7 @@ var menu_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE
70
72
  setInsertionState(n5);
71
73
  createIf(() => hasEmptySlot.value && unref(menu).isEmpty.value, () => {
72
74
  const n3 = t0();
75
+ renderEffect(() => setDynamicProps(n3, [unref(menu).emptyAttributes.value]));
73
76
  setInsertionState(n3);
74
77
  createSlot("empty");
75
78
  return n3;
@@ -7,6 +7,8 @@ export interface MenuRootProps {
7
7
  id?: string;
8
8
  /** The id of the element naming the menu, normally its trigger. */
9
9
  ariaLabelledby?: string;
10
+ /** Names the menu when it has no trigger to point `ariaLabelledby` at. */
11
+ ariaLabel?: string;
10
12
  /** @default "none" */
11
13
  selectionMode?: SelectionMode;
12
14
  /** @default "toggle" */
@@ -16,6 +16,7 @@ export declare const Pagination: ((__VLS_props: NonNullable<Awaited<typeof __VLS
16
16
  emit: {};
17
17
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
18
18
  props: import('vue').PublicProps & {
19
+ ariaLabel?: string;
19
20
  class?: string;
20
21
  size?: import("@ropav/styles").PaginationVariants["size"];
21
22
  } & (typeof globalThis extends {
@@ -212,6 +213,7 @@ export declare const Pagination: ((__VLS_props: NonNullable<Awaited<typeof __VLS
212
213
  emit: {};
213
214
  }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>['expose'], __VLS_setup?: Promise<{
214
215
  props: import('vue').PublicProps & {
216
+ ariaLabel?: string;
215
217
  class?: string;
216
218
  size?: import("@ropav/styles").PaginationVariants["size"];
217
219
  } & (typeof globalThis extends {
@@ -1,11 +1,12 @@
1
1
  import { providePaginationContext } from "./pagination.context.js";
2
- import { computed, createSlot, defineVaporComponent, renderEffect, setClass, setInsertionState, template } from "vue";
2
+ import { computed, createSlot, defineVaporComponent, renderEffect, setAttr, setClass, setInsertionState, template } from "vue";
3
3
  import { paginationVariants } from "@ropav/styles";
4
4
  //#region src/components/pagination/pagination-root.vue?vue&type=script&setup=true&vapor=true&lang.ts
5
- var t0 = template("<nav aria-label=pagination data-slot=pagination role=navigation>", 1);
5
+ var t0 = template("<nav data-slot=pagination role=navigation>", 1);
6
6
  var pagination_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
7
7
  __name: "pagination-root",
8
8
  props: {
9
+ ariaLabel: {},
9
10
  class: {},
10
11
  size: {}
11
12
  },
@@ -14,7 +15,11 @@ var pagination_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@
14
15
  const slots = computed(() => paginationVariants({ size: props.size }));
15
16
  providePaginationContext({ slots });
16
17
  const n1 = t0();
17
- renderEffect(() => setClass(n1, slots.value.base({ class: props.class })));
18
+ renderEffect(() => {
19
+ const _props = props;
20
+ setAttr(n1, "aria-label", _props.ariaLabel ?? "pagination");
21
+ setClass(n1, slots.value.base({ class: _props.class }));
22
+ });
18
23
  setInsertionState(n1);
19
24
  createSlot();
20
25
  return n1;
@@ -1,5 +1,13 @@
1
1
  import type { PaginationVariants } from "@ropav/styles";
2
2
  export interface PaginationRootProps {
3
+ /**
4
+ * Name for the navigation landmark.
5
+ *
6
+ * Overridable because the name is what tells two paginations apart: a list with one set of
7
+ * controls above it and another below reports the same landmark twice otherwise.
8
+ * @default "pagination"
9
+ */
10
+ ariaLabel?: string;
3
11
  class?: string;
4
12
  /** Pagination size. @default "md" */
5
13
  size?: PaginationVariants["size"];
@@ -1,8 +1,9 @@
1
1
  import { dataAttr } from "../../utils/assertion.js";
2
2
  import { useInteractionStates } from "../../composables/use-interaction-states.js";
3
3
  import { composePressResponder, usePressResponder } from "../../composables/press-responder.js";
4
+ import { FOCUSABLE_SELECTOR } from "../../utils/focus.js";
4
5
  import { usePopoverContext } from "./popover.context.js";
5
- import { computed, createSlot, defineVaporComponent, on, renderEffect, setDynamicProps, setInsertionState, setTemplateRefBinding, template, unref } from "vue";
6
+ import { computed, createSlot, defineVaporComponent, on, renderEffect, setDynamicProps, setInsertionState, setTemplateRefBinding, shallowRef, template, unref, watch } from "vue";
6
7
  //#region src/components/popover/popover-trigger.vue?vue&type=script&setup=true&vapor=true&lang.ts
7
8
  var t0 = template("<div>", 1);
8
9
  var popover_trigger_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
@@ -13,23 +14,29 @@ var popover_trigger_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@
13
14
  const { slots } = usePopoverContext();
14
15
  const responder = usePressResponder();
15
16
  const styles = computed(() => slots.value.trigger({ class: props.class }));
17
+ const host = shallowRef(null);
18
+ const hasFocusableContent = shallowRef(false);
16
19
  const setElement = (element) => {
17
- responder?.registerElement(element ?? null);
20
+ host.value = element ?? null;
21
+ responder?.registerElement(host.value);
18
22
  };
23
+ watch(host, (element) => {
24
+ hasFocusableContent.value = Boolean(element?.querySelector(FOCUSABLE_SELECTOR));
25
+ }, { flush: "post" });
19
26
  const { isFocusVisible, onBlur, onFocus } = useInteractionStates();
20
27
  const press = composePressResponder(responder);
28
+ const wrapperAttrs = computed(() => hasFocusableContent.value ? void 0 : responder?.attrs.value);
21
29
  const n1 = t0();
22
30
  renderEffect(() => {
23
31
  const _dataAttr = unref(dataAttr);
24
- const _responder = unref(responder);
25
32
  setDynamicProps(n1, [{
26
33
  class: styles.value,
27
34
  "data-focus-visible": _dataAttr(unref(isFocusVisible)),
28
- "data-pressed": _dataAttr(_responder?.isPressed.value),
35
+ "data-pressed": _dataAttr(unref(responder)?.isPressed.value),
29
36
  "data-slot": "popover-trigger",
30
- role: "button",
31
- tabindex: "0"
32
- }, _responder?.attrs.value]);
37
+ role: hasFocusableContent.value ? void 0 : "button",
38
+ tabindex: hasFocusableContent.value ? void 0 : 0
39
+ }, wrapperAttrs.value]);
33
40
  });
34
41
  setInsertionState(n1);
35
42
  createSlot();
@@ -1,7 +1,7 @@
1
1
  import { useRangeCalendarContext } from "./range-calendar.context.js";
2
2
  import { computed, createSlot, defineVaporComponent, renderEffect, setClass, setInsertionState, template } from "vue";
3
3
  //#region src/components/range-calendar/range-calendar-header.vue?vue&type=script&setup=true&vapor=true&lang.ts
4
- var t0 = template("<header data-slot=range-calendar-header>", 1);
4
+ var t0 = template("<div data-slot=range-calendar-header>", 1);
5
5
  var range_calendar_header_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PURE__*/ defineVaporComponent({
6
6
  __name: "range-calendar-header",
7
7
  props: { class: {} },
@@ -1,5 +1,6 @@
1
+ import { focusableIn } from "../../utils/focus.js";
1
2
  import { useScrollShadow } from "./use-scroll-shadow.js";
2
- import { computed, createSlot, defineVaporComponent, renderEffect, setAttr, setClass, setInsertionState, setStaticTemplateRef, setStyle, shallowRef, template, watch } from "vue";
3
+ import { computed, createSlot, defineVaporComponent, renderEffect, setAttr, setClass, setInsertionState, setProp, setStaticTemplateRef, setStyle, shallowRef, template, watch } from "vue";
3
4
  import { scrollShadowVariants } from "@ropav/styles";
4
5
  //#region src/components/scroll-shadow/scroll-shadow-root.vue?vue&type=script&setup=true&vapor=true&lang.ts
5
6
  var t0 = template("<div data-slot=scroll-shadow>", 1);
@@ -32,6 +33,10 @@ var scroll_shadow_root_vue_vue_type_script_setup_true_vapor_true_lang_default =
32
33
  setup(__props, { expose: __expose }) {
33
34
  const props = __props;
34
35
  const element = shallowRef(null);
36
+ const needsTabStop = shallowRef(false);
37
+ watch(element, (host) => {
38
+ needsTabStop.value = Boolean(host) && focusableIn(host).length === 0;
39
+ }, { flush: "post" });
35
40
  const styles = computed(() => scrollShadowVariants({
36
41
  hideScrollBar: props.hideScrollBar,
37
42
  orientation: props.orientation,
@@ -78,6 +83,7 @@ var scroll_shadow_root_vue_vue_type_script_setup_true_vapor_true_lang_default =
78
83
  setAttr(n1, "data-orientation", _props.orientation);
79
84
  setAttr(n1, "data-scroll-shadow-size", _props.size);
80
85
  setStyle(n1, style.value);
86
+ setProp(n1, "tabindex", needsTabStop.value ? 0 : void 0);
81
87
  });
82
88
  setInsertionState(n1);
83
89
  createSlot();