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
package/dist/radio.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import './radio.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
- import { n as getComponentColorValue, r as getComponentContrastColor } from "./componentColors.js";
4
+ import { t as bem } from "./bem.js";
5
5
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
6
- import { i as useFormControl, o as useControllableValue } from "./useFormControl.js";
6
+ import { i as getComponentContrastColor, r as getComponentColorValue } from "./componentColors.js";
7
+ import { i as useFormControl } from "./useFormControl.js";
7
8
  import { t as useControlState } from "./useControlState.js";
8
9
  import { child, computed, createIf, createSlot, defineVaporComponent, inject, next, onBeforeUnmount, onMounted, provide, ref, renderEffect, setDynamicProps, setInsertionState, setStaticTemplateRef, shallowRef, template, unref, useId } from "vue";
9
10
  //#region src/components/radio/types.ts
@@ -17,13 +18,16 @@ var radioGroupParts = ["root"];
17
18
  var radioGroupKey = Symbol("radioGroup");
18
19
  //#endregion
19
20
  //#region src/components/radio/useRadio.ts
20
- function getRadioColorStyle(color, autoContrast) {
21
+ function getRadioColorStyle(color, autoContrast, contrastColor) {
21
22
  const colorValue = getComponentColorValue(color);
22
23
  if (color && !colorValue) return void 0;
23
- if (!colorValue && !autoContrast) return void 0;
24
+ if (!colorValue && autoContrast === false && contrastColor === void 0) return void 0;
24
25
  const style = {};
25
26
  if (colorValue) style["--_rp-radio-color"] = colorValue;
26
- if (autoContrast) style["--_rp-radio-on-color"] = getComponentContrastColor(color ?? "primary", { autoContrast });
27
+ if (autoContrast !== false || contrastColor !== void 0) style["--_rp-radio-on-color"] = getComponentContrastColor(color ?? "primary", {
28
+ autoContrast,
29
+ contrastColor
30
+ });
27
31
  return style;
28
32
  }
29
33
  function useRadio(props, emitChange) {
@@ -39,6 +43,7 @@ function useRadio(props, emitChange) {
39
43
  const variant = computed(() => props.variant ?? group?.variant);
40
44
  const color = computed(() => props.color ?? group?.color);
41
45
  const autoContrast = computed(() => props.autoContrast ?? group?.autoContrast);
46
+ const contrastColor = computed(() => props.contrastColor ?? group?.contrastColor);
42
47
  const size = computed(() => props.size ?? group?.size);
43
48
  const rootClass = computed(() => bem("rp-radio", {
44
49
  checked: isChecked.value,
@@ -47,7 +52,7 @@ function useRadio(props, emitChange) {
47
52
  [variant.value ?? ""]: Boolean(variant.value),
48
53
  [`size-${size.value}`]: Boolean(size.value)
49
54
  }));
50
- const rootStyle = computed(() => getRadioColorStyle(color.value, autoContrast.value));
55
+ const rootStyle = computed(() => getRadioColorStyle(color.value, autoContrast.value, contrastColor.value));
51
56
  function onSelect(event) {
52
57
  if (isDisabled.value) return;
53
58
  group?.select(props.value);
@@ -163,6 +168,9 @@ function useRadioGroup(props, emitUpdate) {
163
168
  get autoContrast() {
164
169
  return props.autoContrast;
165
170
  },
171
+ get contrastColor() {
172
+ return props.contrastColor;
173
+ },
166
174
  get size() {
167
175
  return props.size;
168
176
  },
@@ -205,6 +213,7 @@ var radio_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__
205
213
  type: Boolean,
206
214
  default: void 0
207
215
  },
216
+ contrastColor: {},
208
217
  size: { default: void 0 },
209
218
  disabled: {
210
219
  type: Boolean,
@@ -325,6 +334,7 @@ var radio_group_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__
325
334
  type: Boolean,
326
335
  default: void 0
327
336
  },
337
+ contrastColor: {},
328
338
  size: { default: void 0 },
329
339
  orientation: { default: "vertical" },
330
340
  disabled: {
@@ -60,6 +60,9 @@
60
60
  user-select: none;
61
61
  transition: opacity var(--rp-transition-fast);
62
62
  }
63
+ .rp-scroll-area__scrollbar[data-direction=rtl][data-v-f5c4e940] {
64
+ direction: rtl;
65
+ }
63
66
  .rp-scroll-area__scrollbar[data-visible][data-v-f5c4e940] {
64
67
  opacity: 1;
65
68
  pointer-events: auto;
@@ -102,6 +105,9 @@
102
105
  height: 100%;
103
106
  transform: translateX(var(--_rp-scroll-area-thumb-offset));
104
107
  }
108
+ .rp-scroll-area__scrollbar--horizontal[data-direction=rtl] .rp-scroll-area__thumb[data-v-f5c4e940] {
109
+ transform: translateX(calc(-1 * var(--_rp-scroll-area-thumb-offset)));
110
+ }
105
111
  .rp-scroll-area__scrollbar--vertical .rp-scroll-area__thumb[data-v-f5c4e940] {
106
112
  width: 100%;
107
113
  height: var(--_rp-scroll-area-thumb-size);
@@ -109,7 +115,7 @@
109
115
  }
110
116
  .rp-scroll-area__corner[data-v-f5c4e940] {
111
117
  position: absolute;
112
- right: 0;
118
+ inset-inline-end: 0;
113
119
  bottom: 0;
114
120
  z-index: 1;
115
121
  width: var(--_rp-scroll-area-scrollbar-size);
@@ -118,6 +124,9 @@
118
124
  pointer-events: none;
119
125
  transition: opacity var(--rp-transition-fast);
120
126
  }
127
+ .rp-scroll-area__corner[data-direction=rtl][data-v-f5c4e940] {
128
+ direction: rtl;
129
+ }
121
130
  .rp-scroll-area__corner[data-visible][data-v-f5c4e940] {
122
131
  opacity: 1;
123
132
  }
@@ -7,6 +7,16 @@ var minimumThumbSize = 18;
7
7
  function clamp(value, min, max) {
8
8
  return Math.min(max, Math.max(min, value));
9
9
  }
10
+ function getScrollDirection(viewport) {
11
+ return viewport.ownerDocument.defaultView?.getComputedStyle(viewport).direction === "rtl" ? "rtl" : "ltr";
12
+ }
13
+ function getLogicalHorizontalPosition(scrollLeft, maxPosition, direction) {
14
+ return clamp(direction === "rtl" ? -scrollLeft : scrollLeft, 0, maxPosition);
15
+ }
16
+ function getRawHorizontalPosition(position, maxPosition, direction) {
17
+ const logicalPosition = clamp(position, 0, maxPosition);
18
+ return direction === "rtl" && logicalPosition !== 0 ? -logicalPosition : logicalPosition;
19
+ }
10
20
  function isAxisEnabled(scrollbars, axis) {
11
21
  if (scrollbars === false) return false;
12
22
  if (axis === "x") return scrollbars === "x" || scrollbars === "both";
@@ -43,7 +53,7 @@ function useScrollAreaControls(options) {
43
53
  y: 0
44
54
  };
45
55
  function onViewportScroll(event) {
46
- options.metrics.update();
56
+ options.metrics.updatePosition();
47
57
  options.showDuringScroll();
48
58
  const position = {
49
59
  x: options.metrics.getPosition("x"),
@@ -70,9 +80,7 @@ function useScrollAreaControls(options) {
70
80
  const reachedStart = position.x <= 1 && previousPosition.x > 1;
71
81
  const reachedEnd = position.x >= maxPosition - 1 && previousPosition.x < maxPosition - 1;
72
82
  if (reachedStart || reachedEnd) {
73
- const viewport = options.viewportRef.value;
74
- const view = viewport?.ownerDocument.defaultView;
75
- const rtl = viewport ? view?.getComputedStyle(viewport).direction === "rtl" : false;
83
+ const rtl = options.metrics.metrics.direction === "rtl";
76
84
  if (reachedStart) boundaries.push(rtl ? "right" : "left");
77
85
  if (reachedEnd) boundaries.push(rtl ? "left" : "right");
78
86
  }
@@ -98,24 +106,26 @@ function useScrollAreaControls(options) {
98
106
  function writeAxisPosition(axis, value) {
99
107
  const viewport = options.viewportRef.value;
100
108
  if (!viewport) return;
101
- if (axis === "x") viewport.scrollLeft = (viewport.scrollLeft < 0 ? -1 : 1) * clamp(value, 0, options.metrics.getMaxPosition("x"));
109
+ if (axis === "x") viewport.scrollLeft = getRawHorizontalPosition(value, options.metrics.getMaxPosition("x"), options.metrics.metrics.direction);
102
110
  else viewport.scrollTop = clamp(value, 0, options.metrics.getMaxPosition("y"));
103
- options.metrics.update();
111
+ options.metrics.updatePosition();
104
112
  options.showDuringScroll();
105
113
  }
106
114
  function onScrollbarKeydown(axis, event) {
107
115
  const viewport = options.viewportRef.value;
108
116
  if (!viewport || !options.metrics.getOverflow(axis)) return;
117
+ options.metrics.updatePosition(viewport);
109
118
  const current = options.metrics.getPosition(axis);
110
119
  const pageSize = axis === "x" ? viewport.clientWidth : viewport.clientHeight;
111
- const nextPosition = getKeyboardPosition(event.key, current, pageSize, options.metrics.getMaxPosition(axis));
120
+ const nextPosition = getKeyboardPosition(axis, event.key, current, pageSize, options.metrics.getMaxPosition(axis), options.metrics.metrics.direction);
112
121
  if (nextPosition === void 0) return;
113
122
  event.preventDefault();
114
123
  writeAxisPosition(axis, nextPosition);
115
124
  }
116
125
  function onScrollbarWheel(axis, event) {
117
126
  if (!options.metrics.getOverflow(axis)) return;
118
- const delta = axis === "x" ? event.deltaX || event.deltaY : event.deltaY;
127
+ options.metrics.updatePosition();
128
+ const delta = getWheelDelta(axis, event, options.metrics.metrics.direction);
119
129
  if (!delta) return;
120
130
  event.preventDefault();
121
131
  writeAxisPosition(axis, options.metrics.getPosition(axis) + delta);
@@ -125,14 +135,14 @@ function useScrollAreaControls(options) {
125
135
  if (!viewport) return;
126
136
  if (typeof viewport.scrollTo === "function") viewport.scrollTo(scrollOptions);
127
137
  else setFallbackPosition(viewport, scrollOptions, false);
128
- options.metrics.scheduleUpdate();
138
+ options.metrics.schedulePositionUpdate();
129
139
  }
130
140
  function scrollBy(scrollOptions) {
131
141
  const viewport = options.viewportRef.value;
132
142
  if (!viewport) return;
133
143
  if (typeof viewport.scrollBy === "function") viewport.scrollBy(scrollOptions);
134
144
  else setFallbackPosition(viewport, scrollOptions, true);
135
- options.metrics.scheduleUpdate();
145
+ options.metrics.schedulePositionUpdate();
136
146
  }
137
147
  return {
138
148
  onViewportScroll,
@@ -143,11 +153,11 @@ function useScrollAreaControls(options) {
143
153
  scrollBy
144
154
  };
145
155
  }
146
- function getKeyboardPosition(key, current, pageSize, max) {
156
+ function getKeyboardPosition(axis, key, current, pageSize, max, direction) {
147
157
  switch (key) {
148
- case "ArrowLeft":
158
+ case "ArrowLeft": return current + (axis === "x" && direction === "rtl" ? 40 : -40);
149
159
  case "ArrowUp": return current - 40;
150
- case "ArrowRight":
160
+ case "ArrowRight": return current + (axis === "x" && direction === "rtl" ? -40 : 40);
151
161
  case "ArrowDown": return current + 40;
152
162
  case "PageUp": return current - pageSize;
153
163
  case "PageDown": return current + pageSize;
@@ -156,6 +166,11 @@ function getKeyboardPosition(key, current, pageSize, max) {
156
166
  default: return;
157
167
  }
158
168
  }
169
+ function getWheelDelta(axis, event, direction) {
170
+ if (axis === "y") return event.deltaY;
171
+ if (!event.deltaX) return event.deltaY;
172
+ return direction === "rtl" ? -event.deltaX : event.deltaX;
173
+ }
159
174
  function setFallbackPosition(viewport, scrollOptions, relative) {
160
175
  if (scrollOptions.left !== void 0) viewport.scrollLeft = (relative ? viewport.scrollLeft : 0) + scrollOptions.left;
161
176
  if (scrollOptions.top !== void 0) viewport.scrollTop = (relative ? viewport.scrollTop : 0) + scrollOptions.top;
@@ -197,6 +212,7 @@ function createRafScheduler(callback, getView) {
197
212
  //#region src/components/scroll-area/useScrollAreaMetrics.ts
198
213
  function useScrollAreaMetrics(options) {
199
214
  const metrics = reactive({
215
+ direction: "ltr",
200
216
  clientWidth: 0,
201
217
  clientHeight: 0,
202
218
  scrollWidth: 0,
@@ -216,33 +232,44 @@ function useScrollAreaMetrics(options) {
216
232
  }));
217
233
  let resizeObserver;
218
234
  let mutationObserver;
235
+ let directionObserver;
236
+ let horizontalThumbSizeRatio = 1;
237
+ let verticalThumbSizeRatio = 1;
219
238
  const scheduler = createRafScheduler(update, () => options.viewportRef.value?.ownerDocument.defaultView);
239
+ const positionScheduler = createRafScheduler(updatePosition, () => options.viewportRef.value?.ownerDocument.defaultView);
220
240
  function update() {
221
241
  const viewport = options.viewportRef.value;
222
242
  if (!viewport) return;
223
- readViewportMetrics(viewport);
224
- updateThumbMetrics(viewport);
243
+ readViewportGeometry(viewport);
244
+ updateThumbGeometry(viewport);
245
+ updatePosition(viewport);
225
246
  }
226
- function readViewportMetrics(viewport) {
247
+ function readViewportGeometry(viewport) {
227
248
  metrics.clientWidth = viewport.clientWidth;
228
249
  metrics.clientHeight = viewport.clientHeight;
229
250
  metrics.scrollWidth = viewport.scrollWidth;
230
251
  metrics.scrollHeight = viewport.scrollHeight;
231
- metrics.x = viewport.scrollLeft;
232
- metrics.y = viewport.scrollTop;
233
252
  metrics.overflowX = options.horizontalEnabled.value && viewport.scrollWidth > viewport.clientWidth + 1;
234
253
  metrics.overflowY = options.verticalEnabled.value && viewport.scrollHeight > viewport.clientHeight + 1;
235
254
  }
236
- function updateThumbMetrics(viewport) {
255
+ function updateThumbGeometry(viewport) {
237
256
  const horizontalGeometry = getThumbGeometry(options.horizontalScrollbarRef.value?.clientWidth ?? viewport.clientWidth, viewport.clientWidth, viewport.scrollWidth);
238
257
  const verticalGeometry = getThumbGeometry(options.verticalScrollbarRef.value?.clientHeight ?? viewport.clientHeight, viewport.clientHeight, viewport.scrollHeight);
239
258
  metrics.horizontalThumbSize = horizontalGeometry.size;
240
- metrics.horizontalThumbOffset = getThumbOffset(clamp(Math.abs(viewport.scrollLeft), 0, getMaxPosition("x")), getMaxPosition("x"), horizontalGeometry.offsetRatio);
259
+ horizontalThumbSizeRatio = horizontalGeometry.offsetRatio;
241
260
  metrics.verticalThumbSize = verticalGeometry.size;
242
- metrics.verticalThumbOffset = getThumbOffset(clamp(viewport.scrollTop, 0, getMaxPosition("y")), getMaxPosition("y"), verticalGeometry.offsetRatio);
261
+ verticalThumbSizeRatio = verticalGeometry.offsetRatio;
262
+ }
263
+ function updatePosition(viewport = options.viewportRef.value) {
264
+ if (!viewport) return;
265
+ metrics.direction = getScrollDirection(viewport);
266
+ metrics.x = getLogicalHorizontalPosition(viewport.scrollLeft, getMaxPosition("x"), metrics.direction);
267
+ metrics.y = clamp(viewport.scrollTop, 0, getMaxPosition("y"));
268
+ metrics.horizontalThumbOffset = getThumbOffset(metrics.x, getMaxPosition("x"), horizontalThumbSizeRatio);
269
+ metrics.verticalThumbOffset = getThumbOffset(metrics.y, getMaxPosition("y"), verticalThumbSizeRatio);
243
270
  }
244
271
  function getPosition(axis) {
245
- return axis === "x" ? Math.abs(metrics.x) : metrics.y;
272
+ return axis === "x" ? metrics.x : metrics.y;
246
273
  }
247
274
  function getMaxPosition(axis) {
248
275
  return axis === "x" ? Math.max(0, metrics.scrollWidth - metrics.clientWidth) : Math.max(0, metrics.scrollHeight - metrics.clientHeight);
@@ -260,8 +287,26 @@ function useScrollAreaMetrics(options) {
260
287
  resizeObserver.observe(viewport);
261
288
  if (options.contentRef.value) resizeObserver.observe(options.contentRef.value);
262
289
  } else attachMutationObserver(view);
290
+ attachDirectionObserver(view, viewport);
263
291
  view?.addEventListener("resize", scheduler.schedule);
264
292
  }
293
+ function attachDirectionObserver(view, viewport) {
294
+ const MutationObserverConstructor = view?.MutationObserver ?? globalThis.MutationObserver;
295
+ if (!MutationObserverConstructor) return;
296
+ directionObserver = new MutationObserverConstructor(positionScheduler.schedule);
297
+ let element = viewport;
298
+ while (element) {
299
+ directionObserver.observe(element, {
300
+ attributes: true,
301
+ attributeFilter: [
302
+ "class",
303
+ "dir",
304
+ "style"
305
+ ]
306
+ });
307
+ element = element.parentElement;
308
+ }
309
+ }
265
310
  function attachMutationObserver(view) {
266
311
  const MutationObserverConstructor = view?.MutationObserver ?? globalThis.MutationObserver;
267
312
  const content = options.contentRef.value;
@@ -279,8 +324,10 @@ function useScrollAreaMetrics(options) {
279
324
  const view = options.viewportRef.value?.ownerDocument.defaultView;
280
325
  resizeObserver?.disconnect();
281
326
  mutationObserver?.disconnect();
327
+ directionObserver?.disconnect();
282
328
  resizeObserver = void 0;
283
329
  mutationObserver = void 0;
330
+ directionObserver = void 0;
284
331
  view?.removeEventListener("resize", scheduler.schedule);
285
332
  }
286
333
  onMounted(() => {
@@ -290,12 +337,15 @@ function useScrollAreaMetrics(options) {
290
337
  onBeforeUnmount(() => {
291
338
  detachObservers();
292
339
  scheduler.cancel();
340
+ positionScheduler.cancel();
293
341
  });
294
342
  return {
295
343
  metrics,
296
344
  position,
297
345
  update,
346
+ updatePosition,
298
347
  scheduleUpdate: scheduler.schedule,
348
+ schedulePositionUpdate: positionScheduler.schedule,
299
349
  getPosition,
300
350
  getMaxPosition,
301
351
  getOverflow
@@ -308,6 +358,7 @@ function useScrollAreaPointer(options) {
308
358
  function onScrollbarPointerdown(axis, event) {
309
359
  if (event.target !== event.currentTarget || event.button !== 0) return;
310
360
  if (!options.metrics.getOverflow(axis)) return;
361
+ options.metrics.updatePosition();
311
362
  const scrollbar = event.currentTarget;
312
363
  const thumb = scrollbar.firstElementChild;
313
364
  const trackRect = scrollbar.getBoundingClientRect();
@@ -319,12 +370,14 @@ function useScrollAreaPointer(options) {
319
370
  const travel = Math.max(0, trackSize - thumbSize);
320
371
  if (travel === 0) return;
321
372
  event.preventDefault();
322
- const ratio = clamp((coordinate - trackStart - thumbSize / 2) / travel, 0, 1);
323
- options.controls.writeAxisPosition(axis, ratio * options.metrics.getMaxPosition(axis));
373
+ const physicalRatio = clamp((coordinate - trackStart - thumbSize / 2) / travel, 0, 1);
374
+ const logicalRatio = axis === "x" && options.metrics.metrics.direction === "rtl" ? 1 - physicalRatio : physicalRatio;
375
+ options.controls.writeAxisPosition(axis, logicalRatio * options.metrics.getMaxPosition(axis));
324
376
  }
325
377
  function onThumbPointerdown(axis, event) {
326
378
  if (event.button !== 0 || event.isPrimary === false) return;
327
379
  if (!options.metrics.getOverflow(axis)) return;
380
+ options.metrics.updatePosition();
328
381
  const scrollbar = getScrollbar(axis);
329
382
  const thumb = event.currentTarget;
330
383
  if (!scrollbar) return;
@@ -349,6 +402,7 @@ function useScrollAreaPointer(options) {
349
402
  startPosition: options.metrics.getPosition(axis),
350
403
  maxPosition: options.metrics.getMaxPosition(axis),
351
404
  travel,
405
+ coordinateDirection: axis === "x" && options.metrics.metrics.direction === "rtl" ? -1 : 1,
352
406
  view
353
407
  };
354
408
  options.setDraggingAxis(axis);
@@ -360,7 +414,7 @@ function useScrollAreaPointer(options) {
360
414
  const session = dragSession;
361
415
  if (!session || !isCurrentPointer(event, session)) return;
362
416
  const delta = getPointerCoordinate(session.axis, event) - session.startCoordinate;
363
- options.controls.writeAxisPosition(session.axis, session.startPosition + delta / session.travel * session.maxPosition);
417
+ options.controls.writeAxisPosition(session.axis, session.startPosition + session.coordinateDirection * delta * session.maxPosition / session.travel);
364
418
  }
365
419
  function onPointerend(event) {
366
420
  if (!dragSession || !isCurrentPointer(event, dragSession)) return;
@@ -542,6 +596,7 @@ function useScrollAreaPresentation(props, scrollArea) {
542
596
  class: "rp-scroll-area",
543
597
  style: getRootStyle(props.scrollbarSize),
544
598
  "data-type": props.type,
599
+ "data-direction": scrollArea.metrics.direction,
545
600
  "data-scrollbars": props.scrollbars === false ? "none" : props.scrollbars,
546
601
  "data-overflow-x": presence(scrollArea.metrics.overflowX),
547
602
  "data-overflow-y": presence(scrollArea.metrics.overflowY),
@@ -593,6 +648,7 @@ function useScrollAreaPresentation(props, scrollArea) {
593
648
  const cornerAttrs = computed(() => ({
594
649
  ...getPartAttrs("corner", { class: "rp-scroll-area__corner" }),
595
650
  "aria-hidden": true,
651
+ "data-direction": scrollArea.metrics.direction,
596
652
  "data-visible": presence(scrollArea.horizontalScrollbarActive.value && scrollArea.verticalScrollbarActive.value)
597
653
  }));
598
654
  const slotProps = computed(() => ({
@@ -619,6 +675,7 @@ function useScrollAreaPresentation(props, scrollArea) {
619
675
  "aria-disabled": !scrollArea.getOverflow(axis) || void 0,
620
676
  "aria-hidden": props.embedded || !active || void 0,
621
677
  "data-orientation": vertical ? "vertical" : "horizontal",
678
+ "data-direction": scrollArea.metrics.direction,
622
679
  "data-active": presence(active),
623
680
  "data-visible": presence(visible)
624
681
  };
package/dist/select.css CHANGED
@@ -1,5 +1,5 @@
1
1
  @layer ropav.components {
2
- .rp-select[data-v-d7a0b110] {
2
+ .rp-select[data-v-7eb8ed79] {
3
3
  --_rp-select-height: var(--rp-size-control-md);
4
4
  --_rp-select-padding-x: calc(var(--rp-size-control-md) / 3);
5
5
  --_rp-select-font-size: var(--rp-font-size-md);
@@ -15,7 +15,7 @@
15
15
  font-weight: var(--rp-font-weight-normal);
16
16
  line-height: 1;
17
17
  }
18
- .rp-select__native[data-v-d7a0b110] {
18
+ .rp-select__native[data-v-7eb8ed79] {
19
19
  position: absolute;
20
20
  width: 1px;
21
21
  height: 1px;
@@ -26,42 +26,42 @@
26
26
  white-space: nowrap;
27
27
  border-width: 0;
28
28
  }
29
- .rp-select--size-xs[data-v-d7a0b110] {
29
+ .rp-select--size-xs[data-v-7eb8ed79] {
30
30
  --_rp-select-height: var(--rp-size-control-xs);
31
31
  --_rp-select-padding-x: calc(var(--rp-size-control-xs) / 3);
32
32
  --_rp-select-font-size: var(--rp-font-size-xs);
33
33
  --_rp-select-option-min-height: calc(var(--rp-size-control-xs) - var(--rp-spacing-2));
34
34
  --_rp-select-option-padding-y: calc(var(--rp-spacing-1) / 2);
35
35
  }
36
- .rp-select--size-sm[data-v-d7a0b110] {
36
+ .rp-select--size-sm[data-v-7eb8ed79] {
37
37
  --_rp-select-height: var(--rp-size-control-sm);
38
38
  --_rp-select-padding-x: calc(var(--rp-size-control-sm) / 3);
39
39
  --_rp-select-font-size: var(--rp-font-size-sm);
40
40
  --_rp-select-option-min-height: calc(var(--rp-size-control-sm) - var(--rp-spacing-3));
41
41
  --_rp-select-option-padding-y: var(--rp-spacing-1);
42
42
  }
43
- .rp-select--size-md[data-v-d7a0b110] {
43
+ .rp-select--size-md[data-v-7eb8ed79] {
44
44
  --_rp-select-height: var(--rp-size-control-md);
45
45
  --_rp-select-padding-x: calc(var(--rp-size-control-md) / 3);
46
46
  --_rp-select-font-size: var(--rp-font-size-md);
47
47
  --_rp-select-option-min-height: calc(var(--rp-size-control-md) - var(--rp-spacing-4));
48
48
  --_rp-select-option-padding-y: var(--rp-spacing-1);
49
49
  }
50
- .rp-select--size-lg[data-v-d7a0b110] {
50
+ .rp-select--size-lg[data-v-7eb8ed79] {
51
51
  --_rp-select-height: var(--rp-size-control-lg);
52
52
  --_rp-select-padding-x: calc(var(--rp-size-control-lg) / 3);
53
53
  --_rp-select-font-size: var(--rp-font-size-lg);
54
54
  --_rp-select-option-min-height: calc(var(--rp-size-control-lg) - var(--rp-spacing-5));
55
55
  --_rp-select-option-padding-y: calc(var(--rp-spacing-3) / 2);
56
56
  }
57
- .rp-select--size-xl[data-v-d7a0b110] {
57
+ .rp-select--size-xl[data-v-7eb8ed79] {
58
58
  --_rp-select-height: var(--rp-size-control-xl);
59
59
  --_rp-select-padding-x: calc(var(--rp-size-control-xl) / 3);
60
60
  --_rp-select-font-size: var(--rp-font-size-xl);
61
61
  --_rp-select-option-min-height: calc(var(--rp-size-control-xl) - var(--rp-spacing-6));
62
62
  --_rp-select-option-padding-y: var(--rp-spacing-2);
63
63
  }
64
- html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[data-v-d7a0b110] {
64
+ html.dark .rp-select[data-v-7eb8ed79], [data-rp-color-scheme=dark] .rp-select[data-v-7eb8ed79] {
65
65
  --_rp-select-invalid-border: var(--rp-color-red-light-color);
66
66
  --_rp-select-invalid-ring: color-mix(
67
67
  in srgb,
@@ -70,11 +70,11 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
70
70
  );
71
71
  --_rp-select-option-focused-bg: var(--rp-color-default-hover);
72
72
  }
73
- .rp-select--disabled[data-v-d7a0b110] {
73
+ .rp-select--disabled[data-v-7eb8ed79] {
74
74
  opacity: var(--rp-opacity-disabled);
75
75
  cursor: not-allowed;
76
76
  }
77
- .rp-select__trigger[data-v-d7a0b110] {
77
+ .rp-select__trigger[data-v-7eb8ed79] {
78
78
  display: inline-flex;
79
79
  align-items: center;
80
80
  justify-content: center;
@@ -91,81 +91,81 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
91
91
  transition: border-color var(--rp-transition-fast), box-shadow var(--rp-transition-fast);
92
92
  gap: var(--rp-spacing-2);
93
93
  }
94
- .rp-select__trigger[data-v-d7a0b110]:hover {
94
+ .rp-select__trigger[data-v-7eb8ed79]:hover {
95
95
  border-color: var(--rp-color-control-border-hover);
96
96
  }
97
- .rp-select__trigger[data-v-d7a0b110]:focus-visible {
97
+ .rp-select__trigger[data-v-7eb8ed79]:focus-visible {
98
98
  outline: none;
99
99
  border-color: var(--rp-color-control-border-focus);
100
100
  box-shadow: 0 0 0 var(--rp-border-width-medium) var(--rp-color-focus-ring);
101
101
  }
102
- .rp-select--radius-xs[data-v-d7a0b110] {
102
+ .rp-select--radius-xs[data-v-7eb8ed79] {
103
103
  --_rp-select-radius: var(--rp-radius-xs);
104
104
  }
105
- .rp-select--radius-sm[data-v-d7a0b110] {
105
+ .rp-select--radius-sm[data-v-7eb8ed79] {
106
106
  --_rp-select-radius: var(--rp-radius-sm);
107
107
  }
108
- .rp-select--radius-md[data-v-d7a0b110] {
108
+ .rp-select--radius-md[data-v-7eb8ed79] {
109
109
  --_rp-select-radius: var(--rp-radius-md);
110
110
  }
111
- .rp-select--radius-lg[data-v-d7a0b110] {
111
+ .rp-select--radius-lg[data-v-7eb8ed79] {
112
112
  --_rp-select-radius: var(--rp-radius-lg);
113
113
  }
114
- .rp-select--radius-xl[data-v-d7a0b110] {
114
+ .rp-select--radius-xl[data-v-7eb8ed79] {
115
115
  --_rp-select-radius: var(--rp-radius-xl);
116
116
  }
117
- .rp-select--open .rp-select__trigger[data-v-d7a0b110] {
117
+ .rp-select--open .rp-select__trigger[data-v-7eb8ed79] {
118
118
  border-color: var(--rp-color-control-border-focus);
119
119
  box-shadow: 0 0 0 var(--rp-border-width-medium) var(--rp-color-focus-ring);
120
120
  }
121
- .rp-select--invalid .rp-select__trigger[data-v-d7a0b110] {
121
+ .rp-select--invalid .rp-select__trigger[data-v-7eb8ed79] {
122
122
  border-color: var(--_rp-select-invalid-border);
123
123
  }
124
- .rp-select--invalid .rp-select__trigger[data-v-d7a0b110]:focus-visible, .rp-select--open.rp-select--invalid .rp-select__trigger[data-v-d7a0b110] {
124
+ .rp-select--invalid .rp-select__trigger[data-v-7eb8ed79]:focus-visible, .rp-select--open.rp-select--invalid .rp-select__trigger[data-v-7eb8ed79] {
125
125
  border-color: var(--_rp-select-invalid-border);
126
126
  box-shadow: 0 0 0 var(--rp-border-width-medium) var(--_rp-select-invalid-ring);
127
127
  }
128
- .rp-select__value[data-v-d7a0b110] {
128
+ .rp-select__value[data-v-7eb8ed79] {
129
129
  flex: 1;
130
130
  overflow: hidden;
131
131
  text-overflow: ellipsis;
132
132
  white-space: nowrap;
133
133
  color: var(--rp-color-control-fg);
134
134
  }
135
- .rp-select__placeholder[data-v-d7a0b110] {
135
+ .rp-select__placeholder[data-v-7eb8ed79] {
136
136
  color: var(--rp-color-control-placeholder);
137
137
  }
138
- .rp-select__indicator[data-v-d7a0b110] {
138
+ .rp-select__indicator[data-v-7eb8ed79] {
139
139
  display: inline-flex;
140
140
  align-items: center;
141
141
  width: 1em;
142
142
  height: 1em;
143
143
  flex-shrink: 0;
144
144
  }
145
- .rp-select__indicator svg[data-v-d7a0b110] {
145
+ .rp-select__indicator svg[data-v-7eb8ed79] {
146
146
  width: 100%;
147
147
  height: 100%;
148
148
  }
149
- .rp-select__indicator[data-v-d7a0b110] {
149
+ .rp-select__indicator[data-v-7eb8ed79] {
150
150
  position: relative;
151
151
  color: var(--rp-color-control-icon);
152
152
  transform: translateX(var(--rp-spacing-1));
153
153
  }
154
- .rp-select__arrow[data-v-d7a0b110] {
154
+ .rp-select__arrow[data-v-7eb8ed79] {
155
155
  display: inline-flex;
156
156
  align-items: center;
157
157
  width: 1em;
158
158
  height: 1em;
159
159
  flex-shrink: 0;
160
160
  }
161
- .rp-select__arrow svg[data-v-d7a0b110] {
161
+ .rp-select__arrow svg[data-v-7eb8ed79] {
162
162
  width: 100%;
163
163
  height: 100%;
164
164
  }
165
- .rp-select__arrow[data-v-d7a0b110] {
165
+ .rp-select__arrow[data-v-7eb8ed79] {
166
166
  transition: opacity var(--rp-transition-fast);
167
167
  }
168
- .rp-select__clear[data-v-d7a0b110] {
168
+ .rp-select__clear[data-v-7eb8ed79] {
169
169
  padding: 0;
170
170
  font: inherit;
171
171
  background: none;
@@ -177,11 +177,11 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
177
177
  height: 1em;
178
178
  flex-shrink: 0;
179
179
  }
180
- .rp-select__clear svg[data-v-d7a0b110] {
180
+ .rp-select__clear svg[data-v-7eb8ed79] {
181
181
  width: 100%;
182
182
  height: 100%;
183
183
  }
184
- .rp-select__clear[data-v-d7a0b110] {
184
+ .rp-select__clear[data-v-7eb8ed79] {
185
185
  position: absolute;
186
186
  inset: 0;
187
187
  z-index: 1;
@@ -190,17 +190,17 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
190
190
  pointer-events: none;
191
191
  transition: color var(--rp-transition-fast), opacity var(--rp-transition-fast);
192
192
  }
193
- .rp-select__clear[data-v-d7a0b110]:hover {
193
+ .rp-select__clear[data-v-7eb8ed79]:hover {
194
194
  color: var(--rp-color-control-fg);
195
195
  }
196
- .rp-select__trigger:hover .rp-select__clear[data-v-d7a0b110] {
196
+ .rp-select__trigger:hover .rp-select__clear[data-v-7eb8ed79] {
197
197
  opacity: 1;
198
198
  pointer-events: auto;
199
199
  }
200
- .rp-select__trigger:hover .rp-select__clear + .rp-select__arrow[data-v-d7a0b110] {
200
+ .rp-select__trigger:hover .rp-select__clear + .rp-select__arrow[data-v-7eb8ed79] {
201
201
  opacity: 0;
202
202
  }
203
- .rp-select__dropdown[data-v-d7a0b110] {
203
+ .rp-select__dropdown[data-v-7eb8ed79] {
204
204
  position: absolute;
205
205
  top: calc(100% + var(--rp-spacing-2));
206
206
  left: 0;
@@ -214,10 +214,10 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
214
214
  max-height: 240px;
215
215
  padding: var(--rp-spacing-1);
216
216
  }
217
- .rp-select__dropdown[data-v-d7a0b110] .rp-scroll-area__viewport {
217
+ .rp-select__dropdown[data-v-7eb8ed79] .rp-scroll-area__viewport {
218
218
  scroll-padding-block: var(--rp-spacing-1);
219
219
  }
220
- .rp-select__option[data-v-d7a0b110] {
220
+ .rp-select__option[data-v-7eb8ed79] {
221
221
  display: flex;
222
222
  align-items: center;
223
223
  min-height: var(--_rp-select-option-min-height);
@@ -228,17 +228,17 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
228
228
  transition: color var(--rp-transition-fast);
229
229
  color: var(--rp-color-control-fg);
230
230
  }
231
- .rp-select__option--focused[data-v-d7a0b110] {
231
+ .rp-select__option--focused[data-v-7eb8ed79] {
232
232
  background-color: var(--_rp-select-option-focused-bg);
233
233
  }
234
- .rp-select__option--selected[data-v-d7a0b110] {
234
+ .rp-select__option--selected[data-v-7eb8ed79] {
235
235
  color: var(--rp-primary-color-light-color);
236
236
  }
237
- .rp-select__option--disabled[data-v-d7a0b110] {
237
+ .rp-select__option--disabled[data-v-7eb8ed79] {
238
238
  color: var(--rp-color-disabled-color);
239
239
  cursor: not-allowed;
240
240
  }
241
- .rp-select__empty[data-v-d7a0b110] {
241
+ .rp-select__empty[data-v-7eb8ed79] {
242
242
  display: flex;
243
243
  align-items: center;
244
244
  justify-content: center;
@@ -246,12 +246,12 @@ html.dark .rp-select[data-v-d7a0b110], [data-rp-color-scheme=dark] .rp-select[da
246
246
  color: var(--rp-color-dimmed);
247
247
  font-size: var(--_rp-select-font-size);
248
248
  }
249
- .rp-select-dropdown-enter-active[data-v-d7a0b110],
250
- .rp-select-dropdown-leave-active[data-v-d7a0b110] {
249
+ .rp-select-dropdown-enter-active[data-v-7eb8ed79],
250
+ .rp-select-dropdown-leave-active[data-v-7eb8ed79] {
251
251
  transition: opacity var(--rp-transition-fast), transform var(--rp-transition-fast);
252
252
  }
253
- .rp-select-dropdown-enter-from[data-v-d7a0b110],
254
- .rp-select-dropdown-leave-to[data-v-d7a0b110] {
253
+ .rp-select-dropdown-enter-from[data-v-7eb8ed79],
254
+ .rp-select-dropdown-leave-to[data-v-7eb8ed79] {
255
255
  opacity: 0;
256
256
  transform: translateY(calc(-1 * var(--rp-spacing-1)));
257
257
  }