@feugene/granularity 0.4.4 → 0.4.5
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/GrLink/chunks/{GrLink-BbN7R3iP.js → GrLink-DvvNkP0M.js} +33 -20
- package/dist/components/GrLink/chunks/GrLink-DvvNkP0M.js.map +1 -0
- package/dist/components/GrLink/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/types/src/components/GrLink/GrLink.vue.d.ts +29 -4
- package/package.json +1 -1
- package/dist/components/GrLink/chunks/GrLink-BbN7R3iP.js.map +0 -1
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import { a as grLinkClass, i as focusRingClass, r as baseRootClass } from "../../../chunks/config-DUtUkSzc.js";
|
|
2
|
-
import { computed,
|
|
3
|
-
//#region src/components/GrLink/GrLink.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
-
var _hoisted_1 = [
|
|
5
|
-
"href",
|
|
6
|
-
"target",
|
|
7
|
-
"rel",
|
|
8
|
-
"aria-label"
|
|
9
|
-
];
|
|
10
|
-
var _hoisted_2 = ["aria-label", "aria-disabled"];
|
|
2
|
+
import { computed, createBlock, defineComponent, markRaw, mergeProps, openBlock, renderSlot, resolveDynamicComponent, unref, useAttrs, withCtx } from "vue";
|
|
11
3
|
//#endregion
|
|
12
4
|
//#region src/components/GrLink/GrLink.vue
|
|
13
5
|
var GrLink_default = /* @__PURE__ */ defineComponent({
|
|
14
6
|
inheritAttrs: false,
|
|
15
7
|
__name: "GrLink",
|
|
16
8
|
props: {
|
|
9
|
+
as: { default: void 0 },
|
|
17
10
|
href: { default: void 0 },
|
|
18
11
|
external: {
|
|
19
12
|
type: Boolean,
|
|
@@ -35,15 +28,28 @@ var GrLink_default = /* @__PURE__ */ defineComponent({
|
|
|
35
28
|
* GrLink — DS-примитив ссылки.
|
|
36
29
|
*
|
|
37
30
|
* Корневой тег зависит от пропов:
|
|
38
|
-
* -
|
|
39
|
-
*
|
|
31
|
+
* - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`
|
|
32
|
+
* (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);
|
|
33
|
+
* - `<a>` — когда задан `href` и не `disabled`;
|
|
34
|
+
* - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан
|
|
35
|
+
* `href`/`as`).
|
|
40
36
|
*
|
|
41
37
|
* Это осознанное решение, чтобы отключённая ссылка не была кликабельной и
|
|
42
38
|
* не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.
|
|
39
|
+
*
|
|
40
|
+
* Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):
|
|
41
|
+
* стили/поведение DS остаются едиными, а тег корня подменяется. Все
|
|
42
|
+
* специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)
|
|
43
|
+
* проходят через fallthrough-attrs.
|
|
43
44
|
*/
|
|
44
45
|
const props = __props;
|
|
45
46
|
const attrs = useAttrs();
|
|
46
|
-
const
|
|
47
|
+
const isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href));
|
|
48
|
+
const renderAs = computed(() => {
|
|
49
|
+
if (!isInteractive.value) return "span";
|
|
50
|
+
if (props.as) return typeof props.as === "string" ? props.as : markRaw(props.as);
|
|
51
|
+
return "a";
|
|
52
|
+
});
|
|
47
53
|
const resolvedTarget = computed(() => {
|
|
48
54
|
if (props.target) return props.target;
|
|
49
55
|
if (props.external) return "_blank";
|
|
@@ -62,17 +68,24 @@ var GrLink_default = /* @__PURE__ */ defineComponent({
|
|
|
62
68
|
return props.disabled ? `${baseRootClass} ${variantClass}` : `${baseRootClass} ${focusRingClass} ${variantClass}`;
|
|
63
69
|
});
|
|
64
70
|
return (_ctx, _cache) => {
|
|
65
|
-
return
|
|
66
|
-
href: __props.href,
|
|
67
|
-
target: resolvedTarget.value,
|
|
68
|
-
rel: resolvedRel.value,
|
|
69
|
-
"aria-label": __props.ariaLabel,
|
|
70
|
-
class: rootClass.value
|
|
71
|
-
}), [renderSlot(_ctx.$slots, "default")], 16, _hoisted_1)) : (openBlock(), createElementBlock("span", mergeProps({ key: 1 }, unref(attrs), {
|
|
71
|
+
return openBlock(), createBlock(resolveDynamicComponent(renderAs.value), mergeProps(unref(attrs), {
|
|
72
|
+
href: isInteractive.value ? __props.href : void 0,
|
|
73
|
+
target: isInteractive.value ? resolvedTarget.value : void 0,
|
|
74
|
+
rel: isInteractive.value ? resolvedRel.value : void 0,
|
|
72
75
|
"aria-label": __props.ariaLabel,
|
|
73
76
|
"aria-disabled": __props.disabled ? "true" : void 0,
|
|
74
77
|
class: rootClass.value
|
|
75
|
-
}),
|
|
78
|
+
}), {
|
|
79
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "default")]),
|
|
80
|
+
_: 3
|
|
81
|
+
}, 16, [
|
|
82
|
+
"href",
|
|
83
|
+
"target",
|
|
84
|
+
"rel",
|
|
85
|
+
"aria-label",
|
|
86
|
+
"aria-disabled",
|
|
87
|
+
"class"
|
|
88
|
+
]);
|
|
76
89
|
};
|
|
77
90
|
}
|
|
78
91
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GrLink-DvvNkP0M.js","names":[],"sources":["../../../../src/components/GrLink/GrLink.vue","../../../../src/components/GrLink/GrLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`\n * (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);\n * - `<a>` — когда задан `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан\n * `href`/`as`).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n *\n * Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):\n * стили/поведение DS остаются едиными, а тег корня подменяется. Все\n * специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)\n * проходят через fallthrough-attrs.\n */\nimport { computed, markRaw, useAttrs, type Component } from 'vue'\n\nimport {\n baseRootClass,\n focusRingClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n grLinkClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n /**\n * Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —\n * рендерится через `<component :is=\"as\">`. Игнорируется при `disabled`.\n */\n as?: string | Component\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n as: undefined,\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\n// Кастомный корень имеет приоритет над `<a>` — DS не пытается угадывать\n// «правильный» тег за пользователя, если он явно его указал.\nconst isInteractive = computed(() => !props.disabled && (!!props.as || !!props.href))\n\nconst renderAs = computed<string | Component>(() => {\n if (!isInteractive.value) return 'span'\n if (props.as) {\n // Если `as` — объект-компонент, помечаем его как нереактивный, чтобы избежать\n // оверхеда от Vue-прокси и предупреждений в консоли. Строки (нативные теги)\n // оставляем как есть.\n return typeof props.as === 'string' ? props.as : markRaw(props.as)\n }\n return 'a'\n})\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <component\n :is=\"renderAs\"\n v-bind=\"attrs\"\n :href=\"isInteractive ? href : undefined\"\n :target=\"isInteractive ? resolvedTarget : undefined\"\n :rel=\"isInteractive ? resolvedRel : undefined\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </component>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCA,MAAM,QAAQ;EA4Bd,MAAM,QAAQ,UAAS;EAIvB,MAAM,gBAAgB,eAAe,CAAC,MAAM,aAAa,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,MAAM,MAAK;EAEpF,MAAM,WAAW,eAAmC;AAClD,OAAI,CAAC,cAAc,MAAO,QAAO;AACjC,OAAI,MAAM,GAIR,QAAO,OAAO,MAAM,OAAO,WAAW,MAAM,KAAK,QAAQ,MAAM,GAAE;AAEnE,UAAO;IACR;EAED,MAAM,iBAAiB,eAAe;AACpC,OAAI,MAAM,OACR,QAAO,MAAM;AAEf,OAAI,MAAM,SACR,QAAO;IAGV;EAED,MAAM,cAAc,eAAe;AACjC,OAAI,MAAM,IACR,QAAO,MAAM;AAIf,OAAI,eAAe,UAAU,SAC3B,QAAO;IAGV;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,eAAe,YAAY;IAC/B,MAAM,MAAM;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;AAID,UAAO,MAAM,WACT,GAAG,cAAc,GAAG,iBACpB,GAAG,cAAc,GAAG,eAAe,GAAG;IAC3C;;uBAIC,YAWY,wBAVL,SAAA,MAAQ,EADf,WAEU,MASE,MATG,EAAA;IACZ,MAAM,cAAA,QAAgB,QAAA,OAAO,KAAA;IAC7B,QAAQ,cAAA,QAAgB,eAAA,QAAiB,KAAA;IACzC,KAAK,cAAA,QAAgB,YAAA,QAAc,KAAA;IACnC,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;IACnC,OAAO,UAAA;;2BAEA,CAAR,WAAQ,KAAA,QAAA,UAAA,CAAA,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as grLinkSafelist, t as grLinkConfig } from "../../chunks/config-DUtUkSzc.js";
|
|
2
|
-
import { t as GrLink_default } from "./chunks/GrLink-
|
|
2
|
+
import { t as GrLink_default } from "./chunks/GrLink-DvvNkP0M.js";
|
|
3
3
|
export { GrLink_default as GrLink, GrLink_default as default, grLinkConfig, grLinkSafelist };
|
package/dist/index.js
CHANGED
|
@@ -69,7 +69,7 @@ import "./components/GrInput/index.js";
|
|
|
69
69
|
import { n as grInputTagSafelist, t as grInputTagConfig } from "./chunks/config-DgRJlF00.js";
|
|
70
70
|
import { t as GrInputTag_default } from "./components/GrInputTag/chunks/GrInputTag-B0x4U0Yk.js";
|
|
71
71
|
import { n as grLinkSafelist, t as grLinkConfig } from "./chunks/config-DUtUkSzc.js";
|
|
72
|
-
import { t as GrLink_default } from "./components/GrLink/chunks/GrLink-
|
|
72
|
+
import { t as GrLink_default } from "./components/GrLink/chunks/GrLink-DvvNkP0M.js";
|
|
73
73
|
import { n as GrList_default, t as GrListItem_default } from "./components/GrList/chunks/GrList--Ib4zLNw.js";
|
|
74
74
|
import { t as grListConfig } from "./chunks/config-fCcRwjIB.js";
|
|
75
75
|
import { n as grLoadingSafelist, t as grLoadingConfig } from "./chunks/config-BN-B2K4r.js";
|
|
@@ -1,5 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GrLink — DS-примитив ссылки.
|
|
3
|
+
*
|
|
4
|
+
* Корневой тег зависит от пропов:
|
|
5
|
+
* - кастомный компонент/тег из пропа `as` — когда `as` передан и не `disabled`
|
|
6
|
+
* (например, `Link` от `@inertiajs/vue3` или `RouterLink` от Vue Router);
|
|
7
|
+
* - `<a>` — когда задан `href` и не `disabled`;
|
|
8
|
+
* - `<span>` — во всех остальных случаях (включая `disabled`, даже если задан
|
|
9
|
+
* `href`/`as`).
|
|
10
|
+
*
|
|
11
|
+
* Это осознанное решение, чтобы отключённая ссылка не была кликабельной и
|
|
12
|
+
* не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.
|
|
13
|
+
*
|
|
14
|
+
* Проп `as` нужен для интеграции с роутерами (Inertia, Vue Router и пр.):
|
|
15
|
+
* стили/поведение DS остаются едиными, а тег корня подменяется. Все
|
|
16
|
+
* специфичные для роутера атрибуты (`method`, `replace`, `preserve-scroll` и т.п.)
|
|
17
|
+
* проходят через fallthrough-attrs.
|
|
18
|
+
*/
|
|
19
|
+
import { type Component } from 'vue';
|
|
1
20
|
import { type GrLinkSize, type GrLinkUnderline, type GrLinkVariant } from './grLinkStyles';
|
|
2
21
|
type __VLS_Props = {
|
|
22
|
+
/**
|
|
23
|
+
* Кастомный корневой тег/компонент. Если передан и компонент не `disabled` —
|
|
24
|
+
* рендерится через `<component :is="as">`. Игнорируется при `disabled`.
|
|
25
|
+
*/
|
|
26
|
+
as?: string | Component;
|
|
3
27
|
href?: string;
|
|
4
28
|
external?: boolean;
|
|
5
29
|
target?: string;
|
|
@@ -10,13 +34,12 @@ type __VLS_Props = {
|
|
|
10
34
|
underline?: GrLinkUnderline;
|
|
11
35
|
size?: GrLinkSize;
|
|
12
36
|
};
|
|
13
|
-
declare var
|
|
37
|
+
declare var __VLS_8: {};
|
|
14
38
|
type __VLS_Slots = {} & {
|
|
15
|
-
default?: (props: typeof
|
|
16
|
-
} & {
|
|
17
|
-
default?: (props: typeof __VLS_3) => any;
|
|
39
|
+
default?: (props: typeof __VLS_8) => any;
|
|
18
40
|
};
|
|
19
41
|
declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
42
|
+
as: undefined;
|
|
20
43
|
href: undefined;
|
|
21
44
|
external: boolean;
|
|
22
45
|
target: undefined;
|
|
@@ -27,6 +50,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
27
50
|
underline: string;
|
|
28
51
|
size: string;
|
|
29
52
|
}>>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
|
|
53
|
+
as: undefined;
|
|
30
54
|
href: undefined;
|
|
31
55
|
external: boolean;
|
|
32
56
|
target: undefined;
|
|
@@ -41,6 +65,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
41
65
|
size: GrLinkSize;
|
|
42
66
|
disabled: boolean;
|
|
43
67
|
ariaLabel: string;
|
|
68
|
+
as: string | Component;
|
|
44
69
|
target: string;
|
|
45
70
|
href: string;
|
|
46
71
|
external: boolean;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feugene/granularity",
|
|
3
3
|
"description": "Granularity design system package with Vue 3 components, consumed via the `@feugene/unocss-preset-granular` preset.",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Evgeniy Fureev",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GrLink-BbN7R3iP.js","names":[],"sources":["../../../../src/components/GrLink/GrLink.vue","../../../../src/components/GrLink/GrLink.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - `<a>` — когда заданы `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если `href` задан).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n */\nimport { computed, useAttrs } from 'vue'\n\nimport {\n baseRootClass,\n grLinkClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n focusRingClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\nconst isAnchor = computed(() => !!props.href && !props.disabled)\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <a\n v-if=\"isAnchor\"\n v-bind=\"attrs\"\n :href=\"href\"\n :target=\"resolvedTarget\"\n :rel=\"resolvedRel\"\n :aria-label=\"ariaLabel\"\n :class=\"rootClass\"\n >\n <slot />\n </a>\n\n <span\n v-else\n v-bind=\"attrs\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </span>\n</template>","<script setup lang=\"ts\">\n/**\n * GrLink — DS-примитив ссылки.\n *\n * Корневой тег зависит от пропов:\n * - `<a>` — когда заданы `href` и не `disabled`;\n * - `<span>` — во всех остальных случаях (включая `disabled`, даже если `href` задан).\n *\n * Это осознанное решение, чтобы отключённая ссылка не была кликабельной и\n * не участвовала в порядке табуляции. Учтите это в внешних CSS-селекторах.\n */\nimport { computed, useAttrs } from 'vue'\n\nimport {\n baseRootClass,\n grLinkClass,\n type GrLinkSize,\n type GrLinkUnderline,\n type GrLinkVariant,\n focusRingClass,\n} from './grLinkStyles'\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<{\n href?: string\n external?: boolean\n target?: string\n rel?: string\n disabled?: boolean\n ariaLabel?: string\n variant?: GrLinkVariant\n underline?: GrLinkUnderline\n size?: GrLinkSize\n}>(), {\n href: undefined,\n external: false,\n target: undefined,\n rel: undefined,\n disabled: false,\n ariaLabel: undefined,\n variant: 'primary',\n underline: 'auto',\n size: 'md',\n})\n\nconst attrs = useAttrs()\n\nconst isAnchor = computed(() => !!props.href && !props.disabled)\n\nconst resolvedTarget = computed(() => {\n if (props.target)\n return props.target\n\n if (props.external)\n return '_blank'\n\n return undefined\n})\n\nconst resolvedRel = computed(() => {\n if (props.rel)\n return props.rel\n\n // Авто-защита для любых ссылок, открывающихся в новой вкладке,\n // а не только когда выставлен `external`.\n if (resolvedTarget.value === '_blank')\n return 'noopener noreferrer'\n\n return undefined\n})\n\nconst rootClass = computed(() => {\n const variantClass = grLinkClass({\n size: props.size,\n underline: props.underline,\n variant: props.variant,\n disabled: props.disabled,\n })\n\n // На disabled-ветке (`<span>`) focus-ring не нужен: элемент не фокусируется,\n // а если снаружи ему навесят `tabindex`, фокус-рамка на «отключённой» ссылке смотрелась бы странно.\n return props.disabled\n ? `${baseRootClass} ${variantClass}`\n : `${baseRootClass} ${focusRingClass} ${variantClass}`\n})\n</script>\n\n<template>\n <a\n v-if=\"isAnchor\"\n v-bind=\"attrs\"\n :href=\"href\"\n :target=\"resolvedTarget\"\n :rel=\"resolvedRel\"\n :aria-label=\"ariaLabel\"\n :class=\"rootClass\"\n >\n <slot />\n </a>\n\n <span\n v-else\n v-bind=\"attrs\"\n :aria-label=\"ariaLabel\"\n :aria-disabled=\"disabled ? 'true' : undefined\"\n :class=\"rootClass\"\n >\n <slot />\n </span>\n</template>"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BA,MAAM,QAAQ;EAsBd,MAAM,QAAQ,UAAS;EAEvB,MAAM,WAAW,eAAe,CAAC,CAAC,MAAM,QAAQ,CAAC,MAAM,SAAQ;EAE/D,MAAM,iBAAiB,eAAe;AACpC,OAAI,MAAM,OACR,QAAO,MAAM;AAEf,OAAI,MAAM,SACR,QAAO;IAGV;EAED,MAAM,cAAc,eAAe;AACjC,OAAI,MAAM,IACR,QAAO,MAAM;AAIf,OAAI,eAAe,UAAU,SAC3B,QAAO;IAGV;EAED,MAAM,YAAY,eAAe;GAC/B,MAAM,eAAe,YAAY;IAC/B,MAAM,MAAM;IACZ,WAAW,MAAM;IACjB,SAAS,MAAM;IACf,UAAU,MAAM;IACjB,CAAA;AAID,UAAO,MAAM,WACT,GAAG,cAAc,GAAG,iBACpB,GAAG,cAAc,GAAG,eAAe,GAAG;IAC3C;;UAKS,SAAA,SAAA,WAAA,EADR,mBAUI,KAVJ,WAUI,EAAA,KAAA,GAAA,EARM,MAAA,MAAK,EAAA;IACZ,MAAM,QAAA;IACN,QAAQ,eAAA;IACR,KAAK,YAAA;IACL,cAAY,QAAA;IACZ,OAAO,UAAA;QAER,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA,KAAA,WAAA,EAGV,mBAQO,QARP,WAQO,EAAA,KAAA,GAAA,EANG,MAAA,MAAK,EAAA;IACZ,cAAY,QAAA;IACZ,iBAAe,QAAA,WAAQ,SAAY,KAAA;IACnC,OAAO,UAAA;QAER,WAAQ,KAAA,QAAA,UAAA,CAAA,EAAA,IAAA,WAAA"}
|