ropav 0.1.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -4
- package/dist/base.css +570 -773
- package/dist/calendar.css +45 -34
- package/dist/calendar.js +108 -83
- package/dist/color-input.css +3 -7
- package/dist/color-picker.css +2 -6
- package/dist/color-swatch.css +2 -6
- package/dist/combobox.css +5 -5
- package/dist/componentColors.js +29 -25
- package/dist/components/alert/types.d.ts +1 -1
- package/dist/components/avatar/types.d.ts +1 -1
- package/dist/components/badge/types.d.ts +1 -1
- package/dist/components/calendar/index.d.ts +1 -1
- package/dist/components/calendar/types.d.ts +3 -0
- package/dist/components/date-picker/index.d.ts +1 -1
- package/dist/components/date-picker/types.d.ts +3 -1
- package/dist/components/pagination/types.d.ts +1 -1
- package/dist/components/progress/types.d.ts +1 -1
- package/dist/components/segmented-control/types.d.ts +1 -1
- package/dist/components/slider/types.d.ts +1 -1
- package/dist/components/slider/useSlider.d.ts +1 -1
- package/dist/components/slider/useSliderPointer.d.ts +15 -0
- package/dist/components/slider/useSliderValueState.d.ts +1 -0
- package/dist/components/toast/types.d.ts +1 -1
- package/dist/components/toolbar/index.d.ts +3 -0
- package/dist/components/toolbar/index.js +2 -0
- package/dist/components/toolbar/toolbar.d.ts +24 -0
- package/dist/components/toolbar/types.d.ts +12 -0
- package/dist/components/toolbar/useToolbar.d.ts +7 -0
- package/dist/date-picker.css +9 -9
- package/dist/date-picker.js +4 -2
- package/dist/dropdown-menu.css +7 -7
- package/dist/field.css +1 -1
- package/dist/focusNavigation.js +12 -6
- package/dist/hover-card.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -1
- package/dist/modal.css +1 -1
- package/dist/multi-select.css +5 -5
- package/dist/pagination.css +1 -1
- package/dist/popover.css +2 -2
- package/dist/select.css +5 -5
- package/dist/slider.css +80 -71
- package/dist/slider.js +91 -16
- package/dist/tabs.css +3 -3
- package/dist/tags-input.css +1 -1
- package/dist/textarea.css +1 -1
- package/dist/toast.css +1 -1
- package/dist/toolbar.css +15 -0
- package/dist/toolbar.js +143 -0
- package/dist/tooltip.css +1 -1
- package/dist/utils/componentColors.d.ts +2 -4
- package/dist/utils/dom/focusNavigation.d.ts +4 -1
- package/docs/code-architecture.md +30 -1
- package/docs/public-styles-api.md +11 -6
- package/docs/releasing.md +39 -0
- package/package.json +52 -39
- package/src/styles/_mixins.scss +2 -6
- package/src/styles/_tokens.scss +4 -833
- package/src/styles/generated/showcase.html +274 -0
- package/src/styles/generated/tokens.css +592 -0
- package/src/styles/generated/tokens.md +583 -0
- package/src/styles/generated/tokens.scss +1134 -0
- package/tokens/manifest.json +6164 -0
- package/docs/public-tokens.md +0 -685
- package/src/styles/_variables.scss +0 -243
- package/src/styles/styles-manifest.json +0 -5244
package/dist/slider.js
CHANGED
|
@@ -112,6 +112,63 @@ function getSliderTooltipAnchor(tooltip) {
|
|
|
112
112
|
return typeof tooltip === "object" && tooltip.anchor === "pointer" ? "pointer" : "thumb";
|
|
113
113
|
}
|
|
114
114
|
//#endregion
|
|
115
|
+
//#region src/components/slider/useSliderPointer.ts
|
|
116
|
+
function readPointerGeometry(track, orientation) {
|
|
117
|
+
const vertical = orientation === "vertical";
|
|
118
|
+
const thumbTravelRect = track.querySelector(".rp-slider__thumb")?.getBoundingClientRect();
|
|
119
|
+
const rect = thumbTravelRect && (vertical ? thumbTravelRect.height > 0 : thumbTravelRect.width > 0) ? thumbTravelRect : track.getBoundingClientRect();
|
|
120
|
+
const length = vertical ? rect.height : rect.width;
|
|
121
|
+
if (length <= 0) return;
|
|
122
|
+
return {
|
|
123
|
+
length,
|
|
124
|
+
start: vertical ? rect.bottom : rect.left,
|
|
125
|
+
vertical
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function getPointerValue(event, geometry, bounds, step) {
|
|
129
|
+
const pointerPosition = geometry.vertical ? event.clientY : event.clientX;
|
|
130
|
+
const ratio = clamp((geometry.vertical ? geometry.start - pointerPosition : pointerPosition - geometry.start) / geometry.length, 0, 1);
|
|
131
|
+
return normalizeSliderValue(bounds.min + ratio * (bounds.max - bounds.min), bounds.min, bounds.max, step);
|
|
132
|
+
}
|
|
133
|
+
function useSliderPointer(options) {
|
|
134
|
+
function refreshGeometry(currentSession) {
|
|
135
|
+
const geometry = readPointerGeometry(currentSession.track, options.orientation());
|
|
136
|
+
if (!geometry) return false;
|
|
137
|
+
currentSession.geometry = geometry;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
function updateFromPointer(event, currentSession) {
|
|
141
|
+
options.updateValue(getPointerValue(event, currentSession.geometry, options.bounds.value, options.step.value));
|
|
142
|
+
}
|
|
143
|
+
const pointerSession = createPointerSession({
|
|
144
|
+
onStart(event, currentSession) {
|
|
145
|
+
event.preventDefault();
|
|
146
|
+
options.inputRef.value?.focus({ preventScroll: true });
|
|
147
|
+
updateFromPointer(event, currentSession);
|
|
148
|
+
},
|
|
149
|
+
onUpdate: updateFromPointer,
|
|
150
|
+
refreshGeometry
|
|
151
|
+
});
|
|
152
|
+
function onPointerDown(event) {
|
|
153
|
+
return pointerSession.start(event, () => {
|
|
154
|
+
if (options.disabled()) return;
|
|
155
|
+
const track = event.currentTarget;
|
|
156
|
+
if (!track) return;
|
|
157
|
+
const geometry = readPointerGeometry(track, options.orientation());
|
|
158
|
+
if (!geometry) return;
|
|
159
|
+
return {
|
|
160
|
+
state: {
|
|
161
|
+
geometry,
|
|
162
|
+
track
|
|
163
|
+
},
|
|
164
|
+
target: track
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
onBeforeUnmount(pointerSession.stop);
|
|
169
|
+
return { onPointerDown };
|
|
170
|
+
}
|
|
171
|
+
//#endregion
|
|
115
172
|
//#region src/components/slider/useSliderPointerPreview.ts
|
|
116
173
|
function getPreviewRect(track, vertical) {
|
|
117
174
|
const travelRect = track.querySelector(".rp-slider__travel")?.getBoundingClientRect();
|
|
@@ -357,7 +414,11 @@ function useSliderValueState(props, onChange) {
|
|
|
357
414
|
function onInput(event) {
|
|
358
415
|
if (control.disabled) return;
|
|
359
416
|
const input = event.target;
|
|
360
|
-
|
|
417
|
+
updateValue(input.valueAsNumber);
|
|
418
|
+
}
|
|
419
|
+
function updateValue(value) {
|
|
420
|
+
if (control.disabled) return;
|
|
421
|
+
controllable.setValue(normalizeSliderValue(value, bounds.value.min, bounds.value.max, nativeStep.value));
|
|
361
422
|
}
|
|
362
423
|
useFormControl({
|
|
363
424
|
elements: () => [inputRef.value],
|
|
@@ -391,7 +452,8 @@ function useSliderValueState(props, onChange) {
|
|
|
391
452
|
markItems,
|
|
392
453
|
hasMarkLabels,
|
|
393
454
|
trackSlotProps,
|
|
394
|
-
onInput
|
|
455
|
+
onInput,
|
|
456
|
+
updateValue
|
|
395
457
|
};
|
|
396
458
|
}
|
|
397
459
|
//#endregion
|
|
@@ -436,6 +498,19 @@ function useSlider(props, onChange) {
|
|
|
436
498
|
invalid: valueState.control.invalid
|
|
437
499
|
}));
|
|
438
500
|
const trackStyle = computed(() => getSliderTrackStyle(props, valueState.valuePercent.value, tooltipState.tooltipPercent.value));
|
|
501
|
+
const pointerState = useSliderPointer({
|
|
502
|
+
bounds: valueState.bounds,
|
|
503
|
+
disabled: () => valueState.control.disabled,
|
|
504
|
+
inputRef: valueState.inputRef,
|
|
505
|
+
orientation: () => props.orientation,
|
|
506
|
+
step: valueState.nativeStep,
|
|
507
|
+
updateValue: valueState.updateValue
|
|
508
|
+
});
|
|
509
|
+
function onTrackPointerDown(event) {
|
|
510
|
+
const started = pointerState.onPointerDown(event);
|
|
511
|
+
tooltipState.onTooltipPointerDown(event);
|
|
512
|
+
return started;
|
|
513
|
+
}
|
|
439
514
|
return {
|
|
440
515
|
inputRef: valueState.inputRef,
|
|
441
516
|
focus: valueState.focus,
|
|
@@ -470,7 +545,7 @@ function useSlider(props, onChange) {
|
|
|
470
545
|
tooltipFormattedValue: tooltipState.tooltipFormattedValue,
|
|
471
546
|
tooltipContent: tooltipState.tooltipContent,
|
|
472
547
|
onInput: valueState.onInput,
|
|
473
|
-
|
|
548
|
+
onTrackPointerDown,
|
|
474
549
|
onTooltipPointerMove: tooltipState.onTooltipPointerMove,
|
|
475
550
|
onTooltipTrackEnter: tooltipState.onTooltipTrackEnter,
|
|
476
551
|
onTooltipTrackLeave: tooltipState.onTooltipTrackLeave,
|
|
@@ -481,17 +556,17 @@ function useSlider(props, onChange) {
|
|
|
481
556
|
}
|
|
482
557
|
//#endregion
|
|
483
558
|
//#region src/components/slider/slider.vue?vue&type=script&setup=true&vapor=true&lang.ts
|
|
484
|
-
var t0$2 = template("<span data-v-
|
|
485
|
-
var t1$2 = template("<span data-v-
|
|
486
|
-
var t2$2 = template("<span data-v-
|
|
487
|
-
var t3$2 = template("<span data-v-
|
|
488
|
-
var t4$2 = template("<span data-v-
|
|
489
|
-
var t5$1 = template("<span data-v-
|
|
490
|
-
var t6$1 = template("<span data-v-
|
|
491
|
-
var t7$1 = template("<span data-v-
|
|
492
|
-
var t8$1 = template("<span data-v-
|
|
559
|
+
var t0$2 = template("<span data-v-0fbfb274>");
|
|
560
|
+
var t1$2 = template("<span data-v-0fbfb274 class=rp-slider__header>");
|
|
561
|
+
var t2$2 = template("<span data-v-0fbfb274 class=\"rp-slider__track-layer rp-slider__track-underlay\"aria-hidden=true>");
|
|
562
|
+
var t3$2 = template("<span data-v-0fbfb274 class=\"rp-slider__track-layer rp-slider__track-overlay\"aria-hidden=true>");
|
|
563
|
+
var t4$2 = template("<span data-v-0fbfb274 class=rp-slider__travel aria-hidden=true>", 2);
|
|
564
|
+
var t5$1 = template("<span data-v-0fbfb274> ");
|
|
565
|
+
var t6$1 = template("<span data-v-0fbfb274><span data-v-0fbfb274 class=rp-slider__mark-dot></span>");
|
|
566
|
+
var t7$1 = template("<span data-v-0fbfb274 class=rp-slider__marks aria-hidden=true>");
|
|
567
|
+
var t8$1 = template("<span data-v-0fbfb274 class=rp-slider__tooltip-anchor aria-hidden=true></span>", 2);
|
|
493
568
|
var t9$1 = template(" ");
|
|
494
|
-
var t10 = template("<label data-v-
|
|
569
|
+
var t10 = template("<label data-v-0fbfb274><span data-v-0fbfb274><span data-v-0fbfb274 class=rp-slider__rail aria-hidden=true></span><!><span data-v-0fbfb274></span><!><input data-v-0fbfb274><!><span data-v-0fbfb274><span data-v-0fbfb274 class=rp-slider__thumb-content>", 1);
|
|
495
570
|
//#endregion
|
|
496
571
|
//#region src/components/slider/slider.vue
|
|
497
572
|
var slider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineVaporComponent({
|
|
@@ -554,7 +629,7 @@ var slider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
|
|
|
554
629
|
const slots = useSlots();
|
|
555
630
|
const props = __props;
|
|
556
631
|
const emit = __emit;
|
|
557
|
-
const { inputRef, focus, control, nativeMin, nativeMax, nativeStep, rootClass, normalizedValue, valuePercent, formattedValue, ariaValueText, markItems, thumbMode, trackSlotProps, trackStyle, trackHovered, dragging, tooltipVisible, tooltipOpen, tooltipAnchor, tooltipPlacement, tooltipId, tooltipColor, tooltipAutoContrast, tooltipContrastColor, tooltipOffset, tooltipOpenDelay, tooltipArrow, tooltipValue, tooltipPercent, tooltipFormattedValue, tooltipContent, onInput,
|
|
632
|
+
const { inputRef, focus, control, nativeMin, nativeMax, nativeStep, rootClass, normalizedValue, valuePercent, formattedValue, ariaValueText, markItems, thumbMode, trackSlotProps, trackStyle, trackHovered, dragging, tooltipVisible, tooltipOpen, tooltipAnchor, tooltipPlacement, tooltipId, tooltipColor, tooltipAutoContrast, tooltipContrastColor, tooltipOffset, tooltipOpenDelay, tooltipArrow, tooltipValue, tooltipPercent, tooltipFormattedValue, tooltipContent, onInput, onTrackPointerDown, onTooltipPointerMove, onTooltipTrackEnter, onTooltipTrackLeave, onTooltipFocusIn, onTooltipFocusOut, onTooltipKeydown } = useSlider(props, (value) => emit("update:modelValue", value));
|
|
558
633
|
const { getPartAttrs, getRootAttrs } = useStylesApi(props, "root");
|
|
559
634
|
const rootAttrs = computed(() => getRootAttrs({
|
|
560
635
|
class: [rootClass.value, { "rp-slider--custom-thumb": Boolean(slots.thumb) }],
|
|
@@ -741,7 +816,7 @@ var slider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
|
|
|
741
816
|
}
|
|
742
817
|
});
|
|
743
818
|
});
|
|
744
|
-
on(n45, "pointerdown", (e) => unref(
|
|
819
|
+
on(n45, "pointerdown", (e) => unref(onTrackPointerDown)(e));
|
|
745
820
|
on(n45, "pointerenter", (e) => unref(onTooltipTrackEnter)(e));
|
|
746
821
|
on(n45, "pointerleave", (e) => unref(onTooltipTrackLeave)(e));
|
|
747
822
|
on(n45, "pointermove", (e) => unref(onTooltipPointerMove)(e));
|
|
@@ -750,7 +825,7 @@ var slider_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE_
|
|
|
750
825
|
on(n45, "keydown", (e) => unref(onTooltipKeydown)(e));
|
|
751
826
|
return n48;
|
|
752
827
|
}
|
|
753
|
-
}), [["__scopeId", "data-v-
|
|
828
|
+
}), [["__scopeId", "data-v-0fbfb274"]]);
|
|
754
829
|
//#endregion
|
|
755
830
|
//#region src/components/slider/useRangeSliderTooltipCollision.ts
|
|
756
831
|
var TOOLTIP_COLLISION_GAP = 4;
|
package/dist/tabs.css
CHANGED
|
@@ -213,7 +213,7 @@
|
|
|
213
213
|
}
|
|
214
214
|
.rp-tabs-trigger--active[data-v-20d5c2eb] {
|
|
215
215
|
--_rp-tabs-trigger-fg: var(--rp-color-text);
|
|
216
|
-
--_rp-tabs-trigger-indicator: var(--rp-primary-
|
|
216
|
+
--_rp-tabs-trigger-indicator: var(--rp-color-primary-filled);
|
|
217
217
|
}
|
|
218
218
|
.rp-tabs-trigger--pills[data-v-20d5c2eb]::after, .rp-tabs-trigger--outline[data-v-20d5c2eb]::after {
|
|
219
219
|
display: none;
|
|
@@ -224,8 +224,8 @@
|
|
|
224
224
|
}
|
|
225
225
|
.rp-tabs-trigger--pills.rp-tabs-trigger--active[data-v-20d5c2eb] {
|
|
226
226
|
--_rp-tabs-trigger-fg: var(--rp-color-white);
|
|
227
|
-
--_rp-tabs-trigger-bg: var(--rp-primary-
|
|
228
|
-
--_rp-tabs-trigger-bg-hover: var(--rp-primary-
|
|
227
|
+
--_rp-tabs-trigger-bg: var(--rp-color-primary-filled);
|
|
228
|
+
--_rp-tabs-trigger-bg-hover: var(--rp-color-primary-filled-hover);
|
|
229
229
|
}
|
|
230
230
|
.rp-tabs-trigger--outline[data-v-20d5c2eb] {
|
|
231
231
|
--_rp-tabs-trigger-bg-hover: var(--rp-color-default-hover);
|
package/dist/tags-input.css
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
display: inline-flex;
|
|
11
11
|
align-items: center;
|
|
12
12
|
box-sizing: border-box;
|
|
13
|
-
min-width:
|
|
13
|
+
min-width: var(--rp-component-menu-min-width);
|
|
14
14
|
min-height: var(--_rp-tags-input-height);
|
|
15
15
|
padding: var(--rp-spacing-1) var(--_rp-tags-input-padding-x);
|
|
16
16
|
gap: var(--rp-spacing-2);
|
package/dist/textarea.css
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
.rp-textarea--radius-xl[data-v-da9cf2c9] {
|
|
69
69
|
--_rp-textarea-radius: var(--rp-radius-xl);
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
[data-scheme=dark] .rp-textarea[data-v-da9cf2c9] {
|
|
72
72
|
--_rp-textarea-valid-border: var(--rp-color-green-light-color);
|
|
73
73
|
--_rp-textarea-valid-ring: color-mix(
|
|
74
74
|
in srgb,
|
package/dist/toast.css
CHANGED
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
--_rp-toast-viewport-shift-x: 0;
|
|
137
137
|
--_rp-toast-viewport-shift-y: calc(var(--rp-spacing-3) * -1);
|
|
138
138
|
position: fixed;
|
|
139
|
-
z-index:
|
|
139
|
+
z-index: var(--rp-z-index-tooltip)1;
|
|
140
140
|
display: flex;
|
|
141
141
|
box-sizing: border-box;
|
|
142
142
|
width: min(24rem, 100vw);
|
package/dist/toolbar.css
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@layer ropav.components {
|
|
2
|
+
.rp-toolbar[data-v-34ce03a4] {
|
|
3
|
+
box-sizing: border-box;
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: var(--rp-spacing-2);
|
|
7
|
+
min-width: 0;
|
|
8
|
+
font-family: var(--rp-font-family);
|
|
9
|
+
}
|
|
10
|
+
.rp-toolbar--vertical[data-v-34ce03a4] {
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
align-items: stretch;
|
|
13
|
+
min-height: 0;
|
|
14
|
+
}
|
|
15
|
+
}
|
package/dist/toolbar.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import './toolbar.css';
|
|
2
|
+
import { t as useStylesApi } from "./styles-api.js";
|
|
3
|
+
import { t as bem } from "./bem.js";
|
|
4
|
+
import { t as isElement } from "./query.js";
|
|
5
|
+
import { n as setFocusNavigationTabStop, t as getFocusNavigationTarget } from "./focusNavigation.js";
|
|
6
|
+
import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
|
|
7
|
+
import { computed, createSlot, defineVaporComponent, onBeforeUnmount, onMounted, renderEffect, setDynamicProps, setInsertionState, setStaticTemplateRef, shallowRef, template } from "vue";
|
|
8
|
+
//#region src/components/toolbar/useToolbar.ts
|
|
9
|
+
var TOOLBAR_SELECTOR = "[role=\"toolbar\"]";
|
|
10
|
+
var TOOLBAR_ITEM_SELECTOR = [
|
|
11
|
+
"button",
|
|
12
|
+
"a[href]",
|
|
13
|
+
"input:not([type=\"hidden\"])",
|
|
14
|
+
"select",
|
|
15
|
+
"textarea",
|
|
16
|
+
"[contenteditable=\"true\"]",
|
|
17
|
+
"[role=\"button\"]",
|
|
18
|
+
"[role=\"checkbox\"]",
|
|
19
|
+
"[role=\"combobox\"]",
|
|
20
|
+
"[role=\"link\"]",
|
|
21
|
+
"[role=\"radio\"]",
|
|
22
|
+
"[role=\"slider\"]",
|
|
23
|
+
"[role=\"spinbutton\"]",
|
|
24
|
+
"[role=\"switch\"]",
|
|
25
|
+
"[tabindex]"
|
|
26
|
+
].join(",");
|
|
27
|
+
var TOOLBAR_NAVIGATION_OPTIONS = {
|
|
28
|
+
itemSelector: TOOLBAR_ITEM_SELECTOR,
|
|
29
|
+
collectionSelector: TOOLBAR_SELECTOR
|
|
30
|
+
};
|
|
31
|
+
function useToolbar(root, getOrientation) {
|
|
32
|
+
const activeItem = shallowRef(null);
|
|
33
|
+
let observer = null;
|
|
34
|
+
function setTabStop(item) {
|
|
35
|
+
const toolbar = root.value;
|
|
36
|
+
if (!toolbar) return null;
|
|
37
|
+
const nextItem = setFocusNavigationTabStop(toolbar, item, TOOLBAR_NAVIGATION_OPTIONS);
|
|
38
|
+
activeItem.value = nextItem;
|
|
39
|
+
return nextItem;
|
|
40
|
+
}
|
|
41
|
+
function syncTabStop() {
|
|
42
|
+
setTabStop(activeItem.value);
|
|
43
|
+
}
|
|
44
|
+
function onFocusin(event) {
|
|
45
|
+
const toolbar = root.value;
|
|
46
|
+
if (!toolbar || !isElement(event.target)) return;
|
|
47
|
+
const item = event.target.closest(TOOLBAR_ITEM_SELECTOR);
|
|
48
|
+
if (item?.closest(TOOLBAR_SELECTOR) === toolbar) setTabStop(item);
|
|
49
|
+
}
|
|
50
|
+
function onKeydown(event) {
|
|
51
|
+
const toolbar = root.value;
|
|
52
|
+
if (!toolbar) return;
|
|
53
|
+
const nextItem = getFocusNavigationTarget(event, toolbar, {
|
|
54
|
+
...TOOLBAR_NAVIGATION_OPTIONS,
|
|
55
|
+
orientation: getOrientation()
|
|
56
|
+
});
|
|
57
|
+
if (!nextItem) return;
|
|
58
|
+
event.preventDefault();
|
|
59
|
+
setTabStop(nextItem);
|
|
60
|
+
nextItem.focus();
|
|
61
|
+
}
|
|
62
|
+
function focus() {
|
|
63
|
+
setTabStop(activeItem.value)?.focus();
|
|
64
|
+
}
|
|
65
|
+
onMounted(() => {
|
|
66
|
+
const toolbar = root.value;
|
|
67
|
+
if (!toolbar) return;
|
|
68
|
+
syncTabStop();
|
|
69
|
+
const MutationObserverConstructor = toolbar.ownerDocument.defaultView?.MutationObserver;
|
|
70
|
+
if (!MutationObserverConstructor) return;
|
|
71
|
+
observer = new MutationObserverConstructor(syncTabStop);
|
|
72
|
+
observer.observe(toolbar, {
|
|
73
|
+
attributes: true,
|
|
74
|
+
attributeFilter: [
|
|
75
|
+
"disabled",
|
|
76
|
+
"hidden",
|
|
77
|
+
"inert"
|
|
78
|
+
],
|
|
79
|
+
childList: true,
|
|
80
|
+
subtree: true
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
onBeforeUnmount(() => observer?.disconnect());
|
|
84
|
+
return {
|
|
85
|
+
focus,
|
|
86
|
+
onFocusin,
|
|
87
|
+
onKeydown
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/components/toolbar/toolbar.vue?vue&type=script&setup=true&vapor=true&lang.ts
|
|
92
|
+
var t0 = template("<div data-v-34ce03a4>", 1);
|
|
93
|
+
//#endregion
|
|
94
|
+
//#region src/components/toolbar/toolbar.vue
|
|
95
|
+
var toolbar_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineVaporComponent({
|
|
96
|
+
name: "RpToolbar",
|
|
97
|
+
inheritAttrs: false,
|
|
98
|
+
__name: "toolbar",
|
|
99
|
+
props: {
|
|
100
|
+
id: {},
|
|
101
|
+
orientation: { default: "horizontal" },
|
|
102
|
+
ariaLabel: {},
|
|
103
|
+
describedby: {},
|
|
104
|
+
labelledby: {},
|
|
105
|
+
classNames: {},
|
|
106
|
+
styles: {}
|
|
107
|
+
},
|
|
108
|
+
setup(__props, { expose: __expose }) {
|
|
109
|
+
const props = __props;
|
|
110
|
+
const root = shallowRef(null);
|
|
111
|
+
const { focus, onFocusin, onKeydown } = useToolbar(root, () => props.orientation);
|
|
112
|
+
const rootClass = computed(() => bem("rp-toolbar", { vertical: props.orientation === "vertical" }));
|
|
113
|
+
const { getRootAttrs } = useStylesApi(props, "root");
|
|
114
|
+
const rootAttrs = computed(() => getRootAttrs({
|
|
115
|
+
id: props.id,
|
|
116
|
+
class: rootClass.value,
|
|
117
|
+
role: "toolbar",
|
|
118
|
+
"data-orientation": props.orientation,
|
|
119
|
+
"aria-orientation": props.orientation,
|
|
120
|
+
"aria-label": props.ariaLabel || void 0,
|
|
121
|
+
"aria-labelledby": props.labelledby,
|
|
122
|
+
"aria-describedby": props.describedby,
|
|
123
|
+
onFocusin,
|
|
124
|
+
onKeydown
|
|
125
|
+
}));
|
|
126
|
+
__expose({
|
|
127
|
+
nativeElement: root,
|
|
128
|
+
focus
|
|
129
|
+
});
|
|
130
|
+
const n1 = t0();
|
|
131
|
+
renderEffect(() => setDynamicProps(n1, [rootAttrs.value]));
|
|
132
|
+
setInsertionState(n1, null, 0);
|
|
133
|
+
createSlot("default", null, null, 1);
|
|
134
|
+
setStaticTemplateRef(n1, root, null, "root");
|
|
135
|
+
return n1;
|
|
136
|
+
}
|
|
137
|
+
}), [["__scopeId", "data-v-34ce03a4"]]);
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/components/toolbar/types.ts
|
|
140
|
+
var toolbarParts = ["root"];
|
|
141
|
+
var toolbarOrientations = ["horizontal", "vertical"];
|
|
142
|
+
//#endregion
|
|
143
|
+
export { toolbarParts as n, toolbar_default as r, toolbarOrientations as t };
|
package/dist/tooltip.css
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
--_rp-tooltip-bg: var(--rp-color-bright);
|
|
13
13
|
--_rp-tooltip-fg: var(--rp-color-default);
|
|
14
14
|
position: absolute;
|
|
15
|
-
z-index:
|
|
15
|
+
z-index: var(--rp-z-index-tooltip);
|
|
16
16
|
box-sizing: border-box;
|
|
17
17
|
width: max-content;
|
|
18
18
|
max-width: min(18rem, 100vw - var(--rp-spacing-6));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const componentColors: readonly ["
|
|
2
|
-
export declare const componentColorShades: readonly ["
|
|
1
|
+
export declare const componentColors: readonly ["primary", "gray", "red", "pink", "grape", "violet", "indigo", "blue", "cyan", "teal", "green", "lime", "yellow", "orange"];
|
|
2
|
+
export declare const componentColorShades: readonly ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
|
|
3
3
|
export type ComponentColor = (typeof componentColors)[number];
|
|
4
4
|
export type ComponentColorShade = (typeof componentColorShades)[number];
|
|
5
5
|
export type ComponentColorShadeValue = `${ComponentColor}.${ComponentColorShade}`;
|
|
@@ -57,8 +57,6 @@ export type ParsedComponentColor = {
|
|
|
57
57
|
} | {
|
|
58
58
|
kind: 'preset';
|
|
59
59
|
color: ComponentColor;
|
|
60
|
-
} | {
|
|
61
|
-
kind: 'primary';
|
|
62
60
|
} | {
|
|
63
61
|
kind: 'shade';
|
|
64
62
|
color: ComponentColor;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export type FocusNavigationOrientation = 'horizontal' | 'vertical';
|
|
2
|
-
export interface
|
|
2
|
+
export interface FocusNavigationCollectionOptions {
|
|
3
3
|
itemSelector: string;
|
|
4
4
|
collectionSelector: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FocusNavigationOptions extends FocusNavigationCollectionOptions {
|
|
5
7
|
orientation: FocusNavigationOrientation;
|
|
6
8
|
}
|
|
9
|
+
export declare function setFocusNavigationTabStop<ElementType extends HTMLElement>(collection: HTMLElement, preferredItem: ElementType | null, options: FocusNavigationCollectionOptions): ElementType | null;
|
|
7
10
|
export declare function getFocusNavigationTarget<ElementType extends HTMLElement>(event: Pick<KeyboardEvent, 'key' | 'target'>, collection: HTMLElement, options: FocusNavigationOptions): ElementType | undefined;
|
|
@@ -4,6 +4,16 @@ This guide defines the source structure expected from contributors. The goal is
|
|
|
4
4
|
codebase where UI files describe rendering, behavior is testable through small interfaces, and
|
|
5
5
|
shared logic has one obvious home.
|
|
6
6
|
|
|
7
|
+
## Package seams
|
|
8
|
+
|
|
9
|
+
This repository publishes `ropav`, a zero-VDOM UI component library for Vue Vapor. Paths such as
|
|
10
|
+
`src/utils/` below are relative to this package's root.
|
|
11
|
+
|
|
12
|
+
The library integrates `@floating-ui/dom` and `focus-trap` through package dependencies, and it
|
|
13
|
+
exposes public composables, component subpath exports, design tokens, and styles through its
|
|
14
|
+
`package.json` exports. Production source stays zero-VDOM: component rendering, style injection,
|
|
15
|
+
and accessible behavior are built with Vue Vapor, never through VDOM interfaces.
|
|
16
|
+
|
|
7
17
|
## Module seams
|
|
8
18
|
|
|
9
19
|
A module should hide a meaningful amount of behavior behind a small interface. Extract code around
|
|
@@ -106,6 +116,22 @@ Test through the interface of the extracted module:
|
|
|
106
116
|
Tests should assert observable behavior rather than private implementation details. Refactoring a
|
|
107
117
|
module internally should not require rewriting its behavioral tests.
|
|
108
118
|
|
|
119
|
+
### Storybook organization
|
|
120
|
+
|
|
121
|
+
Keep component stories beside their component at
|
|
122
|
+
`src/components/<name>/<name>.stories.ts`. Use human-readable Storybook titles with this hierarchy:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
Foundations/<name>
|
|
126
|
+
Components/<category>/<name>
|
|
127
|
+
Utilities/<name>
|
|
128
|
+
Contracts/<name>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Component categories are `Actions`, `Data Display`, `Feedback`, `Forms`, `Layout`, `Navigation`,
|
|
132
|
+
and `Overlays`. Foundations document design tokens, utilities demonstrate lower-level package
|
|
133
|
+
capabilities, and contracts exercise cross-component or browser integration behavior.
|
|
134
|
+
|
|
109
135
|
## Contributor checklist
|
|
110
136
|
|
|
111
137
|
Before opening a pull request:
|
|
@@ -115,4 +141,7 @@ Before opening a pull request:
|
|
|
115
141
|
- Dependency direction remains downward and acyclic.
|
|
116
142
|
- Functions stay below the enforced complexity, depth, length, and parameter limits.
|
|
117
143
|
- New behavior is tested at the module interface.
|
|
118
|
-
-
|
|
144
|
+
- The package defines a `verify` script for package-owned type, test, build, and bundle behavior.
|
|
145
|
+
- Lint, formatting, architecture, and zero-VDOM bundle contracts run from the root verification
|
|
146
|
+
interface.
|
|
147
|
+
- `pnpm verify` passes from the repository root.
|
|
@@ -81,6 +81,9 @@ Only independently useful semantic elements are public parts. Conditional parts
|
|
|
81
81
|
|
|
82
82
|
`ToastProvider` renders no DOM and therefore has no Styles API.
|
|
83
83
|
|
|
84
|
+
When `Calendar.showHeader` is `false`, the `header`, `previousControl` and `nextControl` parts are
|
|
85
|
+
not rendered. The `monthLabel` part remains as a visually hidden live label for the calendar grid.
|
|
86
|
+
|
|
84
87
|
## State attributes
|
|
85
88
|
|
|
86
89
|
Boolean states use presence semantics: the attribute value is empty when true and the attribute is absent when false or unknown. Enum values are lowercase kebab-case.
|
|
@@ -118,13 +121,15 @@ Active menu and listbox descendants use `data-highlighted`. Actual DOM keyboard
|
|
|
118
121
|
|
|
119
122
|
## Public CSS variables
|
|
120
123
|
|
|
121
|
-
The exact entries in [`
|
|
124
|
+
The exact entries in the packaged [`tokens/manifest.json`](../tokens/manifest.json) (also exported as `ropav/styles-manifest`) are the public contract. A design token enters that manifest only when it opts in with `$extensions.umberkit.public: true`. Emitting a CSS variable is a separate runtime concern: neither emission nor a name prefix makes a variable public. Undocumented variables, underscore-prefixed variables, DOM structure and internal component selectors are not part of the public contract and may change.
|
|
125
|
+
|
|
126
|
+
Tokens are built with [umberkit](https://www.npmjs.com/package/umberkit): 12-step OKLCH palettes generated from one seed per hue (Radix step semantics — 1-2 backgrounds, 3-5 component backgrounds, 6-8 borders, 9-10 solids, 11-12 text), plus hand-authored semantic roles (`--rp-color-<hue>-filled`, `-light`, `-outline`, …) and scheme semantics (`--rp-color-body`, `-text`, `-default`, …). The generated `tokens.md` and `showcase.html` shipped in `src/styles/generated/` document every token and render the ramps with a contrast grid.
|
|
122
127
|
|
|
123
|
-
|
|
128
|
+
A deliberately small component-geometry namespace (`--rp-switch-*`, `--rp-slider-*`, `--rp-radio-*`) stays outside the token tree: those variables are consumer override hooks with size-preset fallbacks, so they are intentionally undefined by default. Slider and RangeSlider share the `--rp-slider-*` namespace; size presets provide fallbacks, while a consumer value wins for the individual dimension.
|
|
124
129
|
|
|
125
|
-
|
|
130
|
+
## Color scheme
|
|
126
131
|
|
|
127
|
-
|
|
132
|
+
Every color token is emitted as `light-dark()`. Set `data-scheme="dark"` (or `"light"`) on `<html>` to switch schemes; without the attribute the operating-system preference applies. Because `light-dark()` values resolve against the color scheme of the element they are declared on (`:root`), the attribute must be set on the document element — subtree scheme switching is not supported.
|
|
128
133
|
|
|
129
134
|
## Cascade layers and migration
|
|
130
135
|
|
|
@@ -141,6 +146,6 @@ Place global resets in `reset` and application overrides in `app`. Import order
|
|
|
141
146
|
- Typed parts, state attributes, manifest entries, geometry variables and cascade layers form the current Public Styles API.
|
|
142
147
|
- Renaming or removing a documented part, state attribute or variable changes the public contract.
|
|
143
148
|
- Adding a public part, state attribute or variable extends the public contract.
|
|
144
|
-
- `tokens:check`
|
|
145
|
-
- Release tags must be available in the Git checkout that runs the check
|
|
149
|
+
- `tokens:check` runs `umberkit check`: lint, generated-palette and manifest drift, and the contract ratchet against the latest reachable `v*` release tag. Removing, renaming, retyping or un-publishing a released public token fails until `contract.version` rises in `umberkit.config.ts`.
|
|
150
|
+
- Release tags must be available in the Git checkout that runs the check (`fetch-depth: 0` in CI). `umberkit check --against <ref>` can explicitly select another baseline.
|
|
146
151
|
- Internal DOM, selectors and undocumented variables are outside the public contract.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
This repository publishes `ropav` with [`bumpp`](https://www.npmjs.com/package/bumpp). Release notes
|
|
4
|
+
are generated from Conventional Commits, and the package is published from GitHub Actions with npm
|
|
5
|
+
Trusted Publishing.
|
|
6
|
+
|
|
7
|
+
## Release
|
|
8
|
+
|
|
9
|
+
With a clean working tree, run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm release
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`bumpp` bumps the package to the next version (patch/minor/major prompt), runs `pnpm run changelog`
|
|
16
|
+
to regenerate the changelog from commits since the last `v*` tag, then commits
|
|
17
|
+
`chore(release): vX.Y.Z`, tags `vX.Y.Z`, and pushes the commit and tag.
|
|
18
|
+
|
|
19
|
+
Every push to `main` runs the full quality suite. When the pushed commit is a release commit
|
|
20
|
+
(message starts with `chore(release): v`), the release job rebuilds the package, checks the built
|
|
21
|
+
bundles, and publishes it to npm. Change the release commit message in the `release` script and the
|
|
22
|
+
release workflow will need the matching prefix.
|
|
23
|
+
|
|
24
|
+
## Changelog
|
|
25
|
+
|
|
26
|
+
`pnpm run changelog` regenerates `CHANGELOG.md` from commits since the latest `v*` tag. The release
|
|
27
|
+
flow runs this automatically. The changelog is a tracked file, so the working tree must be clean
|
|
28
|
+
before `pnpm release`.
|
|
29
|
+
|
|
30
|
+
## Trusted Publisher configuration
|
|
31
|
+
|
|
32
|
+
The npm package is configured as a Trusted Publisher:
|
|
33
|
+
|
|
34
|
+
- GitHub owner: `daopk`
|
|
35
|
+
- Repository: `ropav`
|
|
36
|
+
- Workflow filename: `publish.yml`
|
|
37
|
+
|
|
38
|
+
The workflow uses GitHub-hosted runners, Node 24, and `id-token: write`. Do not add a long-lived npm
|
|
39
|
+
publish token to the workflow.
|