nuance-ui 0.2.18 → 0.2.19
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/module.json +1 -1
- package/dist/runtime/components/center.d.vue.ts +18 -0
- package/dist/runtime/components/center.vue +26 -0
- package/dist/runtime/components/center.vue.d.ts +18 -0
- package/dist/runtime/components/group.d.vue.ts +28 -0
- package/dist/runtime/components/group.vue +39 -0
- package/dist/runtime/components/group.vue.d.ts +28 -0
- package/dist/runtime/components/input/ui/input-base.d.vue.ts +1 -0
- package/dist/runtime/components/input/ui/input-base.vue +3 -2
- package/dist/runtime/components/input/ui/input-base.vue.d.ts +1 -0
- package/dist/runtime/components/pin-input/lib.d.ts +2 -0
- package/dist/runtime/components/pin-input/lib.js +19 -0
- package/dist/runtime/components/pin-input/pin-input.d.vue.ts +55 -0
- package/dist/runtime/components/pin-input/pin-input.vue +171 -0
- package/dist/runtime/components/pin-input/pin-input.vue.d.ts +55 -0
- package/dist/runtime/components/pin-input/use-pin-input.d.ts +18 -0
- package/dist/runtime/components/pin-input/use-pin-input.js +94 -0
- package/dist/runtime/components/stack.d.vue.ts +24 -0
- package/dist/runtime/components/stack.vue +33 -0
- package/dist/runtime/components/stack.vue.d.ts +24 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BoxProps } from './box.vue.js';
|
|
2
|
+
export interface CenterProps extends BoxProps {
|
|
3
|
+
/** If set, `inline-flex` is used instead of `flex` */
|
|
4
|
+
inline?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare var __VLS_8: {};
|
|
7
|
+
type __VLS_Slots = {} & {
|
|
8
|
+
default?: (props: typeof __VLS_8) => any;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_base: import("vue").DefineComponent<CenterProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CenterProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
14
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
15
|
+
new (): {
|
|
16
|
+
$slots: S;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import Box from "./box.vue";
|
|
3
|
+
const {
|
|
4
|
+
inline,
|
|
5
|
+
mod,
|
|
6
|
+
...props
|
|
7
|
+
} = defineProps({
|
|
8
|
+
inline: { type: Boolean, required: false },
|
|
9
|
+
is: { type: null, required: false },
|
|
10
|
+
mod: { type: [Object, Array, null], required: false }
|
|
11
|
+
});
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<Box
|
|
16
|
+
v-bind='props'
|
|
17
|
+
:class='$style.root'
|
|
18
|
+
:mod='[{ inline }, mod]'
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</Box>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<style module>
|
|
25
|
+
.root{align-items:center;display:flex;justify-content:center}.root:where([data-inline]){display:inline-flex}
|
|
26
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { BoxProps } from './box.vue.js';
|
|
2
|
+
export interface CenterProps extends BoxProps {
|
|
3
|
+
/** If set, `inline-flex` is used instead of `flex` */
|
|
4
|
+
inline?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare var __VLS_8: {};
|
|
7
|
+
type __VLS_Slots = {} & {
|
|
8
|
+
default?: (props: typeof __VLS_8) => any;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_base: import("vue").DefineComponent<CenterProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<CenterProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
11
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
14
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
15
|
+
new (): {
|
|
16
|
+
$slots: S;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
import type { NuanceSpacing } from '../types/index.js';
|
|
3
|
+
import type { BoxProps } from './box.vue.js';
|
|
4
|
+
export interface GroupProps extends BoxProps {
|
|
5
|
+
/** Controls `justify-content` CSS property @default 'flex-start' */
|
|
6
|
+
justify?: CSSProperties['justifyContent'];
|
|
7
|
+
/** Controls `align-items` CSS property @default 'center' */
|
|
8
|
+
align?: CSSProperties['alignItems'];
|
|
9
|
+
/** Controls `flex-wrap` CSS property @default 'wrap' */
|
|
10
|
+
wrap?: CSSProperties['flexWrap'];
|
|
11
|
+
/** Key of `theme.spacing` or any valid CSS value for `gap`, numbers are converted to rem @default 'md' */
|
|
12
|
+
gap?: NuanceSpacing;
|
|
13
|
+
/** Determines whether each child element should have `flex-grow: 1` style @default false */
|
|
14
|
+
grow?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare var __VLS_8: {};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
default?: (props: typeof __VLS_8) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_base: import("vue").DefineComponent<GroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<GroupProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
24
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
25
|
+
new (): {
|
|
26
|
+
$slots: S;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { getSpacing, useVarsResolver } from "#imports";
|
|
3
|
+
import Box from "./box.vue";
|
|
4
|
+
const {
|
|
5
|
+
grow,
|
|
6
|
+
justify,
|
|
7
|
+
align,
|
|
8
|
+
wrap,
|
|
9
|
+
gap,
|
|
10
|
+
mod,
|
|
11
|
+
...props
|
|
12
|
+
} = defineProps({
|
|
13
|
+
justify: { type: void 0, required: false },
|
|
14
|
+
align: { type: void 0, required: false },
|
|
15
|
+
wrap: { type: void 0, required: false },
|
|
16
|
+
gap: { type: [String, Number], required: false },
|
|
17
|
+
grow: { type: Boolean, required: false },
|
|
18
|
+
is: { type: null, required: false },
|
|
19
|
+
mod: { type: [Object, Array, null], required: false }
|
|
20
|
+
});
|
|
21
|
+
const style = useVarsResolver(() => ({
|
|
22
|
+
root: {
|
|
23
|
+
"--group-gap": getSpacing(gap),
|
|
24
|
+
"--group-align": align ?? void 0,
|
|
25
|
+
"--group-justify": justify ?? void 0,
|
|
26
|
+
"--group-wrap": wrap ?? void 0
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<Box v-bind='props' :style='style.root' :class='$style.root' :mod='[{ grow }, mod]'>
|
|
33
|
+
<slot />
|
|
34
|
+
</Box>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<style module>
|
|
38
|
+
.root{align-items:var(--group-align,center);display:flex;flex-direction:row;flex-wrap:var(--group-wrap,wrap);gap:var(--group-gap,var(--spacing-md));justify-content:var(--group-justify,flex-start)}.root:where([data-grow])>*{flex-grow:1}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
import type { NuanceSpacing } from '../types/index.js';
|
|
3
|
+
import type { BoxProps } from './box.vue.js';
|
|
4
|
+
export interface GroupProps extends BoxProps {
|
|
5
|
+
/** Controls `justify-content` CSS property @default 'flex-start' */
|
|
6
|
+
justify?: CSSProperties['justifyContent'];
|
|
7
|
+
/** Controls `align-items` CSS property @default 'center' */
|
|
8
|
+
align?: CSSProperties['alignItems'];
|
|
9
|
+
/** Controls `flex-wrap` CSS property @default 'wrap' */
|
|
10
|
+
wrap?: CSSProperties['flexWrap'];
|
|
11
|
+
/** Key of `theme.spacing` or any valid CSS value for `gap`, numbers are converted to rem @default 'md' */
|
|
12
|
+
gap?: NuanceSpacing;
|
|
13
|
+
/** Determines whether each child element should have `flex-grow: 1` style @default false */
|
|
14
|
+
grow?: boolean;
|
|
15
|
+
}
|
|
16
|
+
declare var __VLS_8: {};
|
|
17
|
+
type __VLS_Slots = {} & {
|
|
18
|
+
default?: (props: typeof __VLS_8) => any;
|
|
19
|
+
};
|
|
20
|
+
declare const __VLS_base: import("vue").DefineComponent<GroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<GroupProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
22
|
+
declare const _default: typeof __VLS_export;
|
|
23
|
+
export default _default;
|
|
24
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
25
|
+
new (): {
|
|
26
|
+
$slots: S;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -5,6 +5,7 @@ import Box from "../../box.vue";
|
|
|
5
5
|
import { useInputWrapperState } from "../lib/input-wrapper.context";
|
|
6
6
|
const { classes, ...props } = defineProps({
|
|
7
7
|
classes: { type: Object, required: false },
|
|
8
|
+
error: { type: Boolean, required: false },
|
|
8
9
|
required: { type: Boolean, required: false },
|
|
9
10
|
radius: { type: [String, Number, Object], required: false },
|
|
10
11
|
size: { type: [String, Object], required: false },
|
|
@@ -35,7 +36,7 @@ const style = computed(() => ({
|
|
|
35
36
|
"with-left-section": !!$slots.leftSection,
|
|
36
37
|
"with-right-section": !!$slots.rightSection,
|
|
37
38
|
"variant": api.variant,
|
|
38
|
-
"error": !!api?.error
|
|
39
|
+
"error": !!api?.error || props.error
|
|
39
40
|
}]'
|
|
40
41
|
>
|
|
41
42
|
<span
|
|
@@ -59,5 +60,5 @@ const style = computed(() => ({
|
|
|
59
60
|
</template>
|
|
60
61
|
|
|
61
62
|
<style module>
|
|
62
|
-
.root{--input-height-xs:rem(30px);--input-height-sm:rem(36px);--input-height-md:rem(42px);--input-height-lg:rem(50px);--input-height-xl:rem(60px);--input-padding-y-xs:rem(5px);--input-padding-y-sm:rem(6px);--input-padding-y-md:rem(8px);--input-padding-y-lg:rem(10px);--input-padding-y-xl:rem(13px);--input-height:var(--input-height-sm);--input-radius:var(--radius-default);--input-cursor:text;--input-text-align:left;--input-line-height:calc(var(--input-height) - rem(2px));--input-padding:calc(var(--input-height)/3);--input-padding-inline-start:var(--input-padding);--input-padding-inline-end:var(--input-padding);--input-placeholder-color:var(--color-placeholder);--input-color:var(--color-text);--input-left-section-width:calc(var(--input-height) - rem(2px));--input-right-section-width:calc(var(--input-height) - rem(2px));--input-left-section-pointer-events:none;--input-right-section-pointer-events:none;--input-left-section-size:var(--input-left-section-width);--input-right-section-size:var(--input-right-section-width);--input-fz:var(--font-size-sm);--input-size:var(--input-height);--input-resize:none;--section-y:1px;--left-section-start:1px;--left-section-border-radius:var(--input-radius) 0 0 var(--input-radius);--right-section-end:1px;--right-section-border-radius:0 var(--input-radius) var(--input-radius) 0;position:relative}.root[data-variant=unstyled]{--input-padding:0;--input-padding-y:0;--input-padding-inline-start:0;--input-padding-inline-end:0}.root[data-pointer]{--input-cursor:pointer}.root[data-multiline]{--input-padding-y-xs:4.5px;--input-padding-y-sm:5.5px;--input-padding-y-md:7px;--input-padding-y-lg:9.5px;--input-padding-y-xl:13px;--input-size:auto;--input-line-height:var(--line-height);--input-padding-y:var(--input-padding-y-sm)}.root[data-with-left-section]{--input-padding-inline-start:var(--input-left-section-size)}.root[data-with-right-section]{--input-padding-inline-end:var(--input-right-section-size)}.root
|
|
63
|
+
.root{--input-height-xs:rem(30px);--input-height-sm:rem(36px);--input-height-md:rem(42px);--input-height-lg:rem(50px);--input-height-xl:rem(60px);--input-padding-y-xs:rem(5px);--input-padding-y-sm:rem(6px);--input-padding-y-md:rem(8px);--input-padding-y-lg:rem(10px);--input-padding-y-xl:rem(13px);--input-height:var(--input-height-sm);--input-radius:var(--radius-default);--input-cursor:text;--input-text-align:left;--input-line-height:calc(var(--input-height) - rem(2px));--input-padding:calc(var(--input-height)/3);--input-padding-inline-start:var(--input-padding);--input-padding-inline-end:var(--input-padding);--input-placeholder-color:var(--color-placeholder);--input-color:var(--color-text);--input-left-section-width:calc(var(--input-height) - rem(2px));--input-right-section-width:calc(var(--input-height) - rem(2px));--input-left-section-pointer-events:none;--input-right-section-pointer-events:none;--input-left-section-size:var(--input-left-section-width);--input-right-section-size:var(--input-right-section-width);--input-fz:var(--font-size-sm);--input-size:var(--input-height);--input-resize:none;--section-y:1px;--left-section-start:1px;--left-section-border-radius:var(--input-radius) 0 0 var(--input-radius);--right-section-end:1px;--right-section-border-radius:0 var(--input-radius) var(--input-radius) 0;position:relative}.root[data-variant=unstyled]{--input-padding:0;--input-padding-y:0;--input-padding-inline-start:0;--input-padding-inline-end:0}.root[data-pointer]{--input-cursor:pointer}.root[data-multiline]{--input-padding-y-xs:4.5px;--input-padding-y-sm:5.5px;--input-padding-y-md:7px;--input-padding-y-lg:9.5px;--input-padding-y-xl:13px;--input-size:auto;--input-line-height:var(--line-height);--input-padding-y:var(--input-padding-y-sm)}.root[data-with-left-section]{--input-padding-inline-start:var(--input-left-section-size)}.root[data-with-right-section]{--input-padding-inline-end:var(--input-right-section-size)}.root{@mixin where-light{--input-disabled-bg:var(--color-gray-1);--input-disabled-color:var(--color-gray-6);&[data-variant=default]:not(&[data-error]){--input-bd:var(--color-gray-4);--input-bg:var(--color-white);--input-bd-focus:var(--color-primary-filled)}&[data-variant=filled]:not(&[data-error]){--input-bd:transparent;--input-bg:var(--color-gray-1);--input-bd-focus:var(--color-primary-filled)}&[data-variant=unstyled]:not(&[data-error]){--input-bd:transparent;--input-bg:transparent;--input-bd-focus:transparent}}}.root{@mixin where-dark{--input-disabled-bg:var(--color-dark-6);--input-disabled-color:var(--color-dark-2);&[data-variant=default]:not(&[data-error]){--input-bd:var(--color-dark-4);--input-bg:var(--color-dark-6);--input-bd-focus:var(--color-primary-filled)}&[data-variant=filled]:not(&[data-error]){--input-bd:transparent;--input-bg:var(--color-dark-5);--input-bd-focus:var(--color-primary-filled)}&[data-variant=unstyled]:not(&[data-error]){--input-bd:transparent;--input-bg:transparent;--input-bd-focus:transparent}}}.root[data-error]{--input-color:var(--color-error);--input-placeholder-color:var(--color-error);--input-section-color:var(--color-error);--input-bd:var(--color-error)}.root{@mixin where-rtl{--input-text-align:right;--left-section-border-radius:0 var(--input-radius) var(--input-radius) 0;--right-section-border-radius:var(--input-radius) 0 0 var(--input-radius)}}.input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--input-bg);border:rem(1px) solid var(--input-bd);border-radius:var(--input-radius);color:var(--input-color);cursor:var(--input-cursor);display:block;font-family:var(--font-family),serif;font-size:var(--input-fz);height:var(--input-size);line-height:var(--input-line-height);min-height:var(--input-height);overflow:var(--input-overflow);padding-bottom:var(--input-padding-y,0);padding-inline-end:var(--input-padding-inline-end);padding-top:var(--input-padding-y,0);padding-inline-start:var(--input-padding-inline-start);resize:var(--input-resize,none);text-align:var(--input-text-align);transition:border-color .1s ease;width:100%;-webkit-tap-highlight-color:transparent}.input[data-no-overflow]{--input-overflow:hidden}.input:focus,.input:focus-within{--input-bd:var(--input-bd-focus);outline:none}[data-error] .input:focus,[data-error] .input:focus-within{--input-bd:var(--color-error)}.input::-moz-placeholder{color:var(--input-placeholder-color);opacity:1}.input::placeholder{color:var(--input-placeholder-color);opacity:1}.input::-webkit-inner-spin-button,.input::-webkit-outer-spin-button,.input::-webkit-search-cancel-button,.input::-webkit-search-decoration,.input::-webkit-search-results-button,.input::-webkit-search-results-decoration{-webkit-appearance:none;appearance:none}.input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.input:disabled,.input:has(input:disabled),.input[data-disabled]{background-color:var(--input-disabled-bg);color:var(--input-disabled-color);cursor:not-allowed;opacity:.6}.input:-moz-read-only{cursor:default}.input:read-only{cursor:default}.section{align-items:center;border-radius:var(--section-border-radius);bottom:var(--section-y);color:var(--input-section-color,var(--color-dimmed));display:flex;inset-inline-end:var(--section-end);inset-inline-start:var(--section-start);justify-content:center;pointer-events:var(--section-pointer-events);position:absolute;top:var(--section-y);width:var(--section-size);z-index:1}.section[data-position=right]{--section-pointer-events:var(--input-right-section-pointer-events);--section-end:var(--right-section-end);--section-size:var(--input-right-section-size);--section-border-radius:var(--right-section-border-radius)}.section[data-position=left]{--section-pointer-events:var(--input-left-section-pointer-events);--section-start:var(--left-section-start);--section-size:var(--input-left-section-size);--section-border-radius:var(--left-section-border-radius)}
|
|
63
64
|
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const regex = {
|
|
2
|
+
number: /^\d+$/,
|
|
3
|
+
alphanumeric: /^[a-z0-9]+$/i
|
|
4
|
+
};
|
|
5
|
+
export function pinValidate(code, type) {
|
|
6
|
+
const re = type instanceof RegExp ? type : regex[type] ?? null;
|
|
7
|
+
return re?.test(code);
|
|
8
|
+
}
|
|
9
|
+
export function createPinArray(length, value) {
|
|
10
|
+
if (length < 1)
|
|
11
|
+
return [];
|
|
12
|
+
const values = Array.from({ length }).fill("");
|
|
13
|
+
if (value) {
|
|
14
|
+
const splitted = value.trim().split("");
|
|
15
|
+
for (let i = 0; i < Math.min(length, splitted.length); i += 1)
|
|
16
|
+
values[i] = splitted[i] === " " ? "" : splitted[i];
|
|
17
|
+
}
|
|
18
|
+
return values;
|
|
19
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NuanceRadius, NuanceSize, NuanceSpacing } from '../../types/index.js';
|
|
2
|
+
import type { BoxProps } from '../box.vue.js';
|
|
3
|
+
export interface PinInputEmits {
|
|
4
|
+
complete: [value: string];
|
|
5
|
+
}
|
|
6
|
+
export interface PinInputProps extends BoxProps {
|
|
7
|
+
/** Id auto-generated if not provided */
|
|
8
|
+
id?: string;
|
|
9
|
+
/** Hidden input `name` attribute */
|
|
10
|
+
name?: string;
|
|
11
|
+
/** Key of `theme.spacing` or any valid CSS value to set `gap` between inputs, numbers are converted to rem @default 'md' */
|
|
12
|
+
gap?: NuanceSpacing;
|
|
13
|
+
/** Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem @default 'md' */
|
|
14
|
+
radius?: NuanceRadius;
|
|
15
|
+
/** Controls inputs `width` and `height` @default 'sm' */
|
|
16
|
+
size?: NuanceSize;
|
|
17
|
+
/** If set, the first input is focused when component is mounted @default false */
|
|
18
|
+
autoFocus?: boolean;
|
|
19
|
+
/** Inputs placeholder */
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
/** Determines whether focus should be moved automatically to the next input once filled @default true */
|
|
22
|
+
manageFocus?: boolean;
|
|
23
|
+
/** Determines whether `autocomplete="one-time-code"` attribute should be set on all inputs @default true */
|
|
24
|
+
otp?: boolean;
|
|
25
|
+
/** Adds disabled attribute to all inputs */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Sets `aria-invalid` attribute and applies error styles to all inputs */
|
|
28
|
+
error?: boolean;
|
|
29
|
+
/** Determines which values can be entered @default 'alphanumeric' */
|
|
30
|
+
type?: 'alphanumeric' | 'number' | RegExp;
|
|
31
|
+
/** Changes input type to `"password"` @default false */
|
|
32
|
+
mask?: boolean;
|
|
33
|
+
/** Number of inputs @default 4 */
|
|
34
|
+
length?: number;
|
|
35
|
+
/** If set, the user cannot edit the value */
|
|
36
|
+
readOnly?: boolean;
|
|
37
|
+
/** `aria-label` attribute */
|
|
38
|
+
ariaLabel?: string;
|
|
39
|
+
/** Marks the field as required */
|
|
40
|
+
required?: boolean;
|
|
41
|
+
}
|
|
42
|
+
type __VLS_Props = PinInputProps;
|
|
43
|
+
type __VLS_ModelProps = {
|
|
44
|
+
modelValue?: string;
|
|
45
|
+
};
|
|
46
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
47
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
+
"update:modelValue": (value: string) => any;
|
|
49
|
+
complete: (value: string) => any;
|
|
50
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
52
|
+
onComplete?: ((value: string) => any) | undefined;
|
|
53
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
54
|
+
declare const _default: typeof __VLS_export;
|
|
55
|
+
export default _default;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useVarsResolver } from "@nui/composables";
|
|
3
|
+
import { getSize } from "@nui/utils";
|
|
4
|
+
import { computed, useId } from "vue";
|
|
5
|
+
import Group from "../group.vue";
|
|
6
|
+
import InputBase from "../input/ui/input-base.vue";
|
|
7
|
+
import VisuallyHiddenInput from "../visually-hidden/visually-hidden-input.vue";
|
|
8
|
+
import { createPinArray, pinValidate } from "./lib";
|
|
9
|
+
import { usePinInput } from "./use-pin-input";
|
|
10
|
+
const {
|
|
11
|
+
id,
|
|
12
|
+
name,
|
|
13
|
+
disabled,
|
|
14
|
+
required,
|
|
15
|
+
length = 4,
|
|
16
|
+
otp = true,
|
|
17
|
+
type = "number",
|
|
18
|
+
mask,
|
|
19
|
+
gap,
|
|
20
|
+
placeholder,
|
|
21
|
+
autoFocus,
|
|
22
|
+
manageFocus = true,
|
|
23
|
+
size,
|
|
24
|
+
radius = "md",
|
|
25
|
+
readOnly,
|
|
26
|
+
error
|
|
27
|
+
} = defineProps({
|
|
28
|
+
id: { type: String, required: false },
|
|
29
|
+
name: { type: String, required: false },
|
|
30
|
+
gap: { type: [String, Number], required: false },
|
|
31
|
+
radius: { type: [String, Number], required: false },
|
|
32
|
+
size: { type: String, required: false },
|
|
33
|
+
autoFocus: { type: Boolean, required: false },
|
|
34
|
+
placeholder: { type: String, required: false },
|
|
35
|
+
manageFocus: { type: Boolean, required: false },
|
|
36
|
+
otp: { type: Boolean, required: false },
|
|
37
|
+
disabled: { type: Boolean, required: false },
|
|
38
|
+
error: { type: Boolean, required: false },
|
|
39
|
+
type: { type: null, required: false },
|
|
40
|
+
mask: { type: Boolean, required: false },
|
|
41
|
+
length: { type: Number, required: false },
|
|
42
|
+
readOnly: { type: Boolean, required: false },
|
|
43
|
+
ariaLabel: { type: String, required: false },
|
|
44
|
+
required: { type: Boolean, required: false },
|
|
45
|
+
is: { type: null, required: false },
|
|
46
|
+
mod: { type: [Object, Array, null], required: false }
|
|
47
|
+
});
|
|
48
|
+
defineEmits(["complete"]);
|
|
49
|
+
const uuid = computed(() => id ?? useId());
|
|
50
|
+
const inputMode = computed(() => type === "number" ? "numeric" : "text");
|
|
51
|
+
const model = defineModel({ type: String, ...{ default: "" } });
|
|
52
|
+
const {
|
|
53
|
+
refs,
|
|
54
|
+
focus,
|
|
55
|
+
focusedIx,
|
|
56
|
+
cells,
|
|
57
|
+
setFieldValue,
|
|
58
|
+
handleKeydown
|
|
59
|
+
} = usePinInput({
|
|
60
|
+
length: () => length,
|
|
61
|
+
manageFocus,
|
|
62
|
+
value: model,
|
|
63
|
+
inputMode
|
|
64
|
+
});
|
|
65
|
+
function handleInput(event, ix) {
|
|
66
|
+
const target = event.target;
|
|
67
|
+
const inputValue = target.value;
|
|
68
|
+
if (inputValue.length > 1) {
|
|
69
|
+
const isPaste = inputValue.length > 2;
|
|
70
|
+
if (isPaste) {
|
|
71
|
+
const isValid = pinValidate(inputValue, type);
|
|
72
|
+
if (!isValid)
|
|
73
|
+
return;
|
|
74
|
+
cells.value = createPinArray(length, inputValue);
|
|
75
|
+
const filledCount = Math.min(inputValue.length, length);
|
|
76
|
+
if (filledCount < length)
|
|
77
|
+
focus("next", filledCount - 1);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const newChar = inputValue.split("")[inputValue.length - 1];
|
|
81
|
+
if (pinValidate(newChar, type)) {
|
|
82
|
+
setFieldValue(newChar, ix);
|
|
83
|
+
focus("next", ix);
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (inputValue.length === 1) {
|
|
88
|
+
if (pinValidate(inputValue, type)) {
|
|
89
|
+
setFieldValue(inputValue, ix);
|
|
90
|
+
focus("next", ix);
|
|
91
|
+
} else {
|
|
92
|
+
setFieldValue("", ix);
|
|
93
|
+
}
|
|
94
|
+
} else if (inputValue.length === 0) {
|
|
95
|
+
setFieldValue("", ix);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function handlePaste(event) {
|
|
99
|
+
const pasteData = event.clipboardData?.getData("text/plain").replace(/\s+/g, "").trim();
|
|
100
|
+
const isValid = pinValidate(pasteData, type);
|
|
101
|
+
if (!isValid)
|
|
102
|
+
return;
|
|
103
|
+
const pasteArray = createPinArray(length, pasteData);
|
|
104
|
+
cells.value = pasteArray;
|
|
105
|
+
const filledCount = pasteArray.filter((v) => v !== "").length;
|
|
106
|
+
const focusIx = filledCount >= length ? length - 1 : filledCount;
|
|
107
|
+
refs.value[focusIx]?.focus();
|
|
108
|
+
}
|
|
109
|
+
const style = useVarsResolver(() => ({
|
|
110
|
+
root: {
|
|
111
|
+
"--pin-size": getSize(size, "pin-size"),
|
|
112
|
+
"--pin-fz": getSize(size, "pin-fz")
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<template>
|
|
118
|
+
<Group
|
|
119
|
+
role='group'
|
|
120
|
+
wrap='nowrap'
|
|
121
|
+
:gap
|
|
122
|
+
dir='ltr'
|
|
123
|
+
:class='$style.root'
|
|
124
|
+
:style='style.root'
|
|
125
|
+
>
|
|
126
|
+
<InputBase
|
|
127
|
+
v-for='(ids, ix) in length'
|
|
128
|
+
:id='`${uuid}-${ix + 1}`'
|
|
129
|
+
:key='ids'
|
|
130
|
+
:error
|
|
131
|
+
:class='$style.pinRoot'
|
|
132
|
+
:radius
|
|
133
|
+
>
|
|
134
|
+
<template #default='{ id: _id, css }'>
|
|
135
|
+
<input
|
|
136
|
+
:id='_id'
|
|
137
|
+
:key='ids'
|
|
138
|
+
:ref='refs.set'
|
|
139
|
+
:class='[css, $style.pin]'
|
|
140
|
+
:value='cells[ix]'
|
|
141
|
+
:autocomplete='otp ? "one-time-code" : void 0'
|
|
142
|
+
:input-mode
|
|
143
|
+
:type='mask ? "password" : "text"'
|
|
144
|
+
:placeholder
|
|
145
|
+
:auto-focus='autoFocus && ix === 0'
|
|
146
|
+
:readonly='readOnly'
|
|
147
|
+
:disabled
|
|
148
|
+
@input='handleInput($event, ix)'
|
|
149
|
+
@focus='(event) => {
|
|
150
|
+
if (!readOnly) {
|
|
151
|
+
event.target?.select();
|
|
152
|
+
focusedIx = ix;
|
|
153
|
+
}
|
|
154
|
+
}'
|
|
155
|
+
@blur='focusedIx = -1'
|
|
156
|
+
@paste.prevent='handlePaste'
|
|
157
|
+
@keydown='handleKeydown($event, ix)'
|
|
158
|
+
>
|
|
159
|
+
</template>
|
|
160
|
+
</InputBase>
|
|
161
|
+
</Group>
|
|
162
|
+
<VisuallyHiddenInput
|
|
163
|
+
:name
|
|
164
|
+
:disabled
|
|
165
|
+
:required
|
|
166
|
+
/>
|
|
167
|
+
</template>
|
|
168
|
+
|
|
169
|
+
<style module>
|
|
170
|
+
.root{--pin-size-xs:rem(30px);--pin-size-sm:rem(36px);--pin-size-md:rem(42px);--pin-size-lg:rem(50px);--pin-size-xl:rem(60px);--pin-size:var(--pin-size-sm);--pin-fz-xs:1.125rem;--pin-fz-sm:1.5rem;--pin-fz-md:1.75rem;--pin-fz-lg:2rem;--pin-fz-xl:2.5rem;--pin-fz:var(--pin-fz-sm)}.pinRoot{@mixin where-light{--input-bd:var(--color-gray-2);--input-bg:var(--color-gray-0)}@mixin where-dark{--input-bd:var(--color-gray-7);--input-bg:var(--color-dark-9)}}.pin{font-size:var(--pin-fz);font-weight:600;height:calc(var(--pin-size) + var(--pin-size)/3);line-height:1;padding:0;text-align:center;width:var(--pin-size)}
|
|
171
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { NuanceRadius, NuanceSize, NuanceSpacing } from '../../types/index.js';
|
|
2
|
+
import type { BoxProps } from '../box.vue.js';
|
|
3
|
+
export interface PinInputEmits {
|
|
4
|
+
complete: [value: string];
|
|
5
|
+
}
|
|
6
|
+
export interface PinInputProps extends BoxProps {
|
|
7
|
+
/** Id auto-generated if not provided */
|
|
8
|
+
id?: string;
|
|
9
|
+
/** Hidden input `name` attribute */
|
|
10
|
+
name?: string;
|
|
11
|
+
/** Key of `theme.spacing` or any valid CSS value to set `gap` between inputs, numbers are converted to rem @default 'md' */
|
|
12
|
+
gap?: NuanceSpacing;
|
|
13
|
+
/** Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem @default 'md' */
|
|
14
|
+
radius?: NuanceRadius;
|
|
15
|
+
/** Controls inputs `width` and `height` @default 'sm' */
|
|
16
|
+
size?: NuanceSize;
|
|
17
|
+
/** If set, the first input is focused when component is mounted @default false */
|
|
18
|
+
autoFocus?: boolean;
|
|
19
|
+
/** Inputs placeholder */
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
/** Determines whether focus should be moved automatically to the next input once filled @default true */
|
|
22
|
+
manageFocus?: boolean;
|
|
23
|
+
/** Determines whether `autocomplete="one-time-code"` attribute should be set on all inputs @default true */
|
|
24
|
+
otp?: boolean;
|
|
25
|
+
/** Adds disabled attribute to all inputs */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Sets `aria-invalid` attribute and applies error styles to all inputs */
|
|
28
|
+
error?: boolean;
|
|
29
|
+
/** Determines which values can be entered @default 'alphanumeric' */
|
|
30
|
+
type?: 'alphanumeric' | 'number' | RegExp;
|
|
31
|
+
/** Changes input type to `"password"` @default false */
|
|
32
|
+
mask?: boolean;
|
|
33
|
+
/** Number of inputs @default 4 */
|
|
34
|
+
length?: number;
|
|
35
|
+
/** If set, the user cannot edit the value */
|
|
36
|
+
readOnly?: boolean;
|
|
37
|
+
/** `aria-label` attribute */
|
|
38
|
+
ariaLabel?: string;
|
|
39
|
+
/** Marks the field as required */
|
|
40
|
+
required?: boolean;
|
|
41
|
+
}
|
|
42
|
+
type __VLS_Props = PinInputProps;
|
|
43
|
+
type __VLS_ModelProps = {
|
|
44
|
+
modelValue?: string;
|
|
45
|
+
};
|
|
46
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
47
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
48
|
+
"update:modelValue": (value: string) => any;
|
|
49
|
+
complete: (value: string) => any;
|
|
50
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
|
+
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
|
|
52
|
+
onComplete?: ((value: string) => any) | undefined;
|
|
53
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
54
|
+
declare const _default: typeof __VLS_export;
|
|
55
|
+
export default _default;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MaybeRefOrGetter, ModelRef } from 'vue';
|
|
2
|
+
export declare function usePinInput<Element extends HTMLInputElement>({ value: model, length, allowedKeys, manageFocus, inputMode, }: {
|
|
3
|
+
value: ModelRef<string>;
|
|
4
|
+
/** current length */
|
|
5
|
+
length: MaybeRefOrGetter<number>;
|
|
6
|
+
/** @default ['Backspace', 'Tab', 'Control', 'Delete', 'ArrowLeft', 'ArrowRight'] */
|
|
7
|
+
allowedKeys?: string[];
|
|
8
|
+
/** @default true */
|
|
9
|
+
manageFocus?: boolean;
|
|
10
|
+
inputMode: MaybeRefOrGetter<'numeric' | 'text'>;
|
|
11
|
+
}): {
|
|
12
|
+
refs: Readonly<import("vue").Ref<Readonly<import("@vueuse/core").TemplateRefsList<Element>>, Readonly<import("@vueuse/core").TemplateRefsList<Element>>>>;
|
|
13
|
+
cells: import("vue").WritableComputedRef<string[], string[]>;
|
|
14
|
+
focusedIx: import("vue").Ref<number, number>;
|
|
15
|
+
focus: (dir: "next" | "prev", ix: number) => void;
|
|
16
|
+
handleKeydown: (event: KeyboardEvent, ix: number) => void;
|
|
17
|
+
setFieldValue: (value: string, ix: number) => string[];
|
|
18
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { useTemplateRefsList } from "@vueuse/core";
|
|
2
|
+
import { computed, ref, toValue } from "vue";
|
|
3
|
+
import { createPinArray } from "./lib.js";
|
|
4
|
+
export function usePinInput({
|
|
5
|
+
value: model,
|
|
6
|
+
length,
|
|
7
|
+
allowedKeys = ["Backspace", "Tab", "Control", "Delete", "ArrowLeft", "ArrowRight"],
|
|
8
|
+
manageFocus = true,
|
|
9
|
+
inputMode
|
|
10
|
+
}) {
|
|
11
|
+
const refs = useTemplateRefsList();
|
|
12
|
+
const focusedIx = ref(-1);
|
|
13
|
+
const cells = computed({
|
|
14
|
+
get: () => createPinArray(toValue(length), model.value),
|
|
15
|
+
set: (value) => {
|
|
16
|
+
model.value = value.join("").trim();
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
function setFieldValue(value, ix) {
|
|
20
|
+
const values = [...cells.value];
|
|
21
|
+
values[ix] = value;
|
|
22
|
+
cells.value = values;
|
|
23
|
+
return values;
|
|
24
|
+
}
|
|
25
|
+
function focus(dir, ix) {
|
|
26
|
+
if (dir === "next") {
|
|
27
|
+
const nextIx = ix + 1;
|
|
28
|
+
if (nextIx < toValue(length))
|
|
29
|
+
refs.value[nextIx]?.focus();
|
|
30
|
+
} else if (dir === "prev") {
|
|
31
|
+
const prevIx = ix - 1;
|
|
32
|
+
if (prevIx >= 0)
|
|
33
|
+
refs.value[prevIx]?.focus();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function handleKeydown(event, ix) {
|
|
37
|
+
const inputValue = event.target.value;
|
|
38
|
+
if (inputMode === "numeric") {
|
|
39
|
+
const isModifierShortcut = event.ctrlKey || event.metaKey;
|
|
40
|
+
const isAllowedKey = allowedKeys.includes(event.key) || isModifierShortcut || !Number.isNaN(Number(event.key));
|
|
41
|
+
if (!isAllowedKey)
|
|
42
|
+
return event.preventDefault();
|
|
43
|
+
}
|
|
44
|
+
switch (event.key) {
|
|
45
|
+
case "ArrowLeft":
|
|
46
|
+
event.preventDefault();
|
|
47
|
+
focus("prev", ix);
|
|
48
|
+
break;
|
|
49
|
+
case "ArrowRight":
|
|
50
|
+
event.preventDefault();
|
|
51
|
+
focus("next", ix);
|
|
52
|
+
break;
|
|
53
|
+
case "Tab":
|
|
54
|
+
if (event.shiftKey && ix > 0 && manageFocus) {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
focus("prev", ix);
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
case " ":
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
focus("next", ix);
|
|
62
|
+
break;
|
|
63
|
+
case "Delete":
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
setFieldValue("", ix);
|
|
66
|
+
break;
|
|
67
|
+
case "Backspace":
|
|
68
|
+
if (inputValue === "") {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
focus("prev", ix);
|
|
71
|
+
} else {
|
|
72
|
+
setFieldValue("", ix);
|
|
73
|
+
if (ix < toValue(length) - 1) {
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
focus("prev", ix);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
if (inputValue.length > 0 && event.key === cells.value[ix]) {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
focus("next", ix);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
refs,
|
|
88
|
+
cells,
|
|
89
|
+
focusedIx,
|
|
90
|
+
focus,
|
|
91
|
+
handleKeydown,
|
|
92
|
+
setFieldValue
|
|
93
|
+
};
|
|
94
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
import type { NuanceSpacing } from '../types/index.js';
|
|
3
|
+
import type { BoxProps } from './box.vue.js';
|
|
4
|
+
export interface StackProps extends BoxProps {
|
|
5
|
+
/** Key of `theme.spacing` or any valid CSS value to set `gap` property, numbers are converted to rem @default 'md' */
|
|
6
|
+
gap?: NuanceSpacing;
|
|
7
|
+
/** Controls `align-items` CSS property @default 'stretch' */
|
|
8
|
+
align?: CSSProperties['alignItems'];
|
|
9
|
+
/** Controls `justify-content` CSS property @default 'flex-start' */
|
|
10
|
+
justify?: CSSProperties['justifyContent'];
|
|
11
|
+
}
|
|
12
|
+
declare var __VLS_8: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_8) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<StackProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<StackProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { getSpacing, useVarsResolver } from "#imports";
|
|
3
|
+
import Box from "./box.vue";
|
|
4
|
+
const {
|
|
5
|
+
gap,
|
|
6
|
+
align,
|
|
7
|
+
justify,
|
|
8
|
+
...props
|
|
9
|
+
} = defineProps({
|
|
10
|
+
gap: { type: [String, Number], required: false },
|
|
11
|
+
align: { type: void 0, required: false },
|
|
12
|
+
justify: { type: void 0, required: false },
|
|
13
|
+
is: { type: null, required: false },
|
|
14
|
+
mod: { type: [Object, Array, null], required: false }
|
|
15
|
+
});
|
|
16
|
+
const style = useVarsResolver(() => ({
|
|
17
|
+
root: {
|
|
18
|
+
"--stack-gap": getSpacing(gap),
|
|
19
|
+
"--stack-align": align ?? void 0,
|
|
20
|
+
"--stack-justify": justify ?? void 0
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<Box v-bind='props' :style='style.root' :class='$style.root'>
|
|
27
|
+
<slot />
|
|
28
|
+
</Box>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<style module>
|
|
32
|
+
.root{align-items:var(--stack-align,stretch);display:flex;flex-direction:column;gap:var(--stack-gap,var(--spacing-md));justify-content:var(--stack-justify,flex-start)}
|
|
33
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
import type { NuanceSpacing } from '../types/index.js';
|
|
3
|
+
import type { BoxProps } from './box.vue.js';
|
|
4
|
+
export interface StackProps extends BoxProps {
|
|
5
|
+
/** Key of `theme.spacing` or any valid CSS value to set `gap` property, numbers are converted to rem @default 'md' */
|
|
6
|
+
gap?: NuanceSpacing;
|
|
7
|
+
/** Controls `align-items` CSS property @default 'stretch' */
|
|
8
|
+
align?: CSSProperties['alignItems'];
|
|
9
|
+
/** Controls `justify-content` CSS property @default 'flex-start' */
|
|
10
|
+
justify?: CSSProperties['justifyContent'];
|
|
11
|
+
}
|
|
12
|
+
declare var __VLS_8: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_8) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<StackProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<StackProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
17
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
18
|
+
declare const _default: typeof __VLS_export;
|
|
19
|
+
export default _default;
|
|
20
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
21
|
+
new (): {
|
|
22
|
+
$slots: S;
|
|
23
|
+
};
|
|
24
|
+
};
|