design-system-next 2.7.43 → 2.7.44
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/design-system-next.js +3711 -3319
- package/dist/design-system-next.js.gz +0 -0
- package/dist/main.css +1 -1
- package/dist/main.css.gz +0 -0
- package/dist/package.json.d.ts +1 -1
- package/package.json +1 -1
- package/src/assets/styles/tailwind.css +21 -1
- package/src/components/input/input.ts +6 -2
- package/src/components/input/input.vue +11 -6
- package/src/components/input/use-input.ts +33 -3
- package/src/components/select/select-laderrized/select-laderrized.ts +122 -0
- package/src/components/select/select-laderrized/select-laderrized.vue +110 -0
- package/src/components/select/select-laderrized/use-select-laderrized.ts +499 -0
- package/src/components/select/select-multiple/select-multiple.ts +122 -0
- package/src/components/select/select-multiple/select-multiple.vue +110 -0
- package/src/components/select/select-multiple/use-select-multiple.ts +499 -0
- package/src/components/select/select.ts +105 -0
- package/src/components/select/select.vue +90 -0
- package/src/components/select/use-select.ts +445 -0
- package/src/examples/select-number-multi-select.vue +71 -0
- package/src/components/dropdown/__tests__/dropdown-fixes.spec.ts +0 -106
- package/src/components/dropdown/__tests__/dropdown-value-types.spec.ts +0 -213
|
@@ -15,6 +15,8 @@ interface InputClasses {
|
|
|
15
15
|
prefixSlotClasses: string;
|
|
16
16
|
trailingSlotClasses: string;
|
|
17
17
|
helperClasses: string;
|
|
18
|
+
charCountClasses: string;
|
|
19
|
+
helperContainerClasses: string;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export const useInput = (
|
|
@@ -22,13 +24,21 @@ export const useInput = (
|
|
|
22
24
|
emit: SetupContext<InputEmitTypes>['emit'],
|
|
23
25
|
slots: Record<string, unknown>,
|
|
24
26
|
) => {
|
|
25
|
-
const { active, error, disabled, offsetSize } = toRefs(props);
|
|
27
|
+
const { active, error, disabled, offsetSize, showCharCount, maxLength } = toRefs(props);
|
|
26
28
|
|
|
27
29
|
const inputTextRef = ref(null);
|
|
28
30
|
|
|
29
31
|
const { focused } = useFocus(inputTextRef);
|
|
30
32
|
|
|
31
33
|
const modelValue = useVModel(props, 'modelValue', emit);
|
|
34
|
+
|
|
35
|
+
const currentLength = computed(() => {
|
|
36
|
+
return modelValue.value ? String(modelValue.value).length : 0;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const hasCharLimit = computed(() => {
|
|
40
|
+
return maxLength.value !== undefined && maxLength.value > 0;
|
|
41
|
+
});
|
|
32
42
|
|
|
33
43
|
const inputClasses: ComputedRef<InputClasses> = computed(() => {
|
|
34
44
|
const baseClasses = classNames('spr-flex spr-flex-col spr-gap-size-spacing-4xs');
|
|
@@ -99,11 +109,19 @@ export const useInput = (
|
|
|
99
109
|
'spr-text-mushroom-300': !error.value,
|
|
100
110
|
'spr-text-tomato-600': error.value,
|
|
101
111
|
});
|
|
112
|
+
|
|
113
|
+
const helperContainerClasses = classNames('spr-flex spr-flex-row spr-items-start spr-justify-between spr-w-full', {
|
|
114
|
+
'spr-mt-1': showCharCount.value || props.displayHelper,
|
|
115
|
+
});
|
|
102
116
|
|
|
103
|
-
const helperClasses = classNames('spr-body-sm-regular spr-flex spr-items-center spr-gap-size-spacing-5xs', {
|
|
117
|
+
const helperClasses = classNames('spr-body-sm-regular spr-flex spr-items-center spr-gap-size-spacing-5xs spr-flex-1', {
|
|
104
118
|
'spr-text-color-danger-base': error.value,
|
|
105
119
|
'spr-text-color-supporting': !error.value,
|
|
106
120
|
});
|
|
121
|
+
|
|
122
|
+
const charCountClasses = classNames('spr-ml-auto spr-body-2xs-regular spr-text-right spr-text-xs spr-text-color-supporting', {
|
|
123
|
+
'spr-text-color-danger-base': hasCharLimit.value && currentLength.value >= (maxLength.value || 0),
|
|
124
|
+
});
|
|
107
125
|
|
|
108
126
|
return {
|
|
109
127
|
baseClasses,
|
|
@@ -114,11 +132,21 @@ export const useInput = (
|
|
|
114
132
|
prefixSlotClasses,
|
|
115
133
|
trailingSlotClasses,
|
|
116
134
|
helperClasses,
|
|
135
|
+
charCountClasses,
|
|
136
|
+
helperContainerClasses,
|
|
117
137
|
};
|
|
118
138
|
});
|
|
119
139
|
|
|
120
140
|
const onInput = (event: Event) => {
|
|
121
|
-
|
|
141
|
+
const target = event.target as HTMLInputElement;
|
|
142
|
+
let value: string | number = target.value;
|
|
143
|
+
|
|
144
|
+
// Convert to number if type is number
|
|
145
|
+
if (props.type === 'number' && value !== '') {
|
|
146
|
+
value = Number(value);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
modelValue.value = value;
|
|
122
150
|
};
|
|
123
151
|
|
|
124
152
|
const disableClickEvent = (event: Event) => {
|
|
@@ -133,5 +161,7 @@ export const useInput = (
|
|
|
133
161
|
inputClasses,
|
|
134
162
|
onInput,
|
|
135
163
|
disableClickEvent,
|
|
164
|
+
currentLength,
|
|
165
|
+
hasCharLimit,
|
|
136
166
|
};
|
|
137
167
|
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// import type { PropType, ExtractPropTypes } from 'vue';
|
|
2
|
+
// import type { MenuListType } from '../list/list';
|
|
3
|
+
|
|
4
|
+
// export const definePropType = <T>(val: unknown): PropType<T> => val as PropType<T>;
|
|
5
|
+
|
|
6
|
+
// const GROUPED_ITEMS_BY_TYPES = ['A-Z', 'Z-A'] as const;
|
|
7
|
+
|
|
8
|
+
// const PLACEMENTS_TYPES = [
|
|
9
|
+
// 'auto',
|
|
10
|
+
// 'auto-start',
|
|
11
|
+
// 'auto-end',
|
|
12
|
+
// 'top',
|
|
13
|
+
// 'top-start',
|
|
14
|
+
// 'top-end',
|
|
15
|
+
// 'right',
|
|
16
|
+
// 'right-start',
|
|
17
|
+
// 'right-end',
|
|
18
|
+
// 'bottom',
|
|
19
|
+
// 'bottom-start',
|
|
20
|
+
// 'bottom-end',
|
|
21
|
+
// 'left',
|
|
22
|
+
// 'left-start',
|
|
23
|
+
// 'left-end',
|
|
24
|
+
// ] as const;
|
|
25
|
+
|
|
26
|
+
// const POPPER_STRATEGY_TYPES = ['fixed', 'absolute'] as const;
|
|
27
|
+
|
|
28
|
+
// export const selectPropTypes = {
|
|
29
|
+
// id: {
|
|
30
|
+
// type: String,
|
|
31
|
+
// required: true,
|
|
32
|
+
// },
|
|
33
|
+
// modelValue: {
|
|
34
|
+
// type: [String, Number, Object, Array] as PropType<
|
|
35
|
+
// string | number | Record<string, unknown> | (string | number | Record<string, unknown>)[]
|
|
36
|
+
// >,
|
|
37
|
+
// default: () => [],
|
|
38
|
+
// },
|
|
39
|
+
// menuList: {
|
|
40
|
+
// type: Array as PropType<MenuListType[] | string[] | Record<string, unknown>[]>,
|
|
41
|
+
// required: true,
|
|
42
|
+
// default: [],
|
|
43
|
+
// },
|
|
44
|
+
// multiSelect: {
|
|
45
|
+
// type: Boolean,
|
|
46
|
+
// default: false,
|
|
47
|
+
// },
|
|
48
|
+
// groupItemsBy: {
|
|
49
|
+
// type: String as PropType<(typeof GROUPED_ITEMS_BY_TYPES)[number]>,
|
|
50
|
+
// validator: (value: (typeof GROUPED_ITEMS_BY_TYPES)[number] | undefined) => {
|
|
51
|
+
// return value === undefined || GROUPED_ITEMS_BY_TYPES.includes(value);
|
|
52
|
+
// },
|
|
53
|
+
// },
|
|
54
|
+
// textField: {
|
|
55
|
+
// type: String,
|
|
56
|
+
// default: 'text',
|
|
57
|
+
// description: 'Field name to use for display text when using dynamic object arrays',
|
|
58
|
+
// },
|
|
59
|
+
// valueField: {
|
|
60
|
+
// type: String,
|
|
61
|
+
// default: 'value',
|
|
62
|
+
// description: 'Field name to use for value when using dynamic object arrays',
|
|
63
|
+
// },
|
|
64
|
+
// placeholder: {
|
|
65
|
+
// type: String,
|
|
66
|
+
// },
|
|
67
|
+
// searchString: {
|
|
68
|
+
// type: String,
|
|
69
|
+
// default: '',
|
|
70
|
+
// },
|
|
71
|
+
// placement: {
|
|
72
|
+
// type: String as PropType<(typeof PLACEMENTS_TYPES)[number]>,
|
|
73
|
+
// validator: (value: (typeof PLACEMENTS_TYPES)[number]) => PLACEMENTS_TYPES.includes(value),
|
|
74
|
+
// default: 'bottom',
|
|
75
|
+
// },
|
|
76
|
+
// popperStrategy: {
|
|
77
|
+
// type: String,
|
|
78
|
+
// validator: (value: 'fixed' | 'absolute') => POPPER_STRATEGY_TYPES.includes(value),
|
|
79
|
+
// default: 'absolute',
|
|
80
|
+
// },
|
|
81
|
+
// popperWidth: {
|
|
82
|
+
// type: String,
|
|
83
|
+
// default: '100%',
|
|
84
|
+
// },
|
|
85
|
+
// width: {
|
|
86
|
+
// type: String,
|
|
87
|
+
// default: '100%',
|
|
88
|
+
// },
|
|
89
|
+
// wrapperPosition: {
|
|
90
|
+
// type: String,
|
|
91
|
+
// default: 'relative',
|
|
92
|
+
// },
|
|
93
|
+
// disabled: {
|
|
94
|
+
// type: Boolean,
|
|
95
|
+
// default: false,
|
|
96
|
+
// },
|
|
97
|
+
// readonly: {
|
|
98
|
+
// type: Boolean,
|
|
99
|
+
// default: false,
|
|
100
|
+
// },
|
|
101
|
+
// ladderized: {
|
|
102
|
+
// type: Boolean,
|
|
103
|
+
// default: false,
|
|
104
|
+
// },
|
|
105
|
+
// removeCurrentLevelInBackLabel: {
|
|
106
|
+
// type: Boolean,
|
|
107
|
+
// default: false,
|
|
108
|
+
// },
|
|
109
|
+
// disabled: {
|
|
110
|
+
// type: Boolean,
|
|
111
|
+
// default: false,
|
|
112
|
+
// },
|
|
113
|
+
// };
|
|
114
|
+
|
|
115
|
+
// export const selectEmitTypes = {
|
|
116
|
+
// 'infinite-scroll-trigger': Boolean,
|
|
117
|
+
// // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
118
|
+
// 'update:modelValue': (_value: unknown) => true, // Accept any type of value
|
|
119
|
+
// };
|
|
120
|
+
|
|
121
|
+
// export type SelectPropTypes = ExtractPropTypes<typeof selectPropTypes>;
|
|
122
|
+
// export type SelectEmitTypes = typeof selectEmitTypes;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div></div>
|
|
3
|
+
</template>
|
|
4
|
+
<!-- <template>
|
|
5
|
+
<Menu
|
|
6
|
+
:shown="selectPopperState"
|
|
7
|
+
aria-id="select-wrapper"
|
|
8
|
+
distance="4"
|
|
9
|
+
:placement="props.placement"
|
|
10
|
+
:triggers="[]"
|
|
11
|
+
:popper-hide-triggers="[]"
|
|
12
|
+
:auto-hide="false"
|
|
13
|
+
:disabled="isSelectPopperDisabled"
|
|
14
|
+
:container="`#${props.id}`"
|
|
15
|
+
:strategy="
|
|
16
|
+
props.popperStrategy === 'fixed' || props.popperStrategy === 'absolute' ? props.popperStrategy : 'absolute'
|
|
17
|
+
"
|
|
18
|
+
:delay="0"
|
|
19
|
+
:style="{
|
|
20
|
+
position: props.wrapperPosition,
|
|
21
|
+
width: props.width,
|
|
22
|
+
}"
|
|
23
|
+
>
|
|
24
|
+
<div @click="selectPopperState = true">
|
|
25
|
+
{{ selectedListItems }}
|
|
26
|
+
|
|
27
|
+
<spr-input
|
|
28
|
+
v-model="inputText"
|
|
29
|
+
label="Select Numbers"
|
|
30
|
+
:placeholder="props.placeholder"
|
|
31
|
+
:readonly="props.readonly"
|
|
32
|
+
:disabled="props.disabled"
|
|
33
|
+
autocomplete="off"
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div
|
|
38
|
+
:id="props.id"
|
|
39
|
+
:style="{
|
|
40
|
+
width: props.popperWidth,
|
|
41
|
+
}"
|
|
42
|
+
></div>
|
|
43
|
+
|
|
44
|
+
<template #popper>
|
|
45
|
+
<div
|
|
46
|
+
ref="selectRef"
|
|
47
|
+
:class="[
|
|
48
|
+
(!props.ladderized || isLadderizedSearch) && 'spr-p-2',
|
|
49
|
+
'spr-grid spr-max-h-[300px] spr-gap-0.5 spr-overflow-y-auto spr-overflow-x-hidden',
|
|
50
|
+
]"
|
|
51
|
+
>
|
|
52
|
+
<template v-if="selectMenuList.length > 0">
|
|
53
|
+
<spr-list
|
|
54
|
+
v-if="!props.ladderized || isLadderizedSearch"
|
|
55
|
+
v-model="selectedListItems"
|
|
56
|
+
:menu-list="selectMenuList"
|
|
57
|
+
:group-items-by="props.groupItemsBy"
|
|
58
|
+
:multi-select="props.multiSelect"
|
|
59
|
+
:pre-selected-items="selectValue"
|
|
60
|
+
@update:model-value="handleSelectedItem"
|
|
61
|
+
/>
|
|
62
|
+
<spr-ladderized-list
|
|
63
|
+
v-else
|
|
64
|
+
v-model="selectValue"
|
|
65
|
+
:ladderized="props.ladderized"
|
|
66
|
+
:menu-list="selectMenuList"
|
|
67
|
+
:remove-current-level-in-back-label="removeCurrentLevelInBackLabel"
|
|
68
|
+
@update:model-value="handleSelectedLadderizedItem"
|
|
69
|
+
/>
|
|
70
|
+
</template>
|
|
71
|
+
<template v-else>
|
|
72
|
+
<div class="spr-flex spr-items-center spr-justify-center spr-p-2 spr-text-center">
|
|
73
|
+
<span class="spr-body-sm-regular spr-m-0">No results found</span>
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
76
|
+
</div>
|
|
77
|
+
</template>
|
|
78
|
+
</Menu>
|
|
79
|
+
</template>
|
|
80
|
+
|
|
81
|
+
<script lang="ts" setup>
|
|
82
|
+
import { Menu } from 'floating-vue';
|
|
83
|
+
|
|
84
|
+
import 'floating-vue/dist/style.css';
|
|
85
|
+
|
|
86
|
+
import SprInput from '../../input/input.vue';
|
|
87
|
+
import SprList from '../../list/list.vue';
|
|
88
|
+
import SprLadderizedList from '../../list/ladderized-list/ladderized-list.vue';
|
|
89
|
+
|
|
90
|
+
import { selectPropTypes, selectEmitTypes } from './select-laderrized';
|
|
91
|
+
|
|
92
|
+
import { useSelect } from './use-select-laderrized';
|
|
93
|
+
|
|
94
|
+
const props = defineProps(selectPropTypes);
|
|
95
|
+
const emit = defineEmits(selectEmitTypes);
|
|
96
|
+
|
|
97
|
+
const {
|
|
98
|
+
selectPopperState,
|
|
99
|
+
selectRef,
|
|
100
|
+
selectMenuList,
|
|
101
|
+
isSelectPopperDisabled,
|
|
102
|
+
selectedListItems,
|
|
103
|
+
handleSelectedItem,
|
|
104
|
+
handleSelectedLadderizedItem,
|
|
105
|
+
selectValue,
|
|
106
|
+
removeCurrentLevelInBackLabel,
|
|
107
|
+
isLadderizedSearch,
|
|
108
|
+
inputText,
|
|
109
|
+
} = useSelect(props, emit);
|
|
110
|
+
</script> -->
|