ropav 0.12.1 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/components/breadcrumbs/breadcrumbs-item.js +2 -0
  2. package/dist/components/calendar-year-picker/calendar-year-picker-grid.js +1 -0
  3. package/dist/components/date-input-group/date-input-group-hidden-input.js +2 -1
  4. package/dist/components/radio-group/radio-group-root.js +2 -1
  5. package/dist/components/splitter/splitter.state.js +6 -1
  6. package/dist/components/table/table-body.js +1 -1
  7. package/dist/components/table/table-cell.js +3 -1
  8. package/dist/components/table/table-column-resizer.js +2 -1
  9. package/dist/components/table/table-load-more.js +1 -1
  10. package/dist/components/table/use-grid-selection-announcement.js +3 -1
  11. package/dist/components/table/use-table-collection.js +3 -0
  12. package/dist/components/tabs/tabs-list-container.js +2 -1
  13. package/dist/composables/use-calendar-grid.js +2 -1
  14. package/dist/composables/use-collection.js +12 -0
  15. package/dist/composables/use-color-field.js +31 -29
  16. package/dist/composables/use-combo-box-state.js +2 -1
  17. package/dist/composables/use-combo-box.js +2 -1
  18. package/dist/composables/use-disclosure-panel.js +2 -1
  19. package/dist/composables/use-drag.js +9 -6
  20. package/dist/composables/use-drop.js +2 -1
  21. package/dist/composables/use-droppable-collection.js +2 -1
  22. package/dist/composables/use-input-otp.js +5 -2
  23. package/dist/composables/use-move.js +2 -1
  24. package/dist/composables/use-single-select-list-state.js +1 -0
  25. package/dist/composables/use-time-field-state.js +2 -1
  26. package/dist/composables/use-virtualizer.js +1 -0
  27. package/dist/ropav.min.css +1 -1
  28. package/dist/utils/create-context.js +2 -1
  29. package/dist/utils/platform.js +2 -1
  30. package/dist/utils/position.js +4 -2
  31. package/dist/version.js +1 -1
  32. package/package.json +2 -6
  33. package/dist/styles-compat-0.10.css +0 -3
