@leaflink/stash 50.8.1 → 50.10.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/EmptyState.js +29 -22
- package/dist/EmptyState.js.map +1 -1
- package/dist/EmptyState.vue.d.ts +8 -0
- package/dist/ListView.vue.d.ts +31 -0
- package/dist/Textarea.js +16 -14
- package/dist/Textarea.js.map +1 -1
- package/dist/Textarea.vue.d.ts +10 -0
- package/package.json +1 -1
package/dist/EmptyState.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent as p, useCssModule as
|
|
1
|
+
import { defineComponent as p, useCssModule as f, useSlots as _, openBlock as s, createElementBlock as o, createBlock as g, createCommentVNode as n, createElementVNode as u, renderSlot as a, toDisplayString as i, normalizeClass as m, unref as r, createTextVNode as y } from "vue";
|
|
2
2
|
import { t as w } from "./locale.js";
|
|
3
3
|
import { _ as b } from "./Illustration.vue_vue_type_script_setup_true_lang-CYddAFtS.js";
|
|
4
4
|
import { _ as h } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
@@ -9,7 +9,7 @@ const x = {
|
|
|
9
9
|
}, k = {
|
|
10
10
|
key: 0,
|
|
11
11
|
class: "tw-flex tw-flex-col tw-items-center tw-text-center md:tw-flex-row md:tw-text-left"
|
|
12
|
-
}, v = { class: "tw-mb-1.5" },
|
|
12
|
+
}, v = { class: "tw-mb-1.5" }, $ = ["alt", "src"], S = /* @__PURE__ */ p({
|
|
13
13
|
name: "ll-empty-state",
|
|
14
14
|
__name: "EmptyState",
|
|
15
15
|
props: {
|
|
@@ -20,46 +20,53 @@ const x = {
|
|
|
20
20
|
text: { default: "" },
|
|
21
21
|
title: { default: "" },
|
|
22
22
|
subtitle: { default: "" },
|
|
23
|
+
footnote: { default: "" },
|
|
23
24
|
vignette: { default: void 0 }
|
|
24
25
|
},
|
|
25
26
|
setup(d) {
|
|
26
|
-
const t = d, c =
|
|
27
|
-
return (l, N) => (s(),
|
|
28
|
-
t.title || e.title || t.subtitle || e.subtitle || t.vignette ? (s(),
|
|
29
|
-
t.vignette ? (s(),
|
|
27
|
+
const t = d, c = f(), e = _();
|
|
28
|
+
return (l, N) => (s(), o("div", x, [
|
|
29
|
+
t.title || e.title || t.subtitle || e.subtitle || t.vignette ? (s(), o("div", k, [
|
|
30
|
+
t.vignette ? (s(), g(b, {
|
|
30
31
|
key: 0,
|
|
31
32
|
"data-test": "stash-empty-state|illustration",
|
|
32
33
|
type: "vignette",
|
|
33
34
|
class: "tw-mx-3",
|
|
34
35
|
name: t.vignette,
|
|
35
36
|
size: 300
|
|
36
|
-
}, null, 8, ["name"])) :
|
|
37
|
+
}, null, 8, ["name"])) : n("", !0),
|
|
37
38
|
u("section", null, [
|
|
38
|
-
|
|
39
|
-
u("h3", v,
|
|
39
|
+
a(l.$slots, "title", {}, () => [
|
|
40
|
+
u("h3", v, i(t.title), 1)
|
|
40
41
|
]),
|
|
41
|
-
|
|
42
|
-
t.subtitle || e.subtitle ? (s(),
|
|
42
|
+
a(l.$slots, "subtitle", {}, () => [
|
|
43
|
+
t.subtitle || e.subtitle ? (s(), o("p", {
|
|
43
44
|
key: 0,
|
|
44
|
-
class:
|
|
45
|
-
},
|
|
45
|
+
class: m({ "tw-mb-8": e.button, "tw-mb-0": !e.button })
|
|
46
|
+
}, i(t.subtitle), 3)) : n("", !0)
|
|
46
47
|
]),
|
|
47
|
-
|
|
48
|
+
a(l.$slots, "button"),
|
|
49
|
+
a(l.$slots, "footnote", {}, () => [
|
|
50
|
+
t.footnote ? (s(), o("p", {
|
|
51
|
+
key: 0,
|
|
52
|
+
class: m(["tw-mb-0 tw-text-xs", { "tw-mt-3": e.button }])
|
|
53
|
+
}, i(t.footnote), 3)) : n("", !0)
|
|
54
|
+
])
|
|
48
55
|
])
|
|
49
|
-
])) : (s(),
|
|
56
|
+
])) : (s(), o("div", {
|
|
50
57
|
key: 1,
|
|
51
|
-
class:
|
|
58
|
+
class: m(["tw-mx-auto tw-my-0 tw-flex tw-items-center tw-justify-center tw-py-12", [r(c).root, { "tw-text-center": !t.image.src && !e.image }]])
|
|
52
59
|
}, [
|
|
53
|
-
|
|
54
|
-
t.image.src ? (s(),
|
|
60
|
+
a(l.$slots, "image", {}, () => [
|
|
61
|
+
t.image.src ? (s(), o("img", {
|
|
55
62
|
key: 0,
|
|
56
|
-
class:
|
|
63
|
+
class: m(["tw-mr-6", r(c).image]),
|
|
57
64
|
alt: t.image.alt,
|
|
58
65
|
src: t.image.src,
|
|
59
66
|
"data-test": "stash-empty-state__img"
|
|
60
|
-
}, null, 10,
|
|
67
|
+
}, null, 10, $)) : n("", !0)
|
|
61
68
|
]),
|
|
62
|
-
|
|
69
|
+
y(" " + i(t.text || r(w)("ll.emptyState.noResults")), 1)
|
|
63
70
|
], 2))
|
|
64
71
|
]));
|
|
65
72
|
}
|
|
@@ -68,7 +75,7 @@ const x = {
|
|
|
68
75
|
image: E
|
|
69
76
|
}, M = {
|
|
70
77
|
$style: B
|
|
71
|
-
}, R = /* @__PURE__ */ h(
|
|
78
|
+
}, R = /* @__PURE__ */ h(S, [["__cssModules", M]]);
|
|
72
79
|
export {
|
|
73
80
|
R as default
|
|
74
81
|
};
|
package/dist/EmptyState.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.js","sources":["../src/components/EmptyState/EmptyState.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import { VignetteNames } from '../Illustration/Illustration.models';\n import Illustration from '../Illustration/Illustration.vue';\n\n export interface EmptyStateProps {\n /**\n * @deprecated Use illustration instead.\n */\n image?: {\n alt?: string;\n src: string;\n };\n\n /**\n * @deprecated Use title instead.\n */\n text?: string;\n\n /**\n * the title text of the empty state\n */\n title?: string;\n\n /**\n * the subtitle text of the empty state\n */\n subtitle?: string;\n\n /**\n * The name of the vignette illustration to render\n */\n vignette?: VignetteNames;\n }\n\n export interface EmptyStateSlots {\n title?: () => unknown;\n subtitle?: () => unknown;\n button?: () => unknown;\n image?: () => unknown;\n }\n\n defineOptions({\n name: 'll-empty-state',\n });\n\n const props = withDefaults(defineProps<EmptyStateProps>(), {\n /**\n * An optional image to render\n */\n image: () => ({\n alt: '',\n src: '',\n }),\n\n /**\n * The custom message to render\n */\n text: '',\n\n title: '',\n subtitle: '',\n vignette: undefined,\n });\n\n const classes = useCssModule();\n const slots = defineSlots<EmptyStateSlots>();\n</script>\n\n<template>\n <div key=\"empty\" class=\"stash-empty-state\" data-test=\"stash-empty-state\">\n <template v-if=\"props.title || slots.title || props.subtitle || slots.subtitle || props.vignette\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-text-center md:tw-flex-row md:tw-text-left\">\n <Illustration\n v-if=\"props.vignette\"\n data-test=\"stash-empty-state|illustration\"\n type=\"vignette\"\n class=\"tw-mx-3\"\n :name=\"props.vignette\"\n :size=\"300\"\n />\n <section>\n <slot name=\"title\">\n <h3 class=\"tw-mb-1.5\">\n {{ props.title }}\n </h3>\n </slot>\n\n <slot name=\"subtitle\">\n <p v-if=\"props.subtitle || slots.subtitle\" :class=\"{ '
|
|
1
|
+
{"version":3,"file":"EmptyState.js","sources":["../src/components/EmptyState/EmptyState.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { useCssModule } from 'vue';\n\n import { t } from '../../locale';\n import { VignetteNames } from '../Illustration/Illustration.models';\n import Illustration from '../Illustration/Illustration.vue';\n\n export interface EmptyStateProps {\n /**\n * @deprecated Use illustration instead.\n */\n image?: {\n alt?: string;\n src: string;\n };\n\n /**\n * @deprecated Use title instead.\n */\n text?: string;\n\n /**\n * the title text of the empty state\n */\n title?: string;\n\n /**\n * the subtitle text of the empty state\n */\n subtitle?: string;\n\n /**\n * additional text to place at the bottom of the empty state\n */\n footnote?: string;\n\n /**\n * The name of the vignette illustration to render\n */\n vignette?: VignetteNames;\n }\n\n export interface EmptyStateSlots {\n title?: () => unknown;\n subtitle?: () => unknown;\n footnote?: () => unknown;\n button?: () => unknown;\n image?: () => unknown;\n }\n\n defineOptions({\n name: 'll-empty-state',\n });\n\n const props = withDefaults(defineProps<EmptyStateProps>(), {\n /**\n * An optional image to render\n */\n image: () => ({\n alt: '',\n src: '',\n }),\n\n /**\n * The custom message to render\n */\n text: '',\n\n title: '',\n subtitle: '',\n footnote: '',\n vignette: undefined,\n });\n\n const classes = useCssModule();\n const slots = defineSlots<EmptyStateSlots>();\n</script>\n\n<template>\n <div key=\"empty\" class=\"stash-empty-state\" data-test=\"stash-empty-state\">\n <template v-if=\"props.title || slots.title || props.subtitle || slots.subtitle || props.vignette\">\n <div class=\"tw-flex tw-flex-col tw-items-center tw-text-center md:tw-flex-row md:tw-text-left\">\n <Illustration\n v-if=\"props.vignette\"\n data-test=\"stash-empty-state|illustration\"\n type=\"vignette\"\n class=\"tw-mx-3\"\n :name=\"props.vignette\"\n :size=\"300\"\n />\n <section>\n <slot name=\"title\">\n <h3 class=\"tw-mb-1.5\">\n {{ props.title }}\n </h3>\n </slot>\n\n <slot name=\"subtitle\">\n <p v-if=\"props.subtitle || slots.subtitle\" :class=\"{ 'tw-mb-8': slots.button, 'tw-mb-0': !slots.button }\">\n {{ props.subtitle }}\n </p>\n </slot>\n\n <slot name=\"button\"></slot>\n <slot name=\"footnote\">\n <p v-if=\"props.footnote\" class=\"tw-mb-0 tw-text-xs\" :class=\"{ 'tw-mt-3': slots.button }\">\n {{ props.footnote }}\n </p>\n </slot>\n </section>\n </div>\n </template>\n\n <template v-else>\n <div\n class=\"tw-mx-auto tw-my-0 tw-flex tw-items-center tw-justify-center tw-py-12\"\n :class=\"[classes.root, { 'tw-text-center': !props.image.src && !slots.image }]\"\n >\n <slot name=\"image\">\n <img\n v-if=\"props.image.src\"\n class=\"tw-mr-6\"\n :alt=\"props.image.alt\"\n :class=\"classes.image\"\n :src=\"props.image.src\"\n data-test=\"stash-empty-state__img\"\n />\n </slot>\n\n {{ props.text || t('ll.emptyState.noResults') }}\n </div>\n </template>\n </div>\n</template>\n\n<style module>\n .root {\n max-width: 600px;\n }\n\n .image {\n max-width: 60px;\n }\n</style>\n"],"names":["props","__props","classes","useCssModule","slots","_useSlots"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsDE,UAAMA,IAAQC,GAoBRC,IAAUC,EAAa,GACvBC,IAAQC,EAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/EmptyState.vue.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ src: string;
|
|
|
46
46
|
text: string;
|
|
47
47
|
title: string;
|
|
48
48
|
subtitle: string;
|
|
49
|
+
footnote: string;
|
|
49
50
|
vignette: undefined;
|
|
50
51
|
}>>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<EmptyStateProps>, {
|
|
51
52
|
/**
|
|
@@ -61,6 +62,7 @@ src: string;
|
|
|
61
62
|
text: string;
|
|
62
63
|
title: string;
|
|
63
64
|
subtitle: string;
|
|
65
|
+
footnote: string;
|
|
64
66
|
vignette: undefined;
|
|
65
67
|
}>>> & Readonly<{}>, {
|
|
66
68
|
title: string;
|
|
@@ -71,6 +73,7 @@ src: string;
|
|
|
71
73
|
text: string;
|
|
72
74
|
subtitle: string;
|
|
73
75
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
76
|
+
footnote: string;
|
|
74
77
|
}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>, Readonly<EmptyStateSlots> & EmptyStateSlots>;
|
|
75
78
|
export default _default;
|
|
76
79
|
|
|
@@ -94,6 +97,10 @@ export declare interface EmptyStateProps {
|
|
|
94
97
|
* the subtitle text of the empty state
|
|
95
98
|
*/
|
|
96
99
|
subtitle?: string;
|
|
100
|
+
/**
|
|
101
|
+
* additional text to place at the bottom of the empty state
|
|
102
|
+
*/
|
|
103
|
+
footnote?: string;
|
|
97
104
|
/**
|
|
98
105
|
* The name of the vignette illustration to render
|
|
99
106
|
*/
|
|
@@ -103,6 +110,7 @@ export declare interface EmptyStateProps {
|
|
|
103
110
|
export declare interface EmptyStateSlots {
|
|
104
111
|
title?: () => unknown;
|
|
105
112
|
subtitle?: () => unknown;
|
|
113
|
+
footnote?: () => unknown;
|
|
106
114
|
button?: () => unknown;
|
|
107
115
|
image?: () => unknown;
|
|
108
116
|
}
|
package/dist/ListView.vue.d.ts
CHANGED
|
@@ -3489,6 +3489,10 @@ vignette: {
|
|
|
3489
3489
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
3490
3490
|
default: undefined;
|
|
3491
3491
|
};
|
|
3492
|
+
footnote: {
|
|
3493
|
+
type: PropType<string>;
|
|
3494
|
+
default: string;
|
|
3495
|
+
};
|
|
3492
3496
|
}>> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, PublicProps, {
|
|
3493
3497
|
title: string;
|
|
3494
3498
|
image: {
|
|
@@ -3498,6 +3502,7 @@ src: string;
|
|
|
3498
3502
|
text: string;
|
|
3499
3503
|
subtitle: string;
|
|
3500
3504
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
3505
|
+
footnote: string;
|
|
3501
3506
|
}, true, {}, {}, GlobalComponents, GlobalDirectives, string, {}, any, ComponentProvideOptions, {
|
|
3502
3507
|
P: {};
|
|
3503
3508
|
B: {};
|
|
@@ -3532,6 +3537,10 @@ vignette: {
|
|
|
3532
3537
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
3533
3538
|
default: undefined;
|
|
3534
3539
|
};
|
|
3540
|
+
footnote: {
|
|
3541
|
+
type: PropType<string>;
|
|
3542
|
+
default: string;
|
|
3543
|
+
};
|
|
3535
3544
|
}>> & Readonly<{}>, {}, {}, {}, {}, {
|
|
3536
3545
|
title: string;
|
|
3537
3546
|
image: {
|
|
@@ -3541,6 +3550,7 @@ src: string;
|
|
|
3541
3550
|
text: string;
|
|
3542
3551
|
subtitle: string;
|
|
3543
3552
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
3553
|
+
footnote: string;
|
|
3544
3554
|
}>;
|
|
3545
3555
|
__isFragment?: undefined;
|
|
3546
3556
|
__isTeleport?: undefined;
|
|
@@ -3572,6 +3582,10 @@ vignette: {
|
|
|
3572
3582
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
3573
3583
|
default: undefined;
|
|
3574
3584
|
};
|
|
3585
|
+
footnote: {
|
|
3586
|
+
type: PropType<string>;
|
|
3587
|
+
default: string;
|
|
3588
|
+
};
|
|
3575
3589
|
}>> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {
|
|
3576
3590
|
title: string;
|
|
3577
3591
|
image: {
|
|
@@ -3581,6 +3595,7 @@ src: string;
|
|
|
3581
3595
|
text: string;
|
|
3582
3596
|
subtitle: string;
|
|
3583
3597
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
3598
|
+
footnote: string;
|
|
3584
3599
|
}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & VNodeProps & AllowedComponentProps & ComponentCustomProps & (new () => {
|
|
3585
3600
|
$slots: Readonly<EmptyStateSlots> & EmptyStateSlots;
|
|
3586
3601
|
});
|
|
@@ -4687,6 +4702,7 @@ declare type DropdownOffset = {
|
|
|
4687
4702
|
declare interface EmptyStateSlots {
|
|
4688
4703
|
title?: () => unknown;
|
|
4689
4704
|
subtitle?: () => unknown;
|
|
4705
|
+
footnote?: () => unknown;
|
|
4690
4706
|
button?: () => unknown;
|
|
4691
4707
|
image?: () => unknown;
|
|
4692
4708
|
}
|
|
@@ -5253,6 +5269,10 @@ vignette: {
|
|
|
5253
5269
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
5254
5270
|
default: undefined;
|
|
5255
5271
|
};
|
|
5272
|
+
footnote: {
|
|
5273
|
+
type: PropType<string>;
|
|
5274
|
+
default: string;
|
|
5275
|
+
};
|
|
5256
5276
|
}>> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, PublicProps, {
|
|
5257
5277
|
title: string;
|
|
5258
5278
|
image: {
|
|
@@ -5262,6 +5282,7 @@ src: string;
|
|
|
5262
5282
|
text: string;
|
|
5263
5283
|
subtitle: string;
|
|
5264
5284
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
5285
|
+
footnote: string;
|
|
5265
5286
|
}, true, {}, {}, GlobalComponents, GlobalDirectives, string, {}, any, ComponentProvideOptions, {
|
|
5266
5287
|
P: {};
|
|
5267
5288
|
B: {};
|
|
@@ -5296,6 +5317,10 @@ vignette: {
|
|
|
5296
5317
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
5297
5318
|
default: undefined;
|
|
5298
5319
|
};
|
|
5320
|
+
footnote: {
|
|
5321
|
+
type: PropType<string>;
|
|
5322
|
+
default: string;
|
|
5323
|
+
};
|
|
5299
5324
|
}>> & Readonly<{}>, {}, {}, {}, {}, {
|
|
5300
5325
|
title: string;
|
|
5301
5326
|
image: {
|
|
@@ -5305,6 +5330,7 @@ src: string;
|
|
|
5305
5330
|
text: string;
|
|
5306
5331
|
subtitle: string;
|
|
5307
5332
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
5333
|
+
footnote: string;
|
|
5308
5334
|
}>;
|
|
5309
5335
|
__isFragment?: undefined;
|
|
5310
5336
|
__isTeleport?: undefined;
|
|
@@ -5336,6 +5362,10 @@ vignette: {
|
|
|
5336
5362
|
type: PropType<"map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery">;
|
|
5337
5363
|
default: undefined;
|
|
5338
5364
|
};
|
|
5365
|
+
footnote: {
|
|
5366
|
+
type: PropType<string>;
|
|
5367
|
+
default: string;
|
|
5368
|
+
};
|
|
5339
5369
|
}>> & Readonly<{}>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, {
|
|
5340
5370
|
title: string;
|
|
5341
5371
|
image: {
|
|
@@ -5345,6 +5375,7 @@ src: string;
|
|
|
5345
5375
|
text: string;
|
|
5346
5376
|
subtitle: string;
|
|
5347
5377
|
vignette: "map" | "search" | "calendar" | "dashboard" | "edit" | "megaphone" | "truck" | "warehouse" | "payments" | "light-bulb" | "messages" | "pie-chart" | "api" | "bank" | "basket" | "brand-menu" | "deals" | "document-search" | "empty-tray" | "graph" | "integrations" | "money-bank" | "notifications" | "orders-empty" | "product-cards" | "product-display" | "search-storefront" | "store" | "todo" | "users" | "warehouse-delivery";
|
|
5378
|
+
footnote: string;
|
|
5348
5379
|
}, {}, string, {}, GlobalComponents, GlobalDirectives, string, ComponentProvideOptions> & VNodeProps & AllowedComponentProps & ComponentCustomProps & (new () => {
|
|
5349
5380
|
$slots: Readonly<EmptyStateSlots> & EmptyStateSlots;
|
|
5350
5381
|
});
|
package/dist/Textarea.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { defineComponent as E, useAttrs as M, useSlots as k, useCssModule as H, ref as
|
|
1
|
+
import { defineComponent as E, useAttrs as M, useSlots as k, useCssModule as H, ref as x, computed as w, watch as A, onMounted as I, nextTick as P, onBeforeUnmount as V, openBlock as $, createBlock as q, mergeProps as y, unref as p, createSlots as D, withCtx as b, createElementVNode as j, renderSlot as F } from "vue";
|
|
2
2
|
import { _ as L } from "./Field.vue_vue_type_script_setup_true_lang-DEizIcDo.js";
|
|
3
3
|
import { _ as N } from "./_plugin-vue_export-helper-CHgC5LLL.js";
|
|
4
|
-
const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /* @__PURE__ */ E({
|
|
4
|
+
const U = ["id", "maxlength", "value", "placeholder", "disabled", "readonly", "rows"], W = /* @__PURE__ */ E({
|
|
5
5
|
name: "ll-textarea",
|
|
6
6
|
__name: "Textarea",
|
|
7
7
|
props: {
|
|
@@ -9,7 +9,8 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
9
9
|
value: { default: null },
|
|
10
10
|
resize: { type: [Boolean, Object], default: !1 },
|
|
11
11
|
placeholder: { default: void 0 },
|
|
12
|
-
rows: {},
|
|
12
|
+
rows: { default: void 0 },
|
|
13
|
+
maxlength: { default: void 0 },
|
|
13
14
|
addBottomSpace: { type: Boolean },
|
|
14
15
|
errorText: {},
|
|
15
16
|
hintText: {},
|
|
@@ -25,7 +26,7 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
25
26
|
},
|
|
26
27
|
emits: ["update:model-value"],
|
|
27
28
|
setup(_, { emit: g }) {
|
|
28
|
-
const c = M(), B = k(), m = H(), t = _, z = g, u =
|
|
29
|
+
const c = M(), B = k(), m = H(), t = _, z = g, u = x(), r = x(), R = w(() => t.isReadOnly || "readonly" in c && c.readonly !== !1), T = w(() => {
|
|
29
30
|
const e = { ...c };
|
|
30
31
|
return delete e["data-test"], delete e.class, e;
|
|
31
32
|
});
|
|
@@ -33,26 +34,26 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
33
34
|
() => t.resize,
|
|
34
35
|
(e) => {
|
|
35
36
|
var o;
|
|
36
|
-
e ? h() : (o =
|
|
37
|
+
e ? h() : (o = r.value) == null || o.disconnect();
|
|
37
38
|
}
|
|
38
39
|
);
|
|
39
40
|
const O = (e) => {
|
|
40
41
|
z("update:model-value", e.target.value);
|
|
41
42
|
}, h = () => {
|
|
42
|
-
|
|
43
|
+
r.value || !u.value || (r.value = new ResizeObserver(([e]) => {
|
|
43
44
|
const { target: o } = e, s = v(u.value) || document.documentElement, { scrollTop: a } = s;
|
|
44
45
|
let n = 0;
|
|
45
46
|
if (s === document.documentElement) {
|
|
46
|
-
const { top:
|
|
47
|
-
n = Math.max(
|
|
47
|
+
const { top: l, height: i } = C(o), { innerHeight: d } = window;
|
|
48
|
+
n = Math.max(l + i - (d + a), 0);
|
|
48
49
|
} else {
|
|
49
|
-
const { top:
|
|
50
|
+
const { top: l, height: i } = o.getBoundingClientRect(), { top: d } = s.getBoundingClientRect(), { offsetHeight: f } = s, S = l - d;
|
|
50
51
|
n = Math.max(S + i - f, 0);
|
|
51
52
|
}
|
|
52
53
|
n && requestAnimationFrame(() => {
|
|
53
54
|
s.scrollTop = a + n;
|
|
54
55
|
});
|
|
55
|
-
}),
|
|
56
|
+
}), r.value.observe(u.value));
|
|
56
57
|
}, v = (e) => {
|
|
57
58
|
const o = e.parentElement;
|
|
58
59
|
if (!o)
|
|
@@ -62,10 +63,10 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
62
63
|
}, C = (e) => {
|
|
63
64
|
const { offsetWidth: o, offsetHeight: s } = e;
|
|
64
65
|
let a = 0, n = 0;
|
|
65
|
-
const
|
|
66
|
-
a += i, n += d, f &&
|
|
66
|
+
const l = function({ offsetLeft: i, offsetTop: d, offsetParent: f }) {
|
|
67
|
+
a += i, n += d, f && l(f);
|
|
67
68
|
};
|
|
68
|
-
return
|
|
69
|
+
return l(e), {
|
|
69
70
|
top: n,
|
|
70
71
|
left: a,
|
|
71
72
|
width: o,
|
|
@@ -81,7 +82,7 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
81
82
|
(typeof t.resize == "boolean" && t.resize || (e = t.resize) != null && e.forceBrowserScroll) && (await P(), h());
|
|
82
83
|
}), V(() => {
|
|
83
84
|
var e;
|
|
84
|
-
(e =
|
|
85
|
+
(e = r.value) == null || e.disconnect();
|
|
85
86
|
}), (e, o) => ($(), q(L, y(t, {
|
|
86
87
|
class: ["stash-textarea", [p(m).root]],
|
|
87
88
|
"data-test": "stash-textarea"
|
|
@@ -102,6 +103,7 @@ const U = ["id", "value", "placeholder", "disabled", "readonly", "rows"], W = /*
|
|
|
102
103
|
"tw-resize-none": !t.resize
|
|
103
104
|
}
|
|
104
105
|
],
|
|
106
|
+
maxlength: t.maxlength,
|
|
105
107
|
value: t.modelValue,
|
|
106
108
|
"data-test": "stash-textarea|textarea",
|
|
107
109
|
placeholder: t.placeholder
|
package/dist/Textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","sources":["../src/components/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, nextTick, onBeforeUnmount, onMounted, ref, useAttrs, useCssModule, useSlots, watch } from 'vue';\n\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n\n export interface TextareaResizeOptions {\n /**\n * It will automatically scroll the page down when it reaches the bottom of the viewport/element\n */\n forceBrowserScroll: boolean;\n }\n\n export interface TextAreaProps extends FieldProps {\n /**\n * Value for the textarea element.\n */\n modelValue?: string;\n\n /**\n * Deprecated. Use :model-value or v-model instead of :value.\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Allow textarea to be resizable vertically.\n * Alternatively if you want to disable automatic scroll when resizing, you can set `{ forceBrowserScroll: false }`\n */\n resize?: boolean | TextareaResizeOptions;\n\n /**\n * Placeholder text for the textarea element.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n\n /**\n * Number of rows to display in the textarea.\n */\n rows?: number;\n }\n\n defineOptions({\n name: 'll-textarea',\n });\n\n const attrs = useAttrs();\n const slots = useSlots();\n const classes = useCssModule();\n\n const props = withDefaults(defineProps<TextAreaProps>(), {\n modelValue: '',\n value: null,\n resize: false,\n placeholder: undefined,\n });\n\n const emits = defineEmits<{\n /**\n * Emitted when the model value changes.\n */\n (e: 'update:model-value', value: string): void;\n }>();\n\n const textareaRef = ref<HTMLTextAreaElement>();\n const observer = ref<ResizeObserver>();\n const isReadOnly = computed(() => props.isReadOnly || ('readonly' in attrs && attrs.readonly !== false));\n\n const inputAttrs = computed(() => {\n const allAttrs = { ...attrs };\n\n delete allAttrs['data-test'];\n delete allAttrs.class;\n\n return allAttrs;\n });\n\n watch(\n () => props.resize,\n (v) => {\n v ? setupResizeObserver() : observer.value?.disconnect();\n },\n );\n\n const onInput = (event: Event) => {\n emits('update:model-value', (event.target as HTMLTextAreaElement).value);\n };\n\n const setupResizeObserver = () => {\n if (observer.value || !textareaRef.value) {\n return;\n }\n\n // the ResizeObserver will be in charge to detect if page needs to scroll when resizing the component\n observer.value = new ResizeObserver(([entry]) => {\n const { target } = entry;\n const parent = findParentScrollable(textareaRef.value as HTMLTextAreaElement) || document.documentElement;\n\n const { scrollTop: scrollPosition } = parent;\n let offsetDiff = 0;\n\n // checks if the closest parent element scrollable is the document page\n if (parent === document.documentElement) {\n const { top, height } = getOffsetClipRect(target as HTMLElement);\n const { innerHeight: viewportHeight } = window;\n\n offsetDiff = Math.max(top + height - (viewportHeight + scrollPosition), 0);\n } else {\n const { top, height } = (target as HTMLElement).getBoundingClientRect();\n const { top: parentTop } = parent.getBoundingClientRect();\n const { offsetHeight: parentHeight } = parent;\n const offsetTop = top - parentTop;\n\n offsetDiff = Math.max(offsetTop + height - parentHeight, 0);\n }\n\n if (offsetDiff) {\n requestAnimationFrame(() => {\n parent.scrollTop = scrollPosition + offsetDiff;\n });\n }\n });\n\n observer.value.observe(textareaRef.value);\n };\n\n /**\n * Retrieve the closest parent that has a scroll. Defaults to the document page.\n */\n const findParentScrollable = (el: HTMLElement): HTMLElement | null => {\n const parent = el.parentElement as HTMLElement;\n if (!parent) {\n return null;\n }\n\n const { overflowY } = getComputedStyle(parent);\n if (overflowY !== 'visible') {\n return parent;\n }\n\n if (parent === document.body) {\n return document.documentElement;\n }\n\n return findParentScrollable(parent);\n };\n\n /**\n * Retrieve element absolute positioning relative to the page.\n */\n const getOffsetClipRect = (el: HTMLElement) => {\n const { offsetWidth: width, offsetHeight: height } = el;\n\n let left = 0;\n let top = 0;\n\n const findPos = function ({ offsetLeft, offsetTop, offsetParent }: HTMLElement) {\n left += offsetLeft;\n top += offsetTop;\n\n if (offsetParent) {\n findPos(offsetParent as HTMLElement);\n }\n };\n\n findPos(el);\n\n return {\n top,\n left,\n width,\n height,\n };\n };\n\n onMounted(async () => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n\n if (\n (typeof props.resize === 'boolean' && props.resize) ||\n (props.resize as TextareaResizeOptions)?.forceBrowserScroll\n ) {\n await nextTick();\n setupResizeObserver();\n }\n });\n\n onBeforeUnmount(() => {\n observer.value?.disconnect();\n });\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-textarea\" :class=\"[classes.root]\" data-test=\"stash-textarea\">\n <template #default=\"{ fieldId, hasError }\">\n <textarea\n :id=\"fieldId\"\n ref=\"textareaRef\"\n :class=\"[\n classes.textarea,\n 'tw-border tw-border-ice-500',\n {\n 'stash-textarea--error tw-border-red-500 tw-text-red-500': hasError,\n 'tw-text-ice-700 hover:tw-border-ice-500 focus:tw-border-blue-500 active:tw-border-blue-500':\n !hasError && !props.disabled,\n 'tw-resize-y': props.resize,\n 'tw-min-h-[100px]': !props.rows,\n 'tw-resize-none': !props.resize,\n },\n ]\"\n :value=\"props.modelValue\"\n data-test=\"stash-textarea|textarea\"\n :placeholder=\"props.placeholder\"\n v-bind=\"inputAttrs\"\n :disabled=\"props.disabled\"\n :readonly=\"isReadOnly\"\n :rows=\"props.rows\"\n @input=\"onInput\"\n ></textarea>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <!-- @slot Hint content -->\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n width: 100%;\n }\n\n .textarea {\n background: var(--color-white);\n border-radius: theme('borderRadius.DEFAULT');\n display: block;\n outline: none;\n padding: theme('spacing[1.5]');\n width: 100%;\n\n &::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n &[disabled] {\n background-color: var(--color-ice-100);\n border-color: var(--color-ice-500);\n color: var(--color-ice-500);\n pointer-events: none;\n }\n\n &[disabled]:active,\n &[disabled]:focus {\n box-shadow: none;\n }\n\n &[disabled]::placeholder {\n text-transform: none;\n color: var(--color-ice-500);\n }\n\n &[readonly] {\n border-color: transparent;\n background-color: transparent;\n padding-left: 0;\n padding-right: 0;\n min-height: unset;\n }\n }\n</style>\n"],"names":["attrs","useAttrs","slots","useSlots","classes","useCssModule","props","__props","emits","__emit","textareaRef","ref","observer","isReadOnly","computed","inputAttrs","allAttrs","watch","v","setupResizeObserver","_a","onInput","event","entry","target","parent","findParentScrollable","scrollPosition","offsetDiff","top","height","getOffsetClipRect","viewportHeight","parentTop","parentHeight","offsetTop","el","overflowY","width","left","findPos","offsetLeft","offsetParent","onMounted","nextTick","onBeforeUnmount"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Textarea.js","sources":["../src/components/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\" setup>\n import { computed, nextTick, onBeforeUnmount, onMounted, ref, useAttrs, useCssModule, useSlots, watch } from 'vue';\n\n import { FieldProps } from '../Field/Field.types';\n import Field from '../Field/Field.vue';\n\n export interface TextareaResizeOptions {\n /**\n * It will automatically scroll the page down when it reaches the bottom of the viewport/element\n */\n forceBrowserScroll: boolean;\n }\n\n export interface TextAreaProps extends FieldProps {\n /**\n * Value for the textarea element.\n */\n modelValue?: string;\n\n /**\n * Deprecated. Use :model-value or v-model instead of :value.\n * @deprecated Use :model-value or v-model instead of :value.\n */\n value?: string | number | null;\n\n /**\n * Allow textarea to be resizable vertically.\n * Alternatively if you want to disable automatic scroll when resizing, you can set `{ forceBrowserScroll: false }`\n */\n resize?: boolean | TextareaResizeOptions;\n\n /**\n * Placeholder text for the textarea element.\n * **Note:** placeholders should be used to display examples; they should not be used as labels because they are not accessible as labels. If a real label cannot be used, use the `aria-label` attribute.\n */\n placeholder?: string;\n\n /**\n * Number of rows to display in the textarea.\n */\n rows?: number;\n\n /**\n * Maximum number of characters allowed in the textarea.\n */\n maxlength?: number;\n }\n\n defineOptions({\n name: 'll-textarea',\n });\n\n const attrs = useAttrs();\n const slots = useSlots();\n const classes = useCssModule();\n\n const props = withDefaults(defineProps<TextAreaProps>(), {\n modelValue: '',\n value: null,\n resize: false,\n maxlength: undefined,\n rows: undefined,\n placeholder: undefined,\n });\n\n const emits = defineEmits<{\n /**\n * Emitted when the model value changes.\n */\n (e: 'update:model-value', value: string): void;\n }>();\n\n const textareaRef = ref<HTMLTextAreaElement>();\n const observer = ref<ResizeObserver>();\n const isReadOnly = computed(() => props.isReadOnly || ('readonly' in attrs && attrs.readonly !== false));\n\n const inputAttrs = computed(() => {\n const allAttrs = { ...attrs };\n\n delete allAttrs['data-test'];\n delete allAttrs.class;\n\n return allAttrs;\n });\n\n watch(\n () => props.resize,\n (v) => {\n v ? setupResizeObserver() : observer.value?.disconnect();\n },\n );\n\n const onInput = (event: Event) => {\n emits('update:model-value', (event.target as HTMLTextAreaElement).value);\n };\n\n const setupResizeObserver = () => {\n if (observer.value || !textareaRef.value) {\n return;\n }\n\n // the ResizeObserver will be in charge to detect if page needs to scroll when resizing the component\n observer.value = new ResizeObserver(([entry]) => {\n const { target } = entry;\n const parent = findParentScrollable(textareaRef.value as HTMLTextAreaElement) || document.documentElement;\n\n const { scrollTop: scrollPosition } = parent;\n let offsetDiff = 0;\n\n // checks if the closest parent element scrollable is the document page\n if (parent === document.documentElement) {\n const { top, height } = getOffsetClipRect(target as HTMLElement);\n const { innerHeight: viewportHeight } = window;\n\n offsetDiff = Math.max(top + height - (viewportHeight + scrollPosition), 0);\n } else {\n const { top, height } = (target as HTMLElement).getBoundingClientRect();\n const { top: parentTop } = parent.getBoundingClientRect();\n const { offsetHeight: parentHeight } = parent;\n const offsetTop = top - parentTop;\n\n offsetDiff = Math.max(offsetTop + height - parentHeight, 0);\n }\n\n if (offsetDiff) {\n requestAnimationFrame(() => {\n parent.scrollTop = scrollPosition + offsetDiff;\n });\n }\n });\n\n observer.value.observe(textareaRef.value);\n };\n\n /**\n * Retrieve the closest parent that has a scroll. Defaults to the document page.\n */\n const findParentScrollable = (el: HTMLElement): HTMLElement | null => {\n const parent = el.parentElement as HTMLElement;\n if (!parent) {\n return null;\n }\n\n const { overflowY } = getComputedStyle(parent);\n if (overflowY !== 'visible') {\n return parent;\n }\n\n if (parent === document.body) {\n return document.documentElement;\n }\n\n return findParentScrollable(parent);\n };\n\n /**\n * Retrieve element absolute positioning relative to the page.\n */\n const getOffsetClipRect = (el: HTMLElement) => {\n const { offsetWidth: width, offsetHeight: height } = el;\n\n let left = 0;\n let top = 0;\n\n const findPos = function ({ offsetLeft, offsetTop, offsetParent }: HTMLElement) {\n left += offsetLeft;\n top += offsetTop;\n\n if (offsetParent) {\n findPos(offsetParent as HTMLElement);\n }\n };\n\n findPos(el);\n\n return {\n top,\n left,\n width,\n height,\n };\n };\n\n onMounted(async () => {\n if (props.value !== null) {\n throw new Error('ll-input: use :model-value or v-model instead of :value.');\n }\n\n if (attrs.onInput) {\n throw new Error('ll-input: use the @update:model-value event instead of @input');\n }\n\n if (\n (typeof props.resize === 'boolean' && props.resize) ||\n (props.resize as TextareaResizeOptions)?.forceBrowserScroll\n ) {\n await nextTick();\n setupResizeObserver();\n }\n });\n\n onBeforeUnmount(() => {\n observer.value?.disconnect();\n });\n</script>\n\n<template>\n <Field v-bind=\"props\" class=\"stash-textarea\" :class=\"[classes.root]\" data-test=\"stash-textarea\">\n <template #default=\"{ fieldId, hasError }\">\n <textarea\n :id=\"fieldId\"\n ref=\"textareaRef\"\n :class=\"[\n classes.textarea,\n 'tw-border tw-border-ice-500',\n {\n 'stash-textarea--error tw-border-red-500 tw-text-red-500': hasError,\n 'tw-text-ice-700 hover:tw-border-ice-500 focus:tw-border-blue-500 active:tw-border-blue-500':\n !hasError && !props.disabled,\n 'tw-resize-y': props.resize,\n 'tw-min-h-[100px]': !props.rows,\n 'tw-resize-none': !props.resize,\n },\n ]\"\n :maxlength=\"props.maxlength\"\n :value=\"props.modelValue\"\n data-test=\"stash-textarea|textarea\"\n :placeholder=\"props.placeholder\"\n v-bind=\"inputAttrs\"\n :disabled=\"props.disabled\"\n :readonly=\"isReadOnly\"\n :rows=\"props.rows\"\n @input=\"onInput\"\n ></textarea>\n </template>\n <template v-if=\"slots.hint\" #hint>\n <!-- @slot Hint content -->\n <slot name=\"hint\"></slot>\n </template>\n </Field>\n</template>\n\n<style module>\n .root {\n position: relative;\n width: 100%;\n }\n\n .textarea {\n background: var(--color-white);\n border-radius: theme('borderRadius.DEFAULT');\n display: block;\n outline: none;\n padding: theme('spacing[1.5]');\n width: 100%;\n\n &::placeholder {\n color: var(--color-ice-500);\n opacity: 1;\n }\n\n &[disabled] {\n background-color: var(--color-ice-100);\n border-color: var(--color-ice-500);\n color: var(--color-ice-500);\n pointer-events: none;\n }\n\n &[disabled]:active,\n &[disabled]:focus {\n box-shadow: none;\n }\n\n &[disabled]::placeholder {\n text-transform: none;\n color: var(--color-ice-500);\n }\n\n &[readonly] {\n border-color: transparent;\n background-color: transparent;\n padding-left: 0;\n padding-right: 0;\n min-height: unset;\n }\n }\n</style>\n"],"names":["attrs","useAttrs","slots","useSlots","classes","useCssModule","props","__props","emits","__emit","textareaRef","ref","observer","isReadOnly","computed","inputAttrs","allAttrs","watch","v","setupResizeObserver","_a","onInput","event","entry","target","parent","findParentScrollable","scrollPosition","offsetDiff","top","height","getOffsetClipRect","viewportHeight","parentTop","parentHeight","offsetTop","el","overflowY","width","left","findPos","offsetLeft","offsetParent","onMounted","nextTick","onBeforeUnmount"],"mappings":"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"}
|
package/dist/Textarea.vue.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ declare const _default: __VLS_WithTemplateSlots<DefineComponent<ExtractPropTypes
|
|
|
36
36
|
modelValue: string;
|
|
37
37
|
value: null;
|
|
38
38
|
resize: boolean;
|
|
39
|
+
maxlength: undefined;
|
|
40
|
+
rows: undefined;
|
|
39
41
|
placeholder: undefined;
|
|
40
42
|
}>>, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {
|
|
41
43
|
"update:model-value": (value: string) => void;
|
|
@@ -43,6 +45,8 @@ placeholder: undefined;
|
|
|
43
45
|
modelValue: string;
|
|
44
46
|
value: null;
|
|
45
47
|
resize: boolean;
|
|
48
|
+
maxlength: undefined;
|
|
49
|
+
rows: undefined;
|
|
46
50
|
placeholder: undefined;
|
|
47
51
|
}>>> & Readonly<{
|
|
48
52
|
"onUpdate:model-value"?: ((value: string) => any) | undefined;
|
|
@@ -51,6 +55,8 @@ resize: boolean | TextareaResizeOptions;
|
|
|
51
55
|
placeholder: string;
|
|
52
56
|
modelValue: string;
|
|
53
57
|
value: string | number | null;
|
|
58
|
+
maxlength: number;
|
|
59
|
+
rows: number;
|
|
54
60
|
}, {}, {}, {}, string, ComponentProvideOptions, true, {}, any>, {
|
|
55
61
|
hint?(_: {}): any;
|
|
56
62
|
}>;
|
|
@@ -133,6 +139,10 @@ export declare interface TextAreaProps extends FieldProps {
|
|
|
133
139
|
* Number of rows to display in the textarea.
|
|
134
140
|
*/
|
|
135
141
|
rows?: number;
|
|
142
|
+
/**
|
|
143
|
+
* Maximum number of characters allowed in the textarea.
|
|
144
|
+
*/
|
|
145
|
+
maxlength?: number;
|
|
136
146
|
}
|
|
137
147
|
|
|
138
148
|
export declare interface TextareaResizeOptions {
|