eco-vue-js 0.27.4 → 0.28.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/dist/components/ActionsBar/WActionsBar.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Button/WButtonAction.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Button/WButtonDropdown.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Button/WButtonTab.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Chart/WChartLine.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Checkbox/WCheckbox.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Counter/WCounter.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/DatePicker/WDatePicker.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/DatePicker/WDatePickerSingle.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/DatePicker/components/CalendarToggle.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Dismissable/WDismissable.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Expansion/WExpansion.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Expansion/WExpansionItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/FilePicker/components/FilePickerSvg.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/InfiniteList/components/InfiniteListPage.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Input/WInput.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Input/WInputSuggest.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/List/WListHeaderItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/List/components/HeaderSortItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/List/components/ListFilterChip.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/List/components/ListItem.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Modal/WModal.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Nav/WNavBar.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Nav/WNavItem.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Nav/WNavItemExpand.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Nav/WNavItemTransition.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Notify/WNotify.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Notify/WNotifyCenter.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Progress/WProgress.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Progress/WProgressBar.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/components/Progress/WProgressStriped.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/Skeleton/WSkeleton.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Slider/WSlider.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Slider/WSliderRange.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/components/Spinner/WSpinner.vue.js +1 -1
- package/dist/components/Tabs/WTabs.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/components/TextOverflow/WTextOverflow.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/components/Toggle/WToggle.vue_vue_type_script_setup_true_lang.js +1 -1
- package/docs/llms.txt +1 -1
- package/eslint/plugin.js +31 -1
- package/eslint/processors/motion-css.js +42 -0
- package/eslint/rules/motion/classes.js +74 -0
- package/eslint/rules/motion/css.js +196 -0
- package/eslint/rules/motion-safe.js +96 -0
- package/package.json +4 -2
- package/tailwind-base/css/markdown/blocks.css +1 -1
- package/tailwind-base/plugins/internal-classes.ts +6 -2
- package/tailwind-base/plugins/w-hover-circle.ts +5 -3
- package/tailwind-base/plugins/w-ripple.ts +3 -1
|
@@ -38,7 +38,7 @@ var WActionsBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
|
|
|
38
38
|
return (_ctx, _cache) => {
|
|
39
39
|
return openBlock(), createElementBlock("div", {
|
|
40
40
|
ref: "bar",
|
|
41
|
-
class: normalizeClass(["w-actions-bar sm-not:[--actions-bar-filter-width:calc(100vw-var(--w-actions-bar-width))] fixed right-(--w-right-margin,0px) top-0 grid grid-cols-[var(--actions-bar-filter-width-current,0)_var(--w-actions-bar-width)] grid-rows-[var(--header-height)_1fr] justify-end overflow-hidden transition-[grid-template-columns] duration-300 print:hidden", { "[--actions-bar-filter-width-current:var(--actions-bar-filter-width)]": isOpen.value && hasFilter.value }]),
|
|
41
|
+
class: normalizeClass(["w-actions-bar sm-not:[--actions-bar-filter-width:calc(100vw-var(--w-actions-bar-width))] fixed right-(--w-right-margin,0px) top-0 grid grid-cols-[var(--actions-bar-filter-width-current,0)_var(--w-actions-bar-width)] grid-rows-[var(--header-height)_1fr] justify-end overflow-hidden motion-safe:transition-[grid-template-columns] motion-safe:duration-300 print:hidden", { "[--actions-bar-filter-width-current:var(--actions-bar-filter-width)]": isOpen.value && hasFilter.value }]),
|
|
42
42
|
style: normalizeStyle({ zIndex: unref(40) })
|
|
43
43
|
}, [createElementVNode("div", _hoisted_1, [createElementVNode("div", _hoisted_2, [createElementVNode("div", _hoisted_3, toDisplayString(__props.textFilter ?? "Filters"), 1), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(filter), (slot, index) => {
|
|
44
44
|
return openBlock(), createBlock(resolveDynamicComponent(slot), { key: index });
|
|
@@ -48,7 +48,7 @@ var WActionsBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
|
|
|
48
48
|
"aria-expanded": isOpen.value,
|
|
49
49
|
"aria-label": "Toggle filters",
|
|
50
50
|
onClick: toggle
|
|
51
|
-
}, [createVNode(unref(IconBack_default), { class: normalizeClass(["text-description square-4 transition-transform", { "transform-[rotateY(180deg)]": isOpen.value }]) }, null, 8, ["class"])], 8, _hoisted_5)) : createCommentVNode("", true), createElementVNode("div", _hoisted_6, [createElementVNode("div", null, [
|
|
51
|
+
}, [createVNode(unref(IconBack_default), { class: normalizeClass(["text-description square-4 motion-safe:transition-transform", { "transform-[rotateY(180deg)]": isOpen.value }]) }, null, 8, ["class"])], 8, _hoisted_5)) : createCommentVNode("", true), createElementVNode("div", _hoisted_6, [createElementVNode("div", null, [
|
|
52
52
|
renderSlot(_ctx.$slots, "top"),
|
|
53
53
|
_ctx.$slots.top && (hasFilter.value || _ctx.$slots.bottom) ? (openBlock(), createElementBlock("div", _hoisted_7)) : createCommentVNode("", true),
|
|
54
54
|
hasFilter.value ? (openBlock(), createBlock(WButtonAction_default, {
|
|
@@ -82,10 +82,10 @@ var WButtonAction_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
82
82
|
}, null, 8, ["count"])), [[vShow, __props.count > 0]]) : createCommentVNode("", true),
|
|
83
83
|
renderSlot(_ctx.$slots, "icon", {}, () => [__props.icon ? (openBlock(), createBlock(resolveDynamicComponent(__props.icon), {
|
|
84
84
|
key: 0,
|
|
85
|
-
class: normalizeClass(["square-6 w-svg-stroke-width-sm place-self-center transition-transform", { "group-hover:scale-120": !__props.disabled }])
|
|
85
|
+
class: normalizeClass(["square-6 w-svg-stroke-width-sm place-self-center motion-safe:transition-transform", { "group-hover:scale-120": !__props.disabled }])
|
|
86
86
|
}, null, 8, ["class"])) : createCommentVNode("", true)]),
|
|
87
87
|
!__props.disabled && !unref(isBackdrop) && !__props.loading ? (openBlock(), createBlock(WShine_default, { key: 1 })) : createCommentVNode("", true),
|
|
88
|
-
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[0] || (_cache[0] = [createElementVNode("div", { class: "absolute inset-0 bg-linear-90 from-current/0 to-current/0 via-current animate-ticker" }, null, -1)])])) : createCommentVNode("", true)
|
|
88
|
+
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_1, [..._cache[0] || (_cache[0] = [createElementVNode("div", { class: "absolute inset-0 bg-linear-90 from-current/0 to-current/0 via-current motion-safe:animate-ticker" }, null, -1)])])) : createCommentVNode("", true)
|
|
89
89
|
], 2)),
|
|
90
90
|
__props.titleText ? (openBlock(), createElementBlock("div", {
|
|
91
91
|
key: 2,
|
|
@@ -62,7 +62,7 @@ var WButtonDropdown_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
62
62
|
join: "",
|
|
63
63
|
onClick: toggle
|
|
64
64
|
}, {
|
|
65
|
-
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-4 transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
65
|
+
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-4 motion-safe:transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
66
66
|
_: 1
|
|
67
67
|
}, 8, ["semantic-type", "disabled"])) : createCommentVNode("", true),
|
|
68
68
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.$slots.button?.(), (item, index) => {
|
|
@@ -79,7 +79,7 @@ var WButtonDropdown_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
79
79
|
join: "",
|
|
80
80
|
onClick: toggle
|
|
81
81
|
}, {
|
|
82
|
-
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-[1em] transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
82
|
+
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-[1em] motion-safe:transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
83
83
|
_: 1
|
|
84
84
|
}, 8, ["semantic-type", "disabled"])) : createCommentVNode("", true)
|
|
85
85
|
]), __props.tooltipText ? (openBlock(), createBlock(WTooltip_default, {
|
|
@@ -52,7 +52,7 @@ var WButtonTab_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
52
52
|
}],
|
|
53
53
|
onClick: _cache[0] || (_cache[0] = ($event) => !__props.disabled && _ctx.$emit("click", $event))
|
|
54
54
|
}), {
|
|
55
|
-
default: withCtx(() => [__props.indicator ? (openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", { class: normalizeClass(["text-surface rounded-full bg-inherit p-1 outline transition-[outline-width] duration-500", {
|
|
55
|
+
default: withCtx(() => [__props.indicator ? (openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", { class: normalizeClass(["text-surface rounded-full bg-inherit p-1 outline motion-safe:transition-[outline-width] motion-safe:duration-500", {
|
|
56
56
|
"tone-negative bg-tone-fill outline-tone/10": __props.hasError,
|
|
57
57
|
"tone-positive bg-tone-fill outline-tone/10": !__props.hasError && __props.hasValue && __props.showHasValue,
|
|
58
58
|
"bg-track-strong outline-track-strong/10": !__props.hasError && (!__props.showHasValue || !__props.hasValue),
|
|
@@ -124,8 +124,8 @@ var WButtonTab_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
124
124
|
_: 1
|
|
125
125
|
}),
|
|
126
126
|
createVNode(Transition, {
|
|
127
|
-
"enter-active-class": "transition-[scale,opacity] origin-center duration-300",
|
|
128
|
-
"leave-active-class": "transition-[scale,opacity] origin-center duration-300",
|
|
127
|
+
"enter-active-class": "motion-safe:transition-[scale,opacity] origin-center motion-safe:duration-300",
|
|
128
|
+
"leave-active-class": "motion-safe:transition-[scale,opacity] origin-center motion-safe:duration-300",
|
|
129
129
|
"enter-from-class": "scale-x-0 opacity-0",
|
|
130
130
|
"leave-to-class": "scale-x-0 opacity-0",
|
|
131
131
|
css: !__props.indicator
|
|
@@ -240,12 +240,12 @@ var WChartLine_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
240
240
|
d: minMaxAreaPath.value,
|
|
241
241
|
fill: "white",
|
|
242
242
|
"fill-opacity": "0.2",
|
|
243
|
-
class: "transition-[d]"
|
|
243
|
+
class: "motion-safe:transition-[d]"
|
|
244
244
|
}, null, 8, _hoisted_5)) : createCommentVNode("", true)], 64)) : __props.hasArea && areaPath.value ? (openBlock(), createElementBlock("path", {
|
|
245
245
|
key: 1,
|
|
246
246
|
d: areaPath.value,
|
|
247
247
|
fill: `url(#${unref(gradientAreaId)})`,
|
|
248
|
-
class: "transition-[d]"
|
|
248
|
+
class: "motion-safe:transition-[d]"
|
|
249
249
|
}, null, 8, _hoisted_6)) : createCommentVNode("", true),
|
|
250
250
|
linePath.value ? (openBlock(), createElementBlock("path", {
|
|
251
251
|
key: 2,
|
|
@@ -256,7 +256,7 @@ var WChartLine_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
256
256
|
stroke: "white",
|
|
257
257
|
"stroke-linejoin": "round",
|
|
258
258
|
"stroke-linecap": "round",
|
|
259
|
-
class: "transition-[d]"
|
|
259
|
+
class: "motion-safe:transition-[d]"
|
|
260
260
|
}, null, 8, _hoisted_7)) : createCommentVNode("", true),
|
|
261
261
|
_ctx.$slots.tooltip && hoveredData.value && tooltipRef.value?.isOpen ? (openBlock(), createElementBlock("g", _hoisted_8, [createElementVNode("circle", {
|
|
262
262
|
cx: hoveredData.value.x,
|
|
@@ -89,8 +89,8 @@ var WCheckbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
89
89
|
onKeypress: withKeys(withModifiers(toggle, ["stop", "prevent"]), ["enter"])
|
|
90
90
|
}, [
|
|
91
91
|
createVNode(Transition, {
|
|
92
|
-
"enter-active-class": "transition-[scale,opacity]",
|
|
93
|
-
"leave-active-class": "transition-[scale,opacity]",
|
|
92
|
+
"enter-active-class": "motion-safe:transition-[scale,opacity]",
|
|
93
|
+
"leave-active-class": "motion-safe:transition-[scale,opacity]",
|
|
94
94
|
"enter-from-class": __props.radio ? "opacity-0 scale-25!" : "opacity-0 scale-50!",
|
|
95
95
|
"leave-to-class": __props.radio ? "opacity-0 scale-25!" : "opacity-0 scale-50!",
|
|
96
96
|
css: !__props.lessTransitions
|
|
@@ -102,7 +102,7 @@ var WCheckbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
102
102
|
"rounded-[calc(0.25rem+1px)]": !__props.radio && !(__props.intermediate && __props.modelValue === null),
|
|
103
103
|
"tone-primary bg-tone-fill [.w-hover-checked:hover_&]:block!": !unref(isDisabled) && !unref(isSkeleton),
|
|
104
104
|
"bg-track": unref(isDisabled) || unref(isSkeleton),
|
|
105
|
-
"transition-[scale,opacity]": !__props.lessTransitions
|
|
105
|
+
"motion-safe:transition-[scale,opacity]": !__props.lessTransitions
|
|
106
106
|
}]) }, null, 2), [[vShow, __props.modelValue !== false && !__props.loading]])]),
|
|
107
107
|
_: 1
|
|
108
108
|
}, 8, [
|
|
@@ -25,7 +25,7 @@ var WCounter_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
return (_ctx, _cache) => {
|
|
28
|
-
return openBlock(), createElementBlock("div", { class: normalizeClass(["flex min-w-[1.25em] items-center justify-center rounded-full px-[0.375em] font-medium leading-tight", [{ "animate-shake": isShake.value }, unref(semanticTypeBgMap)[__props.semanticType]]]) }, toDisplayString(unref(numberCompactFormatter).format(__props.count)), 3);
|
|
28
|
+
return openBlock(), createElementBlock("div", { class: normalizeClass(["flex min-w-[1.25em] items-center justify-center rounded-full px-[0.375em] font-medium leading-tight", [{ "motion-safe:animate-shake": isShake.value }, unref(semanticTypeBgMap)[__props.semanticType]]]) }, toDisplayString(unref(numberCompactFormatter).format(__props.count)), 3);
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
});
|
|
@@ -121,8 +121,8 @@ var WDatePicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
|
|
|
121
121
|
"onClick:previous",
|
|
122
122
|
"onClick:next"
|
|
123
123
|
])]), createElementVNode("div", _hoisted_3, [createVNode(Transition, {
|
|
124
|
-
"enter-active-class": "transition-transform duration-250 w-full",
|
|
125
|
-
"leave-active-class": "transition-transform duration-250 w-full absolute top-0",
|
|
124
|
+
"enter-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full",
|
|
125
|
+
"leave-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full absolute top-0",
|
|
126
126
|
"enter-from-class": "translate-x-[calc(100%*var(--direction-factor))]",
|
|
127
127
|
"leave-to-class": "translate-x-[calc(100%*var(--direction-factor)*-1)]"
|
|
128
128
|
}, {
|
|
@@ -75,8 +75,8 @@ var WDatePickerSingle_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
75
75
|
"onClick:previous",
|
|
76
76
|
"onClick:next"
|
|
77
77
|
])]), createElementVNode("div", _hoisted_2, [createVNode(Transition, {
|
|
78
|
-
"enter-active-class": "transition-transform duration-250 w-full",
|
|
79
|
-
"leave-active-class": "transition-transform duration-250 w-full absolute top-0",
|
|
78
|
+
"enter-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full",
|
|
79
|
+
"leave-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full absolute top-0",
|
|
80
80
|
"enter-from-class": "translate-x-[calc(100%*var(--direction-factor))]",
|
|
81
81
|
"leave-to-class": "translate-x-[calc(100%*var(--direction-factor)*-1)]"
|
|
82
82
|
}, {
|
package/dist/components/DatePicker/components/CalendarToggle.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -19,8 +19,8 @@ var CalendarToggle_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
|
|
|
19
19
|
onClick: _cache[0] || (_cache[0] = ($event) => !__props.disabledPrevious && _ctx.$emit("click:previous"))
|
|
20
20
|
}, [createVNode(unref(IconArrow_default), { class: "-ml-1 rotate-90" })], 2),
|
|
21
21
|
createElementVNode("div", _hoisted_2, [createVNode(Transition, {
|
|
22
|
-
"enter-active-class": "transition-transform duration-250 w-full",
|
|
23
|
-
"leave-active-class": "transition-transform duration-250 w-full absolute top-0",
|
|
22
|
+
"enter-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full",
|
|
23
|
+
"leave-active-class": "motion-safe:transition-transform motion-safe:duration-250 w-full absolute top-0",
|
|
24
24
|
"enter-from-class": "translate-x-[calc(100%*var(--direction-factor))]",
|
|
25
25
|
"leave-to-class": "translate-x-[calc(100%*var(--direction-factor)*-1)]"
|
|
26
26
|
}, {
|
|
@@ -4,7 +4,7 @@ import { Transition, createBlock, createCommentVNode, createElementBlock, create
|
|
|
4
4
|
var _hoisted_1 = {
|
|
5
5
|
key: 0,
|
|
6
6
|
ref: "container",
|
|
7
|
-
class: "no-scrollbar snap-y snap-mandatory snap-always overflow-scroll overflow-y-auto overscroll-contain scroll-smooth"
|
|
7
|
+
class: "no-scrollbar snap-y snap-mandatory snap-always overflow-scroll overflow-y-auto overscroll-contain motion-safe:scroll-smooth"
|
|
8
8
|
};
|
|
9
9
|
var WDismissable_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
10
10
|
__name: "WDismissable",
|
|
@@ -2,7 +2,7 @@ import { KeepAlive, Transition, createBlock, createCommentVNode, createElementBl
|
|
|
2
2
|
// src/components/Expansion/WExpansion.vue?vue&type=script&setup=true&lang.ts
|
|
3
3
|
var _hoisted_1 = {
|
|
4
4
|
key: 0,
|
|
5
|
-
class: "duration-(--expansion-duration,200ms)"
|
|
5
|
+
class: "motion-safe:duration-(--expansion-duration,200ms)"
|
|
6
6
|
};
|
|
7
7
|
var _hoisted_2 = { class: "grid grid-cols-1 [overflow:inherit]" };
|
|
8
8
|
var WExpansion_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
@@ -21,10 +21,10 @@ var WExpansion_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
|
|
|
21
21
|
setup(__props) {
|
|
22
22
|
return (_ctx, _cache) => {
|
|
23
23
|
return openBlock(), createBlock(Transition, {
|
|
24
|
-
"enter-active-class": "transition-[grid-template-rows] overflow-y-hidden grid",
|
|
24
|
+
"enter-active-class": "motion-safe:transition-[grid-template-rows] overflow-y-hidden grid",
|
|
25
25
|
"enter-from-class": "grid-rows-[0fr]",
|
|
26
26
|
"enter-to-class": "grid-rows-[1fr]",
|
|
27
|
-
"leave-active-class": "transition-[grid-template-rows] overflow-y-hidden grid",
|
|
27
|
+
"leave-active-class": "motion-safe:transition-[grid-template-rows] overflow-y-hidden grid",
|
|
28
28
|
"leave-from-class": "grid-rows-[1fr]",
|
|
29
29
|
"leave-to-class": "grid-rows-[0fr]",
|
|
30
30
|
onBeforeEnter: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:visible", true)),
|
|
@@ -51,7 +51,7 @@ var WExpansionItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
|
|
|
51
51
|
default: withCtx(() => [__props.hasFlag ? (openBlock(), createElementBlock("div", _hoisted_1)) : createCommentVNode("", true)]),
|
|
52
52
|
_: 1
|
|
53
53
|
})], 2)
|
|
54
|
-
]), createElementVNode("div", _hoisted_2, [createVNode(unref(IconArrow_default), { class: normalizeClass(["text-accent square-[1.25em] transition-transform", { "rotate-180": __props.isOpen }]) }, null, 8, ["class"])])]),
|
|
54
|
+
]), createElementVNode("div", _hoisted_2, [createVNode(unref(IconArrow_default), { class: normalizeClass(["text-accent square-[1.25em] motion-safe:transition-transform", { "rotate-180": __props.isOpen }]) }, null, 8, ["class"])])]),
|
|
55
55
|
_: 1
|
|
56
56
|
}, 40, ["aria-expanded", "class"])), createVNode(WExpansion_default, {
|
|
57
57
|
"is-open": __props.isOpen,
|
package/dist/components/FilePicker/components/FilePickerSvg.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -10,7 +10,7 @@ var FilePickerSvg_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
10
10
|
stroke: "currentColor",
|
|
11
11
|
"stroke-linecap": "round",
|
|
12
12
|
"stroke-dasharray": "4px 8px",
|
|
13
|
-
"rect-class": __props.animate ? "animate-border-march" : void 0
|
|
13
|
+
"rect-class": __props.animate ? "motion-safe:animate-border-march" : void 0
|
|
14
14
|
}, null, 8, ["rect-class"]);
|
|
15
15
|
};
|
|
16
16
|
}
|
|
@@ -303,7 +303,7 @@ var InfiniteListPage_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
303
303
|
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(slotList.value, (slot, slotIndex) => {
|
|
304
304
|
return openBlock(), createElementBlock("div", {
|
|
305
305
|
key: slot.key,
|
|
306
|
-
class: "grid w-full transition-[grid-template-rows] duration-300"
|
|
306
|
+
class: "grid w-full motion-safe:transition-[grid-template-rows] motion-safe:duration-300"
|
|
307
307
|
}, [createElementVNode("div", _hoisted_4, [createVNode(InfiniteListPageItem_default, {
|
|
308
308
|
ref_for: true,
|
|
309
309
|
ref: (item) => setItemRef(slot.key, item)
|
|
@@ -714,7 +714,7 @@ var WInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
|
|
|
714
714
|
default: withCtx(() => [unref(asyncState).timeout.value ? (openBlock(), createElementBlock("div", _hoisted_8)) : createCommentVNode("", true)]),
|
|
715
715
|
_: 1
|
|
716
716
|
}), createVNode(Transition, {
|
|
717
|
-
"enter-active-class": "transition-[width] ease-linear rounded-sm duration-(--debounce-duration)",
|
|
717
|
+
"enter-active-class": "motion-safe:transition-[width] ease-linear rounded-sm motion-safe:duration-(--debounce-duration)",
|
|
718
718
|
"enter-from-class": "w-0",
|
|
719
719
|
"enter-to-class": "w-full",
|
|
720
720
|
"leave-active-class": "hidden"
|
|
@@ -243,7 +243,7 @@ var WInputSuggest_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
243
243
|
disabled: unref(isDisabled),
|
|
244
244
|
onClick: ($event) => isOpen.value ? toggleScope.unclickable === false ? close() : blur() : focus()
|
|
245
245
|
}, {
|
|
246
|
-
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-3 text-description transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
246
|
+
default: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-3 text-description motion-safe:transition-transform", { "rotate-180": isOpen.value }]) }, null, 8, ["class"])]),
|
|
247
247
|
_: 1
|
|
248
248
|
}, 8, [
|
|
249
249
|
"expanded",
|
|
@@ -62,7 +62,7 @@ var WListHeaderItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
62
62
|
"enter-from-class": "opacity-0",
|
|
63
63
|
"leave-to-class": "opacity-0"
|
|
64
64
|
}, {
|
|
65
|
-
default: withCtx(() => [index.value !== -1 ? (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(IconBack_default), { class: normalizeClass(["square-3 transition-transform", {
|
|
65
|
+
default: withCtx(() => [index.value !== -1 ? (openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(IconBack_default), { class: normalizeClass(["square-3 motion-safe:transition-transform", {
|
|
66
66
|
"rotate-90": __props.ordering[index.value]?.order === "ASC",
|
|
67
67
|
"-rotate-90": __props.ordering[index.value]?.order === "DESC"
|
|
68
68
|
}]) }, null, 8, ["class"]), __props.ordering.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_2, toDisplayString(index.value + 1), 1)) : createCommentVNode("", true)])) : createCommentVNode("", true)]),
|
package/dist/components/List/components/HeaderSortItem.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -45,7 +45,7 @@ var HeaderSortItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
|
|
|
45
45
|
}, {
|
|
46
46
|
default: withCtx(() => [index.value !== -1 ? (openBlock(), createBlock(unref(IconBack_default), {
|
|
47
47
|
key: 0,
|
|
48
|
-
class: normalizeClass(["square-4 transition-transform", {
|
|
48
|
+
class: normalizeClass(["square-4 motion-safe:transition-transform", {
|
|
49
49
|
"rotate-90": __props.ordering[index.value]?.order === "ASC",
|
|
50
50
|
"-rotate-90": __props.ordering[index.value]?.order === "DESC"
|
|
51
51
|
}])
|
package/dist/components/List/components/ListFilterChip.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -61,7 +61,7 @@ var ListFilterChip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
|
|
|
61
61
|
badge.value ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(badge.value), 1)) : createCommentVNode("", true),
|
|
62
62
|
!hasValue.value ? (openBlock(), createBlock(unref(IconArrow_default), {
|
|
63
63
|
key: 3,
|
|
64
|
-
class: normalizeClass(["square-[1em] text-description shrink-0 transition-transform", { "rotate-180": __props.isOpen }])
|
|
64
|
+
class: normalizeClass(["square-[1em] text-description shrink-0 motion-safe:transition-transform", { "rotate-180": __props.isOpen }])
|
|
65
65
|
}, null, 8, ["class"])) : createCommentVNode("", true)
|
|
66
66
|
], 10, _hoisted_1), isRemovable.value ? (openBlock(), createElementBlock("button", {
|
|
67
67
|
key: 0,
|
|
@@ -130,7 +130,7 @@ var ListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
130
130
|
}, [
|
|
131
131
|
__props.mobile ? (openBlock(), createElementBlock("div", {
|
|
132
132
|
key: 0,
|
|
133
|
-
class: normalizeClass(["tone-primary bg-tone-fill @sm:hidden pointer-events-none absolute left-0 top-0 h-full w-2 transition-[translate,opacity] duration-200", { "-translate-x-2 opacity-0": !__props.selected }])
|
|
133
|
+
class: normalizeClass(["tone-primary bg-tone-fill @sm:hidden pointer-events-none absolute left-0 top-0 h-full w-2 motion-safe:transition-[translate,opacity] motion-safe:duration-200", { "-translate-x-2 opacity-0": !__props.selected }])
|
|
134
134
|
}, null, 2)) : createCommentVNode("", true),
|
|
135
135
|
!__props.card ? (openBlock(), createElementBlock("div", {
|
|
136
136
|
key: 1,
|
|
@@ -128,8 +128,8 @@ var WModal_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
|
|
|
128
128
|
_: 1
|
|
129
129
|
}),
|
|
130
130
|
createVNode(TransitionGroup, {
|
|
131
|
-
"enter-active-class": "transition-all duration-300",
|
|
132
|
-
"leave-active-class": "transition-all duration-300",
|
|
131
|
+
"enter-active-class": "motion-safe:transition-all motion-safe:duration-300",
|
|
132
|
+
"leave-active-class": "motion-safe:transition-all motion-safe:duration-300",
|
|
133
133
|
"enter-from-class": "translate-y-8 opacity-0",
|
|
134
134
|
"leave-to-class": "-translate-y-5 opacity-0"
|
|
135
135
|
}, {
|
|
@@ -56,7 +56,7 @@ var WNavBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
56
56
|
}),
|
|
57
57
|
createElementVNode("nav", {
|
|
58
58
|
ref: "nav",
|
|
59
|
-
class: normalizeClass(["w-nav-bar fixed left-(--w-left-margin,0px) top-0 flex h-full flex-col overflow-hidden transition-[clip-path] duration-200 [clip-path:inset(-2rem)] print:hidden", [{ "xl-not:[clip-path:inset(-2rem_calc(100%+2rem)_-2rem_-2rem)]": !isOpen.value }, _ctx.$attrs.class]]),
|
|
59
|
+
class: normalizeClass(["w-nav-bar fixed left-(--w-left-margin,0px) top-0 flex h-full flex-col overflow-hidden motion-safe:transition-[clip-path] motion-safe:duration-200 [clip-path:inset(-2rem)] print:hidden", [{ "xl-not:[clip-path:inset(-2rem_calc(100%+2rem)_-2rem_-2rem)]": !isOpen.value }, _ctx.$attrs.class]]),
|
|
60
60
|
style: normalizeStyle({ zIndex: unref(30) })
|
|
61
61
|
}, [
|
|
62
62
|
_ctx.$slots.brand && __props.brandTo ? (openBlock(), createBlock(WRouterLink_default, {
|
|
@@ -79,8 +79,8 @@ var WNavItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
|
|
|
79
79
|
}, {
|
|
80
80
|
default: withCtx(() => [
|
|
81
81
|
createVNode(Transition, {
|
|
82
|
-
"enter-active-class": "transition-transform duration-200",
|
|
83
|
-
"leave-active-class": "transition-transform duration-200",
|
|
82
|
+
"enter-active-class": "motion-safe:transition-transform motion-safe:duration-200",
|
|
83
|
+
"leave-active-class": "motion-safe:transition-transform motion-safe:duration-200",
|
|
84
84
|
"enter-from-class": "-translate-x-1",
|
|
85
85
|
"leave-to-class": "-translate-x-1"
|
|
86
86
|
}, {
|
|
@@ -87,7 +87,7 @@ var WNavItemExpand_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ d
|
|
|
87
87
|
"param-fields": __props.paramFields,
|
|
88
88
|
hovered: unref(isDropdownOpen) && !hasActive.value
|
|
89
89
|
}), createSlots({
|
|
90
|
-
right: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-3 transition-transform", { "-rotate-90": !hasActive.value && !__props.even }]) }, null, 8, ["class"])]),
|
|
90
|
+
right: withCtx(() => [createVNode(unref(IconArrow_default), { class: normalizeClass(["square-3 motion-safe:transition-transform", { "-rotate-90": !hasActive.value && !__props.even }]) }, null, 8, ["class"])]),
|
|
91
91
|
_: 2
|
|
92
92
|
}, [_ctx.$slots.icon ? {
|
|
93
93
|
name: "icon",
|
|
@@ -5,10 +5,10 @@ var WNavItemTransition_vue_vue_type_script_setup_true_lang_default = /*@__PURE__
|
|
|
5
5
|
setup(__props) {
|
|
6
6
|
return (_ctx, _cache) => {
|
|
7
7
|
return openBlock(), createBlock(TransitionGroup, {
|
|
8
|
-
"enter-active-class": "transition-[grid-template-rows] overflow-hidden grid",
|
|
8
|
+
"enter-active-class": "motion-safe:transition-[grid-template-rows] overflow-hidden grid",
|
|
9
9
|
"enter-from-class": "grid-rows-[0fr]",
|
|
10
10
|
"enter-to-class": "grid-rows-[1fr]",
|
|
11
|
-
"leave-active-class": "transition-[grid-template-rows] overflow-hidden grid",
|
|
11
|
+
"leave-active-class": "motion-safe:transition-[grid-template-rows] overflow-hidden grid",
|
|
12
12
|
"leave-from-class": "grid-rows-[1fr]",
|
|
13
13
|
"leave-to-class": "grid-rows-[0fr]"
|
|
14
14
|
}, {
|
|
@@ -37,7 +37,7 @@ var WNotify_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
37
37
|
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(notifyCenterToastEntries), (item) => {
|
|
38
38
|
return openBlock(), createElementBlock("div", {
|
|
39
39
|
key: unref(getNotifyItemKey)(item),
|
|
40
|
-
class: normalizeClass(["grid transition-[translate,opacity,grid-template-rows] duration-300", isCenter.value ? "justify-center" : "justify-end"])
|
|
40
|
+
class: normalizeClass(["grid motion-safe:transition-[translate,opacity,grid-template-rows] motion-safe:duration-300", isCenter.value ? "justify-center" : "justify-end"])
|
|
41
41
|
}, [createElementVNode("div", _hoisted_1, [createVNode(NotifyCard_default, {
|
|
42
42
|
item,
|
|
43
43
|
"onClick:close": _cache[0] || (_cache[0] = (entry) => (entry.items ?? [entry]).forEach((value) => unref(hideToast)(value.id)))
|
|
@@ -80,7 +80,7 @@ var WNotifyCenter_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
80
80
|
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(notifyCenterActionEntries), (item) => {
|
|
81
81
|
return openBlock(), createElementBlock("div", {
|
|
82
82
|
key: unref(getNotifyItemKey)(item),
|
|
83
|
-
class: "grid transition-[transform,grid-template-rows] duration-300"
|
|
83
|
+
class: "grid motion-safe:transition-[transform,grid-template-rows] motion-safe:duration-300"
|
|
84
84
|
}, [createElementVNode("div", _hoisted_6, [createVNode(NotifyCard_default, {
|
|
85
85
|
item,
|
|
86
86
|
history: "",
|
|
@@ -110,7 +110,7 @@ var WNotifyCenter_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
110
110
|
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(notifyCenterActivityEntries), (item) => {
|
|
111
111
|
return openBlock(), createElementBlock("div", {
|
|
112
112
|
key: unref(getNotifyItemKey)(item),
|
|
113
|
-
class: "grid transition-[transform,grid-template-rows] duration-300"
|
|
113
|
+
class: "grid motion-safe:transition-[transform,grid-template-rows] motion-safe:duration-300"
|
|
114
114
|
}, [createElementVNode("div", _hoisted_8, [createVNode(NotifyCard_default, {
|
|
115
115
|
item,
|
|
116
116
|
history: "",
|
|
@@ -7,7 +7,7 @@ var WProgress_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
7
7
|
setup(__props) {
|
|
8
8
|
return (_ctx, _cache) => {
|
|
9
9
|
return openBlock(), createElementBlock("div", _hoisted_1, [createElementVNode("div", {
|
|
10
|
-
class: "tone-primary bg-tone-fill h-full transition-[width]",
|
|
10
|
+
class: "tone-primary bg-tone-fill h-full motion-safe:transition-[width]",
|
|
11
11
|
style: normalizeStyle({ width: __props.modelValue + "%" })
|
|
12
12
|
}, null, 4)]);
|
|
13
13
|
};
|
|
@@ -7,7 +7,7 @@ import { Fragment, computed, createCommentVNode, createElementBlock, createEleme
|
|
|
7
7
|
var _hoisted_1 = ["aria-valuenow", "aria-busy"];
|
|
8
8
|
var _hoisted_2 = {
|
|
9
9
|
key: 0,
|
|
10
|
-
class: "animate-ticker absolute inset-0 bg-linear-to-r from-transparent via-white/30 to-transparent [--tiker-duration:1.6s]"
|
|
10
|
+
class: "motion-safe:animate-ticker absolute inset-0 bg-linear-to-r from-transparent via-white/30 to-transparent [--tiker-duration:1.6s]"
|
|
11
11
|
};
|
|
12
12
|
var _hoisted_3 = { class: "text-accent relative flex h-full items-center justify-center" };
|
|
13
13
|
var _hoisted_4 = { class: "text-description relative flex h-full items-center justify-center gap-2 font-medium" };
|
|
@@ -30,16 +30,16 @@ var WProgressBar_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
30
30
|
"aria-busy": __props.modelValue === null || __props.modelValue < 1
|
|
31
31
|
}, [__props.modelValue !== null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
32
32
|
createElementVNode("div", {
|
|
33
|
-
class: normalizeClass(["absolute inset-y-0 left-0 overflow-hidden rounded-xl transition-[width] duration-500 ease-out", unref(progressBarClass)[__props.semanticType]]),
|
|
33
|
+
class: normalizeClass(["absolute inset-y-0 left-0 overflow-hidden rounded-xl motion-safe:transition-[width] motion-safe:duration-500 ease-out", unref(progressBarClass)[__props.semanticType]]),
|
|
34
34
|
style: normalizeStyle({ width: percent.value })
|
|
35
35
|
}, [__props.modelValue < 1 ? (openBlock(), createElementBlock("div", _hoisted_2)) : createCommentVNode("", true)], 6),
|
|
36
36
|
createElementVNode("div", _hoisted_3, toDisplayString(percent.value), 1),
|
|
37
37
|
createElementVNode("div", {
|
|
38
38
|
"aria-hidden": "true",
|
|
39
|
-
class: normalizeClass(["absolute inset-0 flex items-center justify-center transition-[clip-path] duration-500 ease-out", unref(progressBarTextClass)[__props.semanticType]]),
|
|
39
|
+
class: normalizeClass(["absolute inset-0 flex items-center justify-center motion-safe:transition-[clip-path] motion-safe:duration-500 ease-out", unref(progressBarTextClass)[__props.semanticType]]),
|
|
40
40
|
style: normalizeStyle({ clipPath: `inset(0 calc(100% - ${percent.value}) 0 0)` })
|
|
41
41
|
}, toDisplayString(percent.value), 7)
|
|
42
|
-
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createElementVNode("div", { class: normalizeClass(["animate-ticker absolute inset-0 bg-linear-to-r from-transparent to-transparent [--tiker-duration:1.4s]", unref(progressBarIndeterminateClass)[__props.semanticType]]) }, null, 2), createElementVNode("div", _hoisted_4, [createVNode(WSpinner_default, { class: "square-4" }), _cache[0] || (_cache[0] = createElementVNode("span", null, "In progress", -1))])], 64))], 8, _hoisted_1);
|
|
42
|
+
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createElementVNode("div", { class: normalizeClass(["motion-safe:animate-ticker absolute inset-0 bg-linear-to-r from-transparent to-transparent [--tiker-duration:1.4s]", unref(progressBarIndeterminateClass)[__props.semanticType]]) }, null, 2), createElementVNode("div", _hoisted_4, [createVNode(WSpinner_default, { class: "square-4" }), _cache[0] || (_cache[0] = createElementVNode("span", null, "In progress", -1))])], 64))], 8, _hoisted_1);
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
});
|
|
@@ -3,7 +3,7 @@ import { createElementBlock, createElementVNode, defineComponent, normalizeClass
|
|
|
3
3
|
var _hoisted_1 = ["aria-valuenow", "aria-busy"];
|
|
4
4
|
var _hoisted_2 = {
|
|
5
5
|
key: 0,
|
|
6
|
-
class: "animate-ticker tone-primary via-tone/60 absolute inset-0 bg-linear-to-r from-transparent to-transparent [--tiker-duration:1.4s]"
|
|
6
|
+
class: "motion-safe:animate-ticker tone-primary via-tone/60 absolute inset-0 bg-linear-to-r from-transparent to-transparent [--tiker-duration:1.4s]"
|
|
7
7
|
};
|
|
8
8
|
var WProgressStriped_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
9
9
|
__name: "WProgressStriped",
|
|
@@ -19,9 +19,9 @@ var WProgressStriped_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
19
19
|
"aria-busy": __props.modelValue < 100
|
|
20
20
|
}, [__props.modelValue <= 0 ? (openBlock(), createElementBlock("div", _hoisted_2)) : (openBlock(), createElementBlock("div", {
|
|
21
21
|
key: 1,
|
|
22
|
-
class: "from-primary-dark to-primary relative h-full overflow-hidden rounded-full bg-linear-to-r transition-[width] duration-500 ease-out",
|
|
22
|
+
class: "from-primary-dark to-primary relative h-full overflow-hidden rounded-full bg-linear-to-r motion-safe:transition-[width] motion-safe:duration-500 ease-out",
|
|
23
23
|
style: normalizeStyle({ width: Math.min(__props.modelValue, 100) + "%" })
|
|
24
|
-
}, [createElementVNode("div", { class: normalizeClass(["absolute inset-0", __props.modelValue < 100 ? "animate-ticker bg-linear-to-r from-transparent via-white/40 to-transparent [--tiker-duration:1.6s]" : "bg-default/30 animate-pulse"]) }, null, 2)], 4))], 10, _hoisted_1);
|
|
24
|
+
}, [createElementVNode("div", { class: normalizeClass(["absolute inset-0", __props.modelValue < 100 ? "motion-safe:animate-ticker bg-linear-to-r from-transparent via-white/40 to-transparent [--tiker-duration:1.6s]" : "bg-default/30 motion-safe:animate-pulse"]) }, null, 2)], 4))], 10, _hoisted_1);
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
});
|
|
@@ -15,7 +15,7 @@ var WSkeleton_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
15
15
|
});
|
|
16
16
|
return (_ctx, _cache) => {
|
|
17
17
|
return openBlock(), createElementBlock("div", {
|
|
18
|
-
class: "tone-primary bg-tone-soft w-skeleton w-skeleton-opacity-50 dark:w-skeleton-opacity-5 before:animate-ticker w-option-has-bg",
|
|
18
|
+
class: "tone-primary bg-tone-soft w-skeleton w-skeleton-opacity-50 dark:w-skeleton-opacity-5 motion-safe:before:animate-ticker w-option-has-bg",
|
|
19
19
|
style: normalizeStyle({ "--skeleton-width-internal": skeletonWidth.value + "%" })
|
|
20
20
|
}, [renderSlot(_ctx.$slots, "default")], 4);
|
|
21
21
|
};
|
|
@@ -102,7 +102,7 @@ var WSlider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
102
102
|
"bg-track-strong": __props.disabled
|
|
103
103
|
}]),
|
|
104
104
|
style: normalizeStyle({ width: `${rangeScale(cursor.value ?? __props.modelValue) * 100}%` })
|
|
105
|
-
}, [createElementVNode("div", { class: normalizeClass(["square-4 relative right-0 -mr-2 rounded-full bg-inherit transition-transform", {
|
|
105
|
+
}, [createElementVNode("div", { class: normalizeClass(["square-4 relative right-0 -mr-2 rounded-full bg-inherit motion-safe:transition-transform", {
|
|
106
106
|
"scale-180": isMoveStarted.value,
|
|
107
107
|
"hover:scale-200": !__props.readonly && !isMoveStarted.value
|
|
108
108
|
}]) }, null, 2)], 6)], 512), createVNode(Transition, {
|
|
@@ -124,11 +124,11 @@ var WSliderRange_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
|
|
|
124
124
|
})
|
|
125
125
|
}, [
|
|
126
126
|
!__props.disabled ? (openBlock(), createElementBlock("div", _hoisted_3)) : createCommentVNode("", true),
|
|
127
|
-
createElementVNode("div", { class: normalizeClass(["square-4 absolute left-0 -ml-2 rounded-full bg-(--w-slider-from,var(--color-primary)) transition-transform", {
|
|
127
|
+
createElementVNode("div", { class: normalizeClass(["square-4 absolute left-0 -ml-2 rounded-full bg-(--w-slider-from,var(--color-primary)) motion-safe:transition-transform", {
|
|
128
128
|
"scale-180": isCursorFrom.value === true,
|
|
129
129
|
"hover:scale-200": !__props.readonly && isCursorFrom.value === null
|
|
130
130
|
}]) }, null, 2),
|
|
131
|
-
createElementVNode("div", { class: normalizeClass(["square-4 absolute right-0 -mr-2 rounded-full bg-(--w-slider-to,var(--color-primary)) transition-transform", {
|
|
131
|
+
createElementVNode("div", { class: normalizeClass(["square-4 absolute right-0 -mr-2 rounded-full bg-(--w-slider-to,var(--color-primary)) motion-safe:transition-transform", {
|
|
132
132
|
"scale-180": isCursorFrom.value === false,
|
|
133
133
|
"hover:scale-200": !__props.readonly && isCursorFrom.value === null
|
|
134
134
|
}]) }, null, 2)
|
|
@@ -6,7 +6,7 @@ var _hoisted_1 = {
|
|
|
6
6
|
width: "20",
|
|
7
7
|
height: "20",
|
|
8
8
|
viewBox: "0 0 24 24",
|
|
9
|
-
class: "animate-spin"
|
|
9
|
+
class: "motion-safe:animate-spin"
|
|
10
10
|
};
|
|
11
11
|
function _sfc_render(_ctx, _cache) {
|
|
12
12
|
return openBlock(), createElementBlock("svg", _hoisted_1, [..._cache[0] || (_cache[0] = [createElementVNode("circle", {
|
|
@@ -484,7 +484,7 @@ var WTabs_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
|
|
|
484
484
|
]);
|
|
485
485
|
}), 128)) : defaultSlots.value.some((slot) => slot.children?.default) ? (openBlock(), createElementBlock("div", {
|
|
486
486
|
key: 1,
|
|
487
|
-
class: normalizeClass(["relative h-full transition-[min-height] duration-300", {
|
|
487
|
+
class: normalizeClass(["relative h-full motion-safe:transition-[min-height] motion-safe:duration-300", {
|
|
488
488
|
"[overflow-anchor:none]": isSwitching.value,
|
|
489
489
|
"surface-section-joined": !__props.side && __props.section && !joined,
|
|
490
490
|
"sm-not:snap-start sm-not:px-(--w-frame-padding,var(--inner-margin))": __props.side
|
|
@@ -494,8 +494,8 @@ var WTabs_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
|
|
|
494
494
|
"--direction-factor": isDirect.value ? "1" : "-1"
|
|
495
495
|
})
|
|
496
496
|
}, [createVNode(TransitionGroup, {
|
|
497
|
-
"enter-active-class": "transition-[translate,opacity] duration-250 w-full [overflow-anchor:none]",
|
|
498
|
-
"leave-active-class": "transition-[translate,opacity] duration-250 w-full absolute top-0 [overflow-anchor:none]",
|
|
497
|
+
"enter-active-class": "motion-safe:transition-[translate,opacity] motion-safe:duration-250 w-full [overflow-anchor:none]",
|
|
498
|
+
"leave-active-class": "motion-safe:transition-[translate,opacity] motion-safe:duration-250 w-full absolute top-0 [overflow-anchor:none]",
|
|
499
499
|
"enter-from-class": __props.lessTransitions || __props.side || unref(hasScrollbar) ? "opacity-0" : "opacity-0 translate-x-[calc((100%+var(--inner-margin))*var(--direction-factor))]",
|
|
500
500
|
"leave-to-class": __props.lessTransitions || __props.side || unref(hasScrollbar) ? "opacity-0 absolute" : "opacity-0 translate-x-[calc((100%+var(--inner-margin))*var(--direction-factor)*-1)]",
|
|
501
501
|
onAfterEnter: _cache[1] || (_cache[1] = ($event) => isSwitching.value = false),
|
|
@@ -29,7 +29,7 @@ var WTextOverflow_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
29
29
|
onMouseenter: updateOverflow
|
|
30
30
|
}, [createElementVNode("span", _hoisted_1, [renderSlot(_ctx.$slots, "default")]), createElementVNode("div", {
|
|
31
31
|
ref: "element",
|
|
32
|
-
class: normalizeClass(["absolute inset-y-0 left-0", { "delay-300 group-hover/overflow:translate-x-(--text-overflow,0px) group-hover/overflow:transition-transform group-hover/overflow:duration-(--text-overflow-duration,150ms) group-hover/overflow:ease-linear": overflow.value }]),
|
|
32
|
+
class: normalizeClass(["absolute inset-y-0 left-0", { "delay-300 group-hover/overflow:translate-x-(--text-overflow,0px) motion-safe:group-hover/overflow:transition-transform motion-safe:group-hover/overflow:duration-(--text-overflow-duration,150ms) group-hover/overflow:ease-linear": overflow.value }]),
|
|
33
33
|
style: normalizeStyle(overflow.value ? {
|
|
34
34
|
"--text-overflow": `-${overflow.value}px`,
|
|
35
35
|
"--text-overflow-duration": `${overflow.value * 30}ms`
|
|
@@ -111,7 +111,7 @@ var WToggle_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
|
|
|
111
111
|
}, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)])], 2)) : createCommentVNode("", true), createElementVNode("div", _hoisted_2, [createElementVNode("div", { class: normalizeClass(["width-[calc(var(--w-input-height)+0.5rem)] p-0.75 h-full rounded-full bg-size-[200%_auto] bg-right", {
|
|
112
112
|
"bg-track": !value.value || __props.loading,
|
|
113
113
|
[unref(semanticTypeBackgroundMap)[unref(SemanticType).PRIMARY]]: value.value && !__props.loading
|
|
114
|
-
}]) }, [createElementVNode("div", _hoisted_3, [createElementVNode("div", { class: normalizeClass(["tone-primary text-tone scheme-light absolute z-10 flex aspect-square h-full items-center justify-center rounded-full bg-(--w-toggle-caret,#ffffff) shadow-md transition-[right]", {
|
|
114
|
+
}]) }, [createElementVNode("div", _hoisted_3, [createElementVNode("div", { class: normalizeClass(["tone-primary text-tone scheme-light absolute z-10 flex aspect-square h-full items-center justify-center rounded-full bg-(--w-toggle-caret,#ffffff) shadow-md motion-safe:transition-[right]", {
|
|
115
115
|
"right-[calc(100%-(var(--w-input-height)-0.75rem))]": value.value === false,
|
|
116
116
|
"right-[calc(50%-(var(--w-input-height)-0.75rem)/2)]": value.value === null,
|
|
117
117
|
"right-0": value.value === true,
|
package/docs/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# eco-vue-js
|
|
2
2
|
|
|
3
|
-
> Vue 3 UI kit with Tailwind v4 — components, utilities, icons and recipes. These are the docs of version 0.
|
|
3
|
+
> Vue 3 UI kit with Tailwind v4 — components, utilities, icons and recipes. These are the docs of version 0.28.0, the one installed next to them. Start with Getting started and Conventions; each component page lists its props, events and slots with examples.
|
|
4
4
|
|
|
5
5
|
Release notes, for what changed between versions: https://github.com/rsmple/eco-vue-js/releases. The docs site, with live demos: https://rsmple.github.io/eco-vue-js/
|
|
6
6
|
|
package/eslint/plugin.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import motionCss from './processors/motion-css.js'
|
|
1
2
|
import recommended from './recommended.js'
|
|
2
3
|
import modalDeclaration from './rules/modal-declaration.js'
|
|
3
4
|
import modalImportAsync from './rules/modal-import-async.js'
|
|
4
5
|
import modalImport from './rules/modal-import.js'
|
|
6
|
+
import motionSafe from './rules/motion-safe.js'
|
|
5
7
|
import uiKitImports from './rules/ui-kit-imports.js'
|
|
6
8
|
|
|
7
9
|
const plugin = {
|
|
@@ -9,9 +11,14 @@ const plugin = {
|
|
|
9
11
|
'modal-declaration': modalDeclaration,
|
|
10
12
|
'modal-import-async': modalImportAsync,
|
|
11
13
|
'modal-import': modalImport,
|
|
14
|
+
'motion-safe': motionSafe,
|
|
12
15
|
'ui-kit-imports': uiKitImports,
|
|
13
16
|
},
|
|
14
17
|
|
|
18
|
+
processors: {
|
|
19
|
+
'motion-css': motionCss(),
|
|
20
|
+
},
|
|
21
|
+
|
|
15
22
|
configs: {},
|
|
16
23
|
}
|
|
17
24
|
|
|
@@ -41,10 +48,33 @@ const customRules = {
|
|
|
41
48
|
},
|
|
42
49
|
}
|
|
43
50
|
|
|
51
|
+
const motionRules = (config = {}) => [
|
|
52
|
+
{
|
|
53
|
+
name: 'custom-rules/motion',
|
|
54
|
+
files: config.astro ? ['**/*.{ts,js,vue,astro}'] : ['**/*.{ts,js,vue}'],
|
|
55
|
+
plugins: {
|
|
56
|
+
'custom-rules': plugin,
|
|
57
|
+
},
|
|
58
|
+
rules: {
|
|
59
|
+
'custom-rules/motion-safe': ['warn'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'custom-rules/motion-css',
|
|
64
|
+
files: ['**/*.css'],
|
|
65
|
+
plugins: {
|
|
66
|
+
'custom-rules': plugin,
|
|
67
|
+
},
|
|
68
|
+
processor: 'custom-rules/motion-css',
|
|
69
|
+
},
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
plugin.configs.motion = motionRules
|
|
73
|
+
|
|
44
74
|
plugin.configs.recommended = (config = {}) => [
|
|
45
75
|
...recommended(config),
|
|
46
76
|
|
|
47
|
-
...config.noCustom ? [] : [customRules],
|
|
77
|
+
...config.noCustom ? [] : [customRules, ...motionRules(config)],
|
|
48
78
|
]
|
|
49
79
|
|
|
50
80
|
export default plugin
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {checkCss} from '../rules/motion/css.js'
|
|
2
|
+
|
|
3
|
+
const RULE_ID = 'custom-rules/motion-safe'
|
|
4
|
+
const MESSAGE = 'runs under reduced motion. Put it inside `@media (prefers-reduced-motion: no-preference)` or `@variant motion-safe`; in `@apply`, prefix the class with `motion-safe:`.'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Checks `.css` files for motion outside a reduced-motion query. It hands ESLint no code blocks, so no
|
|
8
|
+
* other rule runs on CSS: rules a consumer configures without `files` would otherwise crash on it.
|
|
9
|
+
*/
|
|
10
|
+
export default ({severity = 1, allow = []} = {}) => {
|
|
11
|
+
const pending = new Map()
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
meta: {name: 'motion-css'},
|
|
15
|
+
|
|
16
|
+
preprocess(text, filename) {
|
|
17
|
+
const messages = []
|
|
18
|
+
|
|
19
|
+
checkCss(text, {ruleId: RULE_ID, allow}, ({start, end}, token) => {
|
|
20
|
+
messages.push({
|
|
21
|
+
ruleId: RULE_ID,
|
|
22
|
+
severity,
|
|
23
|
+
message: `\`${ token }\` ${ MESSAGE }`,
|
|
24
|
+
line: start.line,
|
|
25
|
+
column: start.column + 1,
|
|
26
|
+
endLine: end.line,
|
|
27
|
+
endColumn: end.column + 1,
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
pending.set(filename, messages)
|
|
32
|
+
|
|
33
|
+
return []
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
postprocess(_, filename) {
|
|
37
|
+
const messages = pending.get(filename) ?? []
|
|
38
|
+
pending.delete(filename)
|
|
39
|
+
return messages
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const MOTION = /^(?:transition(?:-(?:all|colors|opacity|shadow|transform|\[.+\]|\(.+\)))?|animate-(?!none$)[\w-[\]().,%/]+|scroll-smooth)$/
|
|
2
|
+
// Class lists never hold sentence punctuation; UI copy such as "Status transition failed." does.
|
|
3
|
+
const PROSE = /[`;?]|[.,:](?:\s|$)/
|
|
4
|
+
const DURATION = /^duration-(?!0$|initial$)(?:\d+|\[.+\]|\(.+\))$/
|
|
5
|
+
|
|
6
|
+
// Fading or recolouring is not motion, so it may still play when the OS asks for reduced motion.
|
|
7
|
+
export const FADE_UTILITIES = ['transition-opacity', 'transition-colors', 'transition-shadow']
|
|
8
|
+
export const FADE_PROPERTIES = [
|
|
9
|
+
'opacity',
|
|
10
|
+
'color',
|
|
11
|
+
'background-color',
|
|
12
|
+
'border-color',
|
|
13
|
+
'outline-color',
|
|
14
|
+
'text-decoration-color',
|
|
15
|
+
'fill',
|
|
16
|
+
'stroke',
|
|
17
|
+
'box-shadow',
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const isFade = utility => {
|
|
21
|
+
if (FADE_UTILITIES.includes(utility)) return true
|
|
22
|
+
|
|
23
|
+
const properties = utility.match(/^transition-\[(.+)\]$/)?.[1].split(',')
|
|
24
|
+
|
|
25
|
+
return !!properties && properties.every(property => FADE_PROPERTIES.includes(property.trim()))
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const splitVariants = token => {
|
|
29
|
+
const parts = []
|
|
30
|
+
let depth = 0
|
|
31
|
+
let start = 0
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < token.length; i++) {
|
|
34
|
+
const char = token[i]
|
|
35
|
+
if (char === '[' || char === '(') depth++
|
|
36
|
+
else if (char === ']' || char === ')') depth--
|
|
37
|
+
else if (char === ':' && depth === 0) {
|
|
38
|
+
parts.push(token.slice(start, i))
|
|
39
|
+
start = i + 1
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
parts.push(token.slice(start))
|
|
44
|
+
|
|
45
|
+
return parts
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns `{token, duration}` for each class that would still animate under reduced motion. `duration` marks a
|
|
50
|
+
* `duration-*` class with no ungated transition property beside it: `transition-property` defaults to `all`, so on
|
|
51
|
+
* its own it transitions every property.
|
|
52
|
+
*/
|
|
53
|
+
export const findUngated = (value, allow) => {
|
|
54
|
+
if (PROSE.test(value)) return []
|
|
55
|
+
|
|
56
|
+
const tokens = value.split(/\s+/).filter(Boolean).map(token => {
|
|
57
|
+
const parts = splitVariants(token)
|
|
58
|
+
return {token, utility: parts.pop().replace(/^!|!$/g, ''), gated: parts.includes('motion-safe')}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
if (tokens.some(({token}) => splitVariants(token).includes('motion-reduce'))) return []
|
|
62
|
+
|
|
63
|
+
const hasStillProperty = tokens.some(({utility, gated}) => !gated && (utility === 'transition-none' || isFade(utility)))
|
|
64
|
+
const found = []
|
|
65
|
+
|
|
66
|
+
for (const {token, utility, gated} of tokens) {
|
|
67
|
+
if (gated || allow.includes(utility)) continue
|
|
68
|
+
|
|
69
|
+
if (MOTION.test(utility) && !isFade(utility)) found.push({token, duration: false})
|
|
70
|
+
else if (DURATION.test(utility) && !hasStillProperty) found.push({token, duration: true})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return found
|
|
74
|
+
}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {fork} from '@eslint/css-tree'
|
|
2
|
+
import {tailwind4} from 'tailwind-csstree'
|
|
3
|
+
|
|
4
|
+
import {FADE_PROPERTIES, findUngated} from './classes.js'
|
|
5
|
+
|
|
6
|
+
const {parse, generate} = fork(tailwind4)
|
|
7
|
+
|
|
8
|
+
const GATES = [
|
|
9
|
+
/prefers-reduced-motion:\s*(?:no-preference|reduce)/,
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
const isGate = atrule => {
|
|
13
|
+
const name = atrule.name.toLowerCase()
|
|
14
|
+
const prelude = atrule.prelude ? generate(atrule.prelude) : ''
|
|
15
|
+
|
|
16
|
+
if (name === 'media') return GATES.some(gate => gate.test(prelude))
|
|
17
|
+
if (name === 'variant') return /^motion-(?:safe|reduce)$/.test(prelude.trim())
|
|
18
|
+
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const unprefixed = property => property.toLowerCase().replace(/^-(?:webkit|moz|ms|o)-/, '')
|
|
23
|
+
|
|
24
|
+
const splitTopLevel = value => {
|
|
25
|
+
const parts = []
|
|
26
|
+
let depth = 0
|
|
27
|
+
let start = 0
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < value.length; i++) {
|
|
30
|
+
const char = value[i]
|
|
31
|
+
if (char === '(') depth++
|
|
32
|
+
else if (char === ')') depth--
|
|
33
|
+
else if (char === ',' && depth === 0) {
|
|
34
|
+
parts.push(value.slice(start, i).trim())
|
|
35
|
+
start = i + 1
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
parts.push(value.slice(start).trim())
|
|
40
|
+
|
|
41
|
+
return parts.filter(Boolean)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const RESET = /^(?:none|initial|unset|revert|revert-layer)$/i
|
|
45
|
+
const ZERO = /^(?:0|0?\.0+|0+)(?:m?s)?$/
|
|
46
|
+
|
|
47
|
+
const transitionedProperties = (property, value) => {
|
|
48
|
+
if (property === 'transition-property') return splitTopLevel(value)
|
|
49
|
+
|
|
50
|
+
return splitTopLevel(value).map(item => {
|
|
51
|
+
const words = item.split(/\s+/).filter(word => !/^[\d.]/.test(word) && !/\(/.test(word))
|
|
52
|
+
return words.find(word => !/^(?:ease|ease-in|ease-out|ease-in-out|linear|step-start|step-end|normal|allow-discrete)$/i.test(word)) ?? 'all'
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Walks a parsed stylesheet and reports motion that is not inside a reduced-motion query.
|
|
58
|
+
* `report(node, token)` gets the offending declaration or `@apply` rule.
|
|
59
|
+
*/
|
|
60
|
+
export const checkStylesheet = (stylesheet, report, allow = []) => {
|
|
61
|
+
const checkDeclaration = (declaration, siblings) => {
|
|
62
|
+
const property = unprefixed(declaration.property)
|
|
63
|
+
const value = generate(declaration.value).trim()
|
|
64
|
+
|
|
65
|
+
if (property === 'scroll-behavior') {
|
|
66
|
+
if (value.toLowerCase() === 'smooth') report(declaration, 'scroll-behavior: smooth')
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (property === 'animation' || property === 'animation-name') {
|
|
71
|
+
if (!RESET.test(value)) report(declaration, `${ declaration.property }: ${ value }`)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (property === 'transition' || property === 'transition-property') {
|
|
76
|
+
if (RESET.test(value)) return
|
|
77
|
+
|
|
78
|
+
const properties = transitionedProperties(property, value).map(item => item.toLowerCase())
|
|
79
|
+
if (properties.every(item => FADE_PROPERTIES.includes(item))) return
|
|
80
|
+
|
|
81
|
+
report(declaration, `${ declaration.property }: ${ value }`)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (property === 'transition-duration') {
|
|
86
|
+
if (splitTopLevel(value).every(item => ZERO.test(item))) return
|
|
87
|
+
if (siblings.some(item => ['transition', 'transition-property'].includes(unprefixed(item.property)))) return
|
|
88
|
+
|
|
89
|
+
report(declaration, `${ declaration.property }: ${ value } (transitions all properties)`)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const visitChildren = (list, gated) => {
|
|
94
|
+
const nodes = Array.isArray(list) ? list : list?.toArray?.() ?? []
|
|
95
|
+
const declarations = nodes.filter(node => node.type === 'Declaration')
|
|
96
|
+
|
|
97
|
+
for (const node of nodes) {
|
|
98
|
+
if (node.type === 'Declaration') {
|
|
99
|
+
if (!gated) checkDeclaration(node, declarations)
|
|
100
|
+
} else {
|
|
101
|
+
visit(node, gated)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const visit = (node, gated) => {
|
|
107
|
+
switch (node.type) {
|
|
108
|
+
case 'StyleSheet':
|
|
109
|
+
case 'Block':
|
|
110
|
+
visitChildren(node.children, gated)
|
|
111
|
+
break
|
|
112
|
+
case 'Rule':
|
|
113
|
+
visit(node.block, gated)
|
|
114
|
+
break
|
|
115
|
+
case 'Atrule': {
|
|
116
|
+
const name = node.name.toLowerCase()
|
|
117
|
+
|
|
118
|
+
if (name === 'keyframes' || name.endsWith('-keyframes')) return
|
|
119
|
+
|
|
120
|
+
if (name === 'apply') {
|
|
121
|
+
if (gated || !node.prelude) return
|
|
122
|
+
for (const {token, duration} of findUngated(generate(node.prelude), allow)) {
|
|
123
|
+
report(node, duration ? `${ token } (transitions all properties)` : token)
|
|
124
|
+
}
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (node.block) visit(node.block, gated || isGate(node))
|
|
129
|
+
break
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
visit(stylesheet, false)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const STYLE_BLOCK = /<style\b([^>]*)>([\s\S]*?)<\/style\s*>/gi
|
|
138
|
+
const SKIPPED_LANG = /\blang\s*=\s*["']?(?:scss|sass|less|stylus|styl)\b/i
|
|
139
|
+
const DISABLE = /eslint-disable(-next-line|-line)?(?:\s+([^*]+?))?\s*$/
|
|
140
|
+
|
|
141
|
+
const isDisabledBy = (comment, ruleId) => {
|
|
142
|
+
const match = comment.match(DISABLE)
|
|
143
|
+
if (!match) return null
|
|
144
|
+
const rules = match[2]?.split(',').map(item => item.trim()).filter(Boolean)
|
|
145
|
+
if (rules?.length && !rules.includes(ruleId)) return null
|
|
146
|
+
return match[1] ?? ''
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Checks CSS text that starts at `startLine`/`startColumn` (1-based line, 0-based column) of its file.
|
|
151
|
+
* `/* eslint-disable *\/`, `/* eslint-disable-line <rule> *\/` and `/* eslint-disable-next-line <rule> *\/` work inside it.
|
|
152
|
+
*/
|
|
153
|
+
export const checkCss = (css, {startLine = 1, startColumn = 0, ruleId, allow = []}, report) => {
|
|
154
|
+
const disabledLines = new Set()
|
|
155
|
+
let disabledAll = false
|
|
156
|
+
|
|
157
|
+
const stylesheet = parse(css, {
|
|
158
|
+
positions: true,
|
|
159
|
+
onParseError: () => {},
|
|
160
|
+
onComment: (value, loc) => {
|
|
161
|
+
const kind = isDisabledBy(value.trim(), ruleId)
|
|
162
|
+
if (kind === null) return
|
|
163
|
+
if (kind === '') disabledAll = true
|
|
164
|
+
else if (kind === '-line') disabledLines.add(loc.start.line)
|
|
165
|
+
else disabledLines.add(loc.end.line + 1)
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
if (disabledAll) return
|
|
170
|
+
|
|
171
|
+
checkStylesheet(stylesheet, (node, token) => {
|
|
172
|
+
const {start, end} = node.loc
|
|
173
|
+
if (disabledLines.has(start.line)) return
|
|
174
|
+
|
|
175
|
+
const toLoc = point => ({
|
|
176
|
+
line: startLine + point.line - 1,
|
|
177
|
+
column: point.line === 1 ? startColumn + point.column - 1 : point.column - 1,
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
report({start: toLoc(start), end: toLoc(end)}, token)
|
|
181
|
+
}, allow)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Finds `<style>` blocks in a Vue or Astro file and checks each like a CSS file.
|
|
186
|
+
*/
|
|
187
|
+
export const checkStyleBlocks = (text, options, report) => {
|
|
188
|
+
for (const match of text.matchAll(STYLE_BLOCK)) {
|
|
189
|
+
if (SKIPPED_LANG.test(match[1])) continue
|
|
190
|
+
|
|
191
|
+
const offset = match.index + match[0].indexOf('>') + 1
|
|
192
|
+
const before = text.slice(0, offset).split('\n')
|
|
193
|
+
|
|
194
|
+
checkCss(match[2], {...options, startLine: before.length, startColumn: before.at(-1).length}, report)
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import {findUngated} from './motion/classes.js'
|
|
2
|
+
import {checkStyleBlocks} from './motion/css.js'
|
|
3
|
+
|
|
4
|
+
const CLASS_ATTRIBUTE = /^(?:class|className|class:list)$|-class$|Class$/
|
|
5
|
+
|
|
6
|
+
const attributeName = node => {
|
|
7
|
+
const name = node.name
|
|
8
|
+
if (!name) return null
|
|
9
|
+
if (name.type === 'JSXNamespacedName') return `${ name.namespace.name }:${ name.name.name }`
|
|
10
|
+
return name.name ?? null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default {
|
|
14
|
+
meta: {
|
|
15
|
+
type: 'suggestion',
|
|
16
|
+
docs: {
|
|
17
|
+
description: 'Require motion to be opted into with motion-safe: (classes) or a prefers-reduced-motion query (<style> blocks)',
|
|
18
|
+
recommended: true,
|
|
19
|
+
},
|
|
20
|
+
schema: [
|
|
21
|
+
{
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
allow: {
|
|
25
|
+
type: 'array',
|
|
26
|
+
items: {type: 'string'},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
messages: {
|
|
33
|
+
ungated: '`{{token}}` runs under reduced motion. Prefix it with `motion-safe:`, or add a `motion-reduce:` fallback in the same class string.',
|
|
34
|
+
ungatedDuration: '`{{token}}` has no transition property beside it, so under reduced motion it transitions every property. Prefix it with `motion-safe:` like the transition it belongs to.',
|
|
35
|
+
ungatedCss: '`{{token}}` runs under reduced motion. Put it inside `@media (prefers-reduced-motion: no-preference)` or `@variant motion-safe`; in `@apply`, prefix the class with `motion-safe:`.',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
create(context) {
|
|
40
|
+
const allow = context.options[0]?.allow ?? []
|
|
41
|
+
|
|
42
|
+
const check = (node, value) => {
|
|
43
|
+
if (typeof value !== 'string' || !value) return
|
|
44
|
+
|
|
45
|
+
for (const {token, duration} of findUngated(value, allow)) {
|
|
46
|
+
context.report({node, messageId: duration ? 'ungatedDuration' : 'ungated', data: {token}})
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const isModuleSource = node => {
|
|
51
|
+
const parent = node.parent
|
|
52
|
+
return parent && (
|
|
53
|
+
parent.type === 'ImportDeclaration'
|
|
54
|
+
|| parent.type === 'ExportNamedDeclaration'
|
|
55
|
+
|| parent.type === 'ExportAllDeclaration'
|
|
56
|
+
|| parent.type === 'ImportExpression'
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const scriptVisitor = {
|
|
61
|
+
Literal(node) {
|
|
62
|
+
if (isModuleSource(node)) return
|
|
63
|
+
if (node.parent?.type === 'JSXAttribute' && !CLASS_ATTRIBUTE.test(attributeName(node.parent) ?? '')) return
|
|
64
|
+
check(node, node.value)
|
|
65
|
+
},
|
|
66
|
+
TemplateElement(node) {
|
|
67
|
+
check(node, node.value.cooked)
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const templateVisitor = {
|
|
72
|
+
'VAttribute[directive=false]'(node) {
|
|
73
|
+
if (!CLASS_ATTRIBUTE.test(node.key.name)) return
|
|
74
|
+
check(node, node.value?.value)
|
|
75
|
+
},
|
|
76
|
+
Literal: scriptVisitor.Literal,
|
|
77
|
+
TemplateElement: scriptVisitor.TemplateElement,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (/\.(?:vue|astro)$/.test(context.filename)) {
|
|
81
|
+
scriptVisitor['Program:exit'] = () => {
|
|
82
|
+
checkStyleBlocks(context.sourceCode.text, {ruleId: context.id, allow}, (loc, token) => {
|
|
83
|
+
context.report({loc, messageId: 'ungatedCss', data: {token}})
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const parserServices = context.sourceCode.parserServices
|
|
89
|
+
|
|
90
|
+
if (parserServices?.defineTemplateBodyVisitor) {
|
|
91
|
+
return parserServices.defineTemplateBodyVisitor(templateVisitor, scriptVisitor)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return scriptVisitor
|
|
95
|
+
},
|
|
96
|
+
}
|
package/package.json
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "https://github.com/rsmple/eco-vue-js.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.28.0",
|
|
8
8
|
"homepage": "https://rsmple.github.io/eco-vue-js/",
|
|
9
9
|
"dependencies": {
|
|
10
|
+
"@eslint/css-tree": "4.1.2",
|
|
10
11
|
"@stylistic/eslint-plugin": "5.10.0",
|
|
11
12
|
"@tanstack/eslint-plugin-query": "5.105.0",
|
|
12
13
|
"@vue/eslint-config-typescript": "14.9.0",
|
|
@@ -17,7 +18,8 @@
|
|
|
17
18
|
"eslint-plugin-tailwindcss": "4.4.0",
|
|
18
19
|
"eslint-plugin-template-security": "0.2.0",
|
|
19
20
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
20
|
-
"eslint-plugin-vue": "10.12.0"
|
|
21
|
+
"eslint-plugin-vue": "10.12.0",
|
|
22
|
+
"tailwind-csstree": "0.4.2"
|
|
21
23
|
},
|
|
22
24
|
"peerDependencies": {
|
|
23
25
|
"@tanstack/vue-query": ">=5.92.9",
|
|
@@ -167,7 +167,9 @@ const pluginDefault = plugin(function ({addBase, addUtilities, theme}) {
|
|
|
167
167
|
height: '100%',
|
|
168
168
|
'background-repeat': 'repeat',
|
|
169
169
|
'background-size': '40px 40px',
|
|
170
|
-
|
|
170
|
+
'@media (prefers-reduced-motion: no-preference)': {
|
|
171
|
+
animation: theme('animation.move-horizontal'),
|
|
172
|
+
},
|
|
171
173
|
},
|
|
172
174
|
[DARK_SELECTOR]: {
|
|
173
175
|
'&::before': {
|
|
@@ -208,7 +210,9 @@ const pluginDefault = plugin(function ({addBase, addUtilities, theme}) {
|
|
|
208
210
|
width: '100%',
|
|
209
211
|
height: '100%',
|
|
210
212
|
'background-image': 'linear-gradient(90deg, rgb(255 255 255 / 0), rgb(255 255 255 / var(--w-skeleton-opacity)), rgb(255 255 255 / 0))',
|
|
211
|
-
|
|
213
|
+
'@media (prefers-reduced-motion: no-preference)': {
|
|
214
|
+
animation: theme('animation.ticker'),
|
|
215
|
+
},
|
|
212
216
|
},
|
|
213
217
|
},
|
|
214
218
|
})
|
|
@@ -18,9 +18,11 @@ const pluginDefault = plugin(function ({addBase}) {
|
|
|
18
18
|
'user-select': 'none',
|
|
19
19
|
opacity: '0',
|
|
20
20
|
transform: 'scaleX(0.5) scaleY(0.5)',
|
|
21
|
-
'
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
'@media (prefers-reduced-motion: no-preference)': {
|
|
22
|
+
'transition-property': 'opacity, transform',
|
|
23
|
+
'transition-timing-function': 'cubic-bezier(0.4, 0, 0.2, 1)',
|
|
24
|
+
'transition-duration': '200ms',
|
|
25
|
+
},
|
|
24
26
|
},
|
|
25
27
|
|
|
26
28
|
'&:hover::after, .w-hover-circle-trigger:hover &::after, &:focus::after, .w-hover-circle-trigger:focus &::after': {
|
|
@@ -48,7 +48,9 @@ const pluginRipple = plugin(function ({matchUtilities, addUtilities, addBase}) {
|
|
|
48
48
|
const configRippleStatic = {
|
|
49
49
|
'w-ripple-active:not(:active)': () => ({
|
|
50
50
|
'&::before': {
|
|
51
|
-
|
|
51
|
+
'@media (prefers-reduced-motion: no-preference)': {
|
|
52
|
+
animation: 'ripple-active infinite linear alternate 0.5s',
|
|
53
|
+
},
|
|
52
54
|
},
|
|
53
55
|
}),
|
|
54
56
|
}
|