@@ -54,6 +54,8 @@ var breadcrumbs_item_vue_vue_type_script_setup_true_vapor_true_lang_default = /*
54
54
  immediate: true
55
55
  });
56
56
  const isCurrent = computed(() => {
57
+ context.collection.size.value;
58
+ context.orderVersion.value;
57
59
  return context.collection.getLastKey() === itemKey.value;
58
60
  });
59
61
  const isDisabled = computed(() => Boolean(props.isDisabled || context.isDisabled.value || isCurrent.value));
@@ -55,6 +55,7 @@ var calendar_year_picker_grid_vue_vue_type_script_setup_true_vapor_true_lang_def
55
55
  const grid = element.value;
56
56
  const calendar = calendarElement.value;
57
57
  if (!grid || !calendar) return;
58
+ state.focusedDate.value;
58
59
  const dayGrid = calendar.querySelector(`[data-slot='${calendarGridSlot}']`);
59
60
  if (!dayGrid) return;
60
61
  grid.style.top = `${dayGrid.offsetTop}px`;
@@ -60,7 +60,8 @@ var date_input_group_hidden_input_vue_vue_type_script_setup_true_vapor_true_lang
60
60
  const text = event.target.value;
61
61
  if (!text) return;
62
62
  const granularity = state.granularity.value;
63
- const times = TIME_SEGMENTS.slice(0, granularity === "day" ? 0 : GRANULARITY_DEPTH[granularity]);
63
+ const depth = granularity === "day" ? 0 : GRANULARITY_DEPTH[granularity];
64
+ const times = TIME_SEGMENTS.slice(0, depth);
64
65
  try {
65
66
  const parsed = granularity === "day" ? parseDate(text) : parseDateTime(text);
66
67
  for (const segment of DATE_SEGMENTS) if (segment in parsed) state.setSegment(segment, parsed[segment]);
@@ -101,7 +101,8 @@ var radio_group_root_vue_vue_type_script_setup_true_vapor_true_lang_default = /*
101
101
  const onKeydown = (event) => {
102
102
  const isHorizontalFlip = locale.value.direction === "rtl" && resolvedOrientation.value !== "vertical";
103
103
  const isNext = event.key === "ArrowDown" || event.key === (isHorizontalFlip ? "ArrowLeft" : "ArrowRight");
104
- if (!isNext && !(event.key === "ArrowUp" || event.key === (isHorizontalFlip ? "ArrowRight" : "ArrowLeft"))) return;
104
+ const isPrevious = event.key === "ArrowUp" || event.key === (isHorizontalFlip ? "ArrowRight" : "ArrowLeft");
105
+ if (!isNext && !isPrevious) return;
105
106
  if (state.isDisabled.value || state.isReadOnly.value) return;
106
107
  const radios = focusableRadios();
107
108
  if (radios.length === 0) return;
@@ -25,9 +25,11 @@ var registry = () => {
25
25
  const version = shallowRef(0);
26
26
  return {
27
27
  get: (key) => {
28
+ version.value;
28
29
  return items.get(key);
29
30
  },
30
31
  keys: computed(() => {
32
+ version.value;
31
33
  return sortByDocumentOrder([...items.entries()], ([, meta]) => meta.element()).map(([key]) => key);
32
34
  }),
33
35
  register: (key, meta) => {
@@ -83,7 +85,8 @@ var useSplitterState = (options) => {
83
85
  const indexOf = (key) => panels.keys.value.indexOf(key);
84
86
  const getPanelSize = (key) => layout.value[indexOf(key)] ?? 0;
85
87
  const boundsOf = (index) => {
86
- const panel = panels.get(panels.keys.value[index]);
88
+ const key = panels.keys.value[index];
89
+ const panel = panels.get(key);
87
90
  const available = availableSize.value;
88
91
  const min = getMinSize(panel.minSize(), available);
89
92
  const shut = panel.isCollapsible() ? getMinSize(panel.collapsedSize() ?? 0, available) : min;
@@ -206,6 +209,8 @@ var useSplitterState = (options) => {
206
209
  };
207
210
  };
208
211
  const neighbourCache = computed(() => {
212
+ panels.keys.value;
213
+ handles.keys.value;
209
214
  return /* @__PURE__ */ new Map();
210
215
  });
211
216
  const neighboursOf = (handleKey) => {
@@ -107,7 +107,7 @@ var table_body_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
107
107
  return createDynamicComponent(() => unref(virtualizer) ? "div" : "td", {
108
108
  "aria-colspan": () => unref(virtualizer) ? columnCount.value : void 0,
109
109
  colspan: () => unref(virtualizer) ? void 0 : columnCount.value,
110
- role: "rowheader",
110
+ role: "gridcell",
111
111
  style: () => emptyStateStyle.value
112
112
  }, extend(() => {
113
113
  return createSlot("empty", null, null, 4);
@@ -58,7 +58,8 @@ var table_cell_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
58
58
  const virtualizer = useTableVirtualizerContext();
59
59
  const layoutInfo = computed(() => {
60
60
  if (!virtualizer || columnKey.value == null) return null;
61
- return virtualizer.getLayoutInfo(virtualizer.collection.value.cellKey(rowKey.value, columnKey.value));
61
+ const collection = virtualizer.collection.value;
62
+ return virtualizer.getLayoutInfo(collection.cellKey(rowKey.value, columnKey.value));
62
63
  });
63
64
  const parentLayoutInfo = computed(() => virtualizer ? virtualizer.getLayoutInfo(rowKey.value) : null);
64
65
  const placement = virtualizer ? useVirtualizerItem({
@@ -69,6 +70,7 @@ var table_cell_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@__PUR
69
70
  const n1 = createDynamicComponent(() => unref(virtualizer) ? "div" : "td", {
70
71
  id: () => cellId.value,
71
72
  "aria-colindex": () => unref(virtualizer) && index.value >= 0 ? index.value + 1 : void 0,
73
+ "aria-label": () => isRowHeader.value ? props.textValue : void 0,
72
74
  class: () => ["rp-table__cell", props.class],
73
75
  "data-collection": () => unref(collectionId),
74
76
  "data-column-index": () => index.value < 0 ? void 0 : index.value,
@@ -103,7 +103,8 @@ var table_column_resizer_vue_vue_type_script_setup_true_vapor_true_lang_default
103
103
  * arrow press does.
104
104
  */
105
105
  const onChange = (event) => {
106
- resize(parseFloat(event.target.value) > columnWidth.value ? columnWidth.value + KEYBOARD_STEP : columnWidth.value - KEYBOARD_STEP);
106
+ const next = parseFloat(event.target.value);
107
+ resize(next > columnWidth.value ? columnWidth.value + KEYBOARD_STEP : columnWidth.value - KEYBOARD_STEP);
107
108
  };
108
109
  const n1 = t0();
109
110
  const n0 = child(n1);
@@ -100,7 +100,7 @@ var table_load_more_vue_vue_type_script_setup_true_vapor_true_lang_default = /*@
100
100
  return createDynamicComponent(() => unref(virtualizer) ? "div" : "td", {
101
101
  "aria-colspan": () => unref(virtualizer) ? columnCount.value : void 0,
102
102
  colspan: () => unref(virtualizer) ? void 0 : columnCount.value,
103
- role: "rowheader",
103
+ role: "gridcell",
104
104
  style: () => indicatorStyle.value
105
105
  }, extend(() => {
106
106
  return createSlot("default", null, null, 4);
@@ -41,7 +41,9 @@ var useGridSelectionAnnouncement = (options) => {
41
41
  else if (added.size === 1 && removed.size === 0) single([...added][0], "selected");
42
42
  else if (removed.size === 1 && added.size === 0) single([...removed][0], "not selected");
43
43
  if (selection.selectionMode.value === "multiple") {
44
- if (messages.length === 0 || current === "all" || (current === "all" ? 0 : current.size) > 1 || last === "all" || (last === "all" ? 0 : last.size) > 1) messages.push(current === "all" ? "All items selected." : countMessage(selection.selectedKeys.value.size));
44
+ const size = current === "all" ? 0 : current.size;
45
+ const lastSize = last === "all" ? 0 : last.size;
46
+ if (messages.length === 0 || current === "all" || size > 1 || last === "all" || lastSize > 1) messages.push(current === "all" ? "All items selected." : countMessage(selection.selectedKeys.value.size));
45
47
  }
46
48
  if (messages.length > 0) announce(messages.join(" "));
47
49
  });
@@ -19,10 +19,12 @@ var createTableRegistry = () => {
19
19
  const items = /* @__PURE__ */ new Map();
20
20
  const version = shallowRef(0);
21
21
  const orderedKeys = computed(() => {
22
+ version.value;
22
23
  return [...items.entries()].filter(([, meta]) => meta.element()?.isConnected).sort(([, a], [, b]) => a.element().compareDocumentPosition(b.element()) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1).map(([key]) => key);
23
24
  });
24
25
  return {
25
26
  getItem: (key) => {
27
+ version.value;
26
28
  return items.get(key);
27
29
  },
28
30
  indexOf: (key) => orderedKeys.value.indexOf(key),
@@ -39,6 +41,7 @@ var createTableRegistry = () => {
39
41
  };
40
42
  },
41
43
  size: computed(() => {
44
+ version.value;
42
45
  return orderedKeys.value.length;
43
46
  })
44
47
  };
@@ -26,7 +26,8 @@ var tabs_list_container_vue_vue_type_script_setup_true_vapor_true_lang_default =
26
26
  if (!element) return;
27
27
  const vertical = isVertical.value;
28
28
  const size = vertical ? element.clientHeight : element.clientWidth;
29
- const maxScroll = Math.max(0, (vertical ? element.scrollHeight : element.scrollWidth) - size);
29
+ const scrollSize = vertical ? element.scrollHeight : element.scrollWidth;
30
+ const maxScroll = Math.max(0, scrollSize - size);
30
31
  const isRtl = !vertical && getComputedStyle(element).direction === "rtl";
31
32
  const delta = direction * size * SCROLL_FRACTION * (isRtl ? -1 : 1);
32
33
  const current = vertical ? element.scrollTop : element.scrollLeft;
@@ -92,7 +92,8 @@ var useCalendarGrid = (options, state, shared) => {
92
92
  const isDayView = Boolean(duration.days && duration.days < 7);
93
93
  const firstDayOfWeek = toValue(options.firstDayOfWeek);
94
94
  const weekStart = isDayView ? startDate.value : startOfWeek(today(state.timeZone.value), locale.value.locale, firstDayOfWeek);
95
- return Array.from({ length: isDayView ? duration.days : 7 }, (_, index) => dayFormatter.value.format(weekStart.add({ days: index }).toDate(state.timeZone.value)));
95
+ const days = isDayView ? duration.days : 7;
96
+ return Array.from({ length: days }, (_, index) => dayFormatter.value.format(weekStart.add({ days: index }).toDate(state.timeZone.value)));
96
97
  });
97
98
  return {
98
99
  attrs: computed(() => ({
@@ -123,13 +123,24 @@ var useCollection = (options = {}) => {
123
123
  if (index === -1) return null;
124
124
  return keys[index + step] ?? null;
125
125
  };
126
+ /**
127
+ * Read the registration counter, so a lookup made inside a `computed` re-runs once the item
128
+ * it asked about registers. `getItem` and `getElement` are read during render — an item's
129
+ * own disabled state and tabindex come from them — unlike `orderedKeys()`, which is only ever
130
+ * read on an interaction and so deliberately stays outside reactivity.
131
+ */
132
+ const track = () => {
133
+ version.value;
134
+ };
126
135
  return {
127
136
  getElement: (key) => {
137
+ track();
128
138
  return items.get(key)?.element() ?? null;
129
139
  },
130
140
  getFirstKey: () => keyAt(0),
131
141
  getIndex: (key) => order().indexOf(key),
132
142
  getItem: (key) => {
143
+ track();
133
144
  return items.get(key) ?? metaFromSource(key);
134
145
  },
135
146
  getKeyAfter: (key) => neighbour(key, 1),
@@ -138,6 +149,7 @@ var useCollection = (options = {}) => {
138
149
  orderedKeys,
139
150
  register,
140
151
  size: computed(() => {
152
+ track();
141
153
  return source()?.itemCount ?? items.size;
142
154
  }),
143
155
  withOrder
@@ -108,38 +108,40 @@ var useColorField = (options = {}) => {
108
108
  else if (deltaY < 0) state.decrement();
109
109
  }
110
110
  });
111
+ const attrs = computed(() => {
112
+ const all = {
113
+ ...field.attrs.value,
114
+ "aria-disabled": isDisabled.value || void 0,
115
+ "aria-readonly": isReadOnly.value || void 0
116
+ };
117
+ for (const key of Object.keys(all)) if (all[key] === void 0) delete all[key];
118
+ return all;
119
+ });
120
+ const handlers = {
121
+ onBlur: (event) => {
122
+ isFocused.value = false;
123
+ spin.onBlur();
124
+ state.commit();
125
+ reassert();
126
+ field.handlers.onBlur(event);
127
+ },
128
+ onFocus: (event) => {
129
+ isFocused.value = true;
130
+ spin.onFocus();
131
+ field.handlers.onFocus(event);
132
+ },
133
+ onInput: field.handlers.onInput,
134
+ onKeydown: (event) => {
135
+ spin.onKeydown(event);
136
+ field.handlers.onKeydown(event);
137
+ },
138
+ onKeyup: field.handlers.onKeyup
139
+ };
111
140
  return {
112
- attrs: computed(() => {
113
- const all = {
114
- ...field.attrs.value,
115
- "aria-disabled": isDisabled.value || void 0,
116
- "aria-readonly": isReadOnly.value || void 0
117
- };
118
- for (const key of Object.keys(all)) if (all[key] === void 0) delete all[key];
119
- return all;
120
- }),
141
+ attrs,
121
142
  element,
122
143
  fieldIds: field.fieldIds,
123
- handlers: {
124
- onBlur: (event) => {
125
- isFocused.value = false;
126
- spin.onBlur();
127
- state.commit();
128
- reassert();
129
- field.handlers.onBlur(event);
130
- },
131
- onFocus: (event) => {
132
- isFocused.value = true;
133
- spin.onFocus();
134
- field.handlers.onFocus(event);
135
- },
136
- onInput: field.handlers.onInput,
137
- onKeydown: (event) => {
138
- spin.onKeydown(event);
139
- field.handlers.onKeydown(event);
140
- },
141
- onKeyup: field.handlers.onKeyup
142
- },
144
+ handlers,
143
145
  isDisabled,
144
146
  isInvalid: field.isInvalid,
145
147
  isReadOnly,
@@ -128,7 +128,8 @@ var useComboBoxState = (options) => {
128
128
  const given = toValue(options.defaultInputValue);
129
129
  if (given != null) return given;
130
130
  const value = defaultValue.value;
131
- return selectionMode.value === "single" ? textOf(Array.isArray(value) ? value[0] ?? null : value) : "";
131
+ const key = Array.isArray(value) ? value[0] ?? null : value;
132
+ return selectionMode.value === "single" ? textOf(key) : "";
132
133
  });
133
134
  const input = useControllableState({
134
135
  defaultValue: defaultInputValue.value,
@@ -176,7 +176,8 @@ var useComboBox = (options, state) => {
176
176
  },
177
177
  onPressStart: (event) => {
178
178
  if (event.pointerType === "touch") return;
179
- state.toggle(event.pointerType === "keyboard" || event.pointerType === "virtual" ? "first" : null, "manual");
179
+ const strategy = event.pointerType === "keyboard" || event.pointerType === "virtual" ? "first" : null;
180
+ state.toggle(strategy, "manual");
180
181
  focusInput();
181
182
  },
182
183
  preventFocusOnPress: true
@@ -34,7 +34,8 @@ var useDisclosurePanel = (options) => {
34
34
  panel.style.setProperty("--disclosure-panel-height", height);
35
35
  };
36
36
  const applyPanelState = (panel, expanded) => {
37
- if (wasExpanded === null || !(typeof panel.getAnimations === "function")) {
37
+ const canAnimate = typeof panel.getAnimations === "function";
38
+ if (wasExpanded === null || !canAnimate) {
38
39
  if (expanded) {
39
40
  panel.removeAttribute("hidden");
40
41
  setSize(panel, "auto", "auto");
@@ -160,12 +160,15 @@ var useDrag = (options) => {
160
160
  };
161
161
  const onDragend = (event) => {
162
162
  event.stopPropagation();
163
- if (options.onDragEnd) options.onDragEnd({
164
- dropOperation: DROP_EFFECT_TO_DROP_OPERATION[globalDropEffect ?? event.dataTransfer?.dropEffect ?? "none"] ?? "cancel",
165
- type: "dragend",
166
- x: event.clientX,
167
- y: event.clientY
168
- });
163
+ if (options.onDragEnd) {
164
+ const dropEffect = event.dataTransfer?.dropEffect ?? "none";
165
+ options.onDragEnd({
166
+ dropOperation: DROP_EFFECT_TO_DROP_OPERATION[globalDropEffect ?? dropEffect] ?? "cancel",
167
+ type: "dragend",
168
+ x: event.clientX,
169
+ y: event.clientY
170
+ });
171
+ }
169
172
  draggingElement.value = null;
170
173
  releaseDropGuard?.();
171
174
  releaseDropGuard = null;
@@ -14,7 +14,8 @@ var DROP_ACTIVATE_TIMEOUT = 800;
14
14
  * Ported from React Aria's `getAllowedOperations`.
15
15
  */
16
16
  var getAllowedOperations = (event) => {
17
- let allowed = DROP_OPERATION_ALLOWED[event.dataTransfer?.effectAllowed ?? "uninitialized"] ?? DROP_OPERATION.all;
17
+ const effectAllowed = event.dataTransfer?.effectAllowed ?? "uninitialized";
18
+ let allowed = DROP_OPERATION_ALLOWED[effectAllowed] ?? DROP_OPERATION.all;
18
19
  if (globalAllowedDropOperations) allowed &= globalAllowedDropOperations;
19
20
  let allowedModifiers = DROP_OPERATION.none;
20
21
  if (isMac()) {
@@ -100,7 +100,8 @@ var useDroppableCollection = (options, state, element) => {
100
100
  if (inserted.length > 0) {
101
101
  selectionManager.setSelectedKeys(inserted);
102
102
  if (selectionManager.focusedKey.value === focusedKey) {
103
- selectionManager.setFocusedKey(inserted[0]);
103
+ const first = inserted[0];
104
+ selectionManager.setFocusedKey(first);
104
105
  if (selectionManager.selectionMode.value === "none") setInteractionModality("keyboard");
105
106
  }
106
107
  }
@@ -182,7 +182,9 @@ var useInputOTP = (options) => {
182
182
  let end = -1;
183
183
  let direction = void 0;
184
184
  if (_val.length !== 0 && _s !== null && _e !== null) {
185
- if (_s === _e && !(_s === _val.length && _val.length < _ml)) {
185
+ const isSingleCaret = _s === _e;
186
+ const isInsertMode = _s === _val.length && _val.length < _ml;
187
+ if (isSingleCaret && !isInsertMode) {
186
188
  const c = _s;
187
189
  if (c === 0) {
188
190
  start = 0;
@@ -196,7 +198,8 @@ var useInputOTP = (options) => {
196
198
  let offset = 0;
197
199
  if (_prev[0] !== null && _prev[1] !== null) {
198
200
  direction = c < _prev[1] ? "backward" : "forward";
199
- if (direction === "backward" && !(_prev[0] === _prev[1] && _prev[0] < _ml)) offset = -1;
201
+ const wasPreviouslyInserting = _prev[0] === _prev[1] && _prev[0] < _ml;
202
+ if (direction === "backward" && !wasPreviouslyInserting) offset = -1;
200
203
  }
201
204
  start = offset + c;
202
205
  end = offset + c + 1;
@@ -79,7 +79,8 @@ var useMove = (options) => {
79
79
  };
80
80
  const onPointermove = (event) => {
81
81
  if (event.pointerId !== pointerId) return;
82
- move(event, event.pointerType || "mouse", event.pageX - (lastPosition?.pageX ?? 0), event.pageY - (lastPosition?.pageY ?? 0));
82
+ const pointerType = event.pointerType || "mouse";
83
+ move(event, pointerType, event.pageX - (lastPosition?.pageX ?? 0), event.pageY - (lastPosition?.pageY ?? 0));
83
84
  lastPosition = {
84
85
  pageX: event.pageX,
85
86
  pageY: event.pageY
@@ -56,6 +56,7 @@ var useSingleSelectListState = (options = {}) => {
56
56
  * empty collection of the first render and keep that answer.
57
57
  */
58
58
  const selectedKey = computed(() => {
59
+ collection.size.value;
59
60
  const key = stored.state.value;
60
61
  if (stored.isControlled.value) return key ?? null;
61
62
  if (key != null && collection.getItem(key)) return key;
@@ -55,6 +55,7 @@ var useTimeFieldState = (options) => {
55
55
  if (current == null) return null;
56
56
  return "day" in current ? toTime(current) : current;
57
57
  });
58
+ const validateTime = options.validate ? () => options.validate(value.value) : void 0;
58
59
  return {
59
60
  ...useDateFieldState({
60
61
  createCalendar: () => new GregorianCalendar(),
@@ -77,7 +78,7 @@ var useTimeFieldState = (options) => {
77
78
  },
78
79
  placeholderValue: () => placeholderDate.value ?? void 0,
79
80
  shouldForceLeadingZeros: () => toValue(options.shouldForceLeadingZeros),
80
- validate: options.validate ? () => options.validate(value.value) : void 0,
81
+ validate: validateTime,
81
82
  validationBehavior: () => toValue(options.validationBehavior),
82
83
  value: () => toDateTime(value.value)
83
84
  }),
@@ -49,6 +49,7 @@ var useVirtualizer = (options) => {
49
49
  /** Set by `updateItemSize`, consumed by the next pass. */
50
50
  let pendingItemSizeChange = false;
51
51
  const pass = computed(() => {
52
+ revision.value;
52
53
  const collection = options.collection();
53
54
  const layout = options.layout();
54
55
  const layoutOptions = options.layoutOptions?.();