@nexxtmove/ui 0.1.34 → 0.1.36
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/index.d.ts +40 -15
- package/dist/index.js +1118 -1050
- package/dist/nuxt.js +15 -14
- package/package.json +1 -1
- package/src/components/InputField/InputField.vue +84 -0
- package/src/components/Pagination/Pagination.vue +2 -0
- package/src/components/Table/Table.vue +30 -31
- package/src/components.json +1 -0
- package/src/index.ts +1 -0
package/dist/nuxt.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineNuxtModule as c, addComponent as s, addTemplate as a } from "@nuxt/kit";
|
|
2
|
-
const i = "components/AnimatedNumber/AnimatedNumber.vue", m = "components/Avatar/Avatar.vue", x = "components/Button/Button.vue", u = "components/Calendar/Calendar.vue", p = "components/Checkbox/Checkbox.vue", l = "components/Chip/Chip.vue", r = "components/CustomerJourneyTile/CustomerJourneyTile.vue", d = "components/DatePicker/DatePicker.vue", v = "components/DropdownButton/DropdownButton.vue", N = "components/Header/Header.vue", T = "components/Icon/Icon.vue", C = "components/InfoBlock/InfoBlock.vue", S = "components/Pagination/Pagination.vue",
|
|
2
|
+
const i = "components/AnimatedNumber/AnimatedNumber.vue", m = "components/Avatar/Avatar.vue", x = "components/Button/Button.vue", u = "components/Calendar/Calendar.vue", p = "components/Checkbox/Checkbox.vue", l = "components/Chip/Chip.vue", r = "components/CustomerJourneyTile/CustomerJourneyTile.vue", d = "components/DatePicker/DatePicker.vue", v = "components/DropdownButton/DropdownButton.vue", N = "components/Header/Header.vue", T = "components/Icon/Icon.vue", C = "components/InfoBlock/InfoBlock.vue", S = "components/InputField/InputField.vue", b = "components/Pagination/Pagination.vue", f = "components/ProgressBar/ProgressBar.vue", h = "components/SocialIcons/SocialIcons.vue", P = "components/SocialMediaCustomTemplate/SocialMediaCustomTemplate.vue", k = "components/SocialMediaTemplate/SocialMediaTemplate.vue", B = "components/SocialMediaType/SocialMediaType.vue", I = "components/StepperHeader/StepperHeader.vue", M = "components/Table/Table.vue", g = "components/TimelineEvent/TimelineEvent.vue", y = "components/TimelinePhaseblock/TimelinePhaseblock.vue", A = "components/Tooltip/Tooltip.vue", D = {
|
|
3
3
|
NexxtAnimatedNumber: i,
|
|
4
4
|
NexxtAvatar: m,
|
|
5
5
|
NexxtButton: x,
|
|
@@ -12,18 +12,19 @@ const i = "components/AnimatedNumber/AnimatedNumber.vue", m = "components/Avatar
|
|
|
12
12
|
NexxtHeader: N,
|
|
13
13
|
NexxtIcon: T,
|
|
14
14
|
NexxtInfoBlock: C,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
NexxtInputField: S,
|
|
16
|
+
NexxtPagination: b,
|
|
17
|
+
NexxtProgressBar: f,
|
|
18
|
+
NexxtSocialIcons: h,
|
|
19
|
+
NexxtSocialMediaCustomTemplate: P,
|
|
20
|
+
NexxtSocialMediaTemplate: k,
|
|
21
|
+
NexxtSocialMediaType: B,
|
|
22
|
+
NexxtStepperHeader: I,
|
|
22
23
|
NexxtTable: M,
|
|
23
|
-
NexxtTimelineEvent:
|
|
24
|
-
NexxtTimelinePhaseblock:
|
|
25
|
-
NexxtTooltip:
|
|
26
|
-
},
|
|
24
|
+
NexxtTimelineEvent: g,
|
|
25
|
+
NexxtTimelinePhaseblock: y,
|
|
26
|
+
NexxtTooltip: A
|
|
27
|
+
}, w = c({
|
|
27
28
|
meta: {
|
|
28
29
|
name: "@nexxtmove/ui",
|
|
29
30
|
configKey: "nexxtmoveUi",
|
|
@@ -35,7 +36,7 @@ const i = "components/AnimatedNumber/AnimatedNumber.vue", m = "components/Avatar
|
|
|
35
36
|
addCSS: !0
|
|
36
37
|
},
|
|
37
38
|
setup(e, o) {
|
|
38
|
-
for (const [t, n] of Object.entries(
|
|
39
|
+
for (const [t, n] of Object.entries(D))
|
|
39
40
|
s({
|
|
40
41
|
name: t,
|
|
41
42
|
export: "default",
|
|
@@ -54,5 +55,5 @@ const i = "components/AnimatedNumber/AnimatedNumber.vue", m = "components/Avatar
|
|
|
54
55
|
}
|
|
55
56
|
});
|
|
56
57
|
export {
|
|
57
|
-
|
|
58
|
+
w as default
|
|
58
59
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed } from 'vue'
|
|
3
|
+
import Icon from '../Icon/Icon.vue'
|
|
4
|
+
|
|
5
|
+
const generateId = () => 'input-field-' + Math.random().toString(36).slice(2, 10)
|
|
6
|
+
const inputId = ref(generateId())
|
|
7
|
+
|
|
8
|
+
defineOptions({
|
|
9
|
+
name: 'NexxtInputField',
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
interface NexxtInputFieldProps {
|
|
13
|
+
placeholder?: string
|
|
14
|
+
label?: string
|
|
15
|
+
error?: boolean
|
|
16
|
+
errorMessage?: string
|
|
17
|
+
focused?: boolean
|
|
18
|
+
leftIcon?: InstanceType<typeof Icon>['name']
|
|
19
|
+
rightIcon?: InstanceType<typeof Icon>['name']
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const props = defineProps<NexxtInputFieldProps>()
|
|
23
|
+
|
|
24
|
+
// ✅ Correct usage
|
|
25
|
+
const modelValue = defineModel<string>()
|
|
26
|
+
|
|
27
|
+
const isFocused = ref(false)
|
|
28
|
+
|
|
29
|
+
const wrapperClasses = computed(() => {
|
|
30
|
+
if (props.error) {
|
|
31
|
+
return 'border-brick-400'
|
|
32
|
+
}
|
|
33
|
+
if (props.focused || isFocused.value) {
|
|
34
|
+
return 'border-cornflower-blue-500'
|
|
35
|
+
}
|
|
36
|
+
return 'border-gray-200'
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const onFocus = () => {
|
|
40
|
+
isFocused.value = true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const onBlur = () => {
|
|
44
|
+
isFocused.value = false
|
|
45
|
+
}
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<div class="flex w-full flex-col gap-1">
|
|
50
|
+
<label
|
|
51
|
+
v-if="props.label"
|
|
52
|
+
class="text-color-gray-700 justify-start body-normal text-sm"
|
|
53
|
+
:for="inputId"
|
|
54
|
+
>
|
|
55
|
+
{{ props.label }}
|
|
56
|
+
</label>
|
|
57
|
+
|
|
58
|
+
<div
|
|
59
|
+
class="flex items-center gap-2 rounded-lg border px-3 py-2 transition-colors"
|
|
60
|
+
:class="wrapperClasses"
|
|
61
|
+
>
|
|
62
|
+
<span v-if="props.leftIcon" class="flex items-center">
|
|
63
|
+
<Icon :name="props.leftIcon" />
|
|
64
|
+
</span>
|
|
65
|
+
|
|
66
|
+
<input
|
|
67
|
+
:id="inputId"
|
|
68
|
+
v-model="modelValue"
|
|
69
|
+
:placeholder="props.placeholder"
|
|
70
|
+
@focus="onFocus"
|
|
71
|
+
@blur="onBlur"
|
|
72
|
+
class="w-full bg-transparent text-sm text-gray-900 placeholder-gray-400 focus:outline-none"
|
|
73
|
+
/>
|
|
74
|
+
|
|
75
|
+
<span v-if="props.rightIcon" class="flex items-center">
|
|
76
|
+
<Icon :name="props.rightIcon" />
|
|
77
|
+
</span>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<p v-if="props.errorMessage" class="text-sm text-brick-400">
|
|
81
|
+
{{ props.errorMessage }}
|
|
82
|
+
</p>
|
|
83
|
+
</div>
|
|
84
|
+
</template>
|
|
@@ -46,6 +46,7 @@ const {
|
|
|
46
46
|
:class="{ 'pointer-events-none opacity-50': disabled }"
|
|
47
47
|
>
|
|
48
48
|
<PaginationFirst
|
|
49
|
+
v-if="items.some((item) => item.type === 'ellipsis')"
|
|
49
50
|
class="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-transparent transition hover:bg-cornflower-blue-50 disabled:cursor-not-allowed disabled:opacity-50"
|
|
50
51
|
:disabled="disabled"
|
|
51
52
|
>
|
|
@@ -83,6 +84,7 @@ const {
|
|
|
83
84
|
<NexxtIcon name="chevron-right" />
|
|
84
85
|
</PaginationNext>
|
|
85
86
|
<PaginationLast
|
|
87
|
+
v-if="items.some((item) => item.type === 'ellipsis')"
|
|
86
88
|
class="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-transparent transition hover:bg-cornflower-blue-50 disabled:cursor-not-allowed disabled:opacity-50"
|
|
87
89
|
:disabled="disabled"
|
|
88
90
|
>
|
|
@@ -13,25 +13,23 @@ export interface TableColumn<K extends string = string> {
|
|
|
13
13
|
export interface NexxtTableProps<TKey extends string = string> {
|
|
14
14
|
columns: TableColumn<TKey>[]
|
|
15
15
|
rows: Record<TKey, unknown>[]
|
|
16
|
-
sortKey?: TKey
|
|
17
|
-
sortDirection?: 'asc' | 'desc'
|
|
18
16
|
selectable?: boolean
|
|
19
|
-
modelValue?: number[]
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
const INTERACTIVE = ['a', 'button', 'input', 'select', 'textarea', 'label']
|
|
23
20
|
|
|
24
21
|
defineOptions({ name: 'NexxtTable' })
|
|
25
22
|
|
|
26
|
-
const props =
|
|
27
|
-
sortDirection: 'asc',
|
|
28
|
-
})
|
|
23
|
+
const props = defineProps<NexxtTableProps<TKey>>()
|
|
29
24
|
const emit = defineEmits<{
|
|
30
|
-
|
|
31
|
-
'update:modelValue': [selected: number[]]
|
|
25
|
+
'row-click': [row: Record<TKey, unknown>]
|
|
32
26
|
}>()
|
|
33
27
|
|
|
34
|
-
const selected =
|
|
28
|
+
const selected = defineModel<Record<TKey, unknown>[]>({ default: () => [] })
|
|
29
|
+
const sortKey = defineModel<TKey>('sortKey')
|
|
30
|
+
const sortDirection = defineModel<'asc' | 'desc'>('sortDirection', { default: 'asc' })
|
|
31
|
+
|
|
32
|
+
const rowRefs = ref<HTMLElement[]>([])
|
|
35
33
|
|
|
36
34
|
const allSelected = computed(
|
|
37
35
|
() => props.rows.length > 0 && selected.value.length === props.rows.length,
|
|
@@ -40,15 +38,16 @@ const someSelected = computed(
|
|
|
40
38
|
() => selected.value.length > 0 && selected.value.length < props.rows.length,
|
|
41
39
|
)
|
|
42
40
|
|
|
41
|
+
const isRowSelected = (row: Record<TKey, unknown>) => selected.value.includes(row)
|
|
42
|
+
|
|
43
43
|
const toggleAll = () => {
|
|
44
|
-
|
|
44
|
+
selected.value = allSelected.value ? [] : [...props.rows]
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
const toggleRow = (
|
|
48
|
-
|
|
49
|
-
? selected.value.filter((
|
|
50
|
-
: [...selected.value,
|
|
51
|
-
emit('update:modelValue', next)
|
|
47
|
+
const toggleRow = (row: Record<TKey, unknown>) => {
|
|
48
|
+
selected.value = isRowSelected(row)
|
|
49
|
+
? selected.value.filter((r) => r !== row)
|
|
50
|
+
: [...selected.value, row]
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
const columnTemplate = computed(() =>
|
|
@@ -61,32 +60,30 @@ const gridTemplate = computed(() =>
|
|
|
61
60
|
|
|
62
61
|
const handleSort = (column: TableColumn) => {
|
|
63
62
|
if (!column.sortable) return
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
sortDirection.value =
|
|
64
|
+
sortKey.value === column.key && sortDirection.value === 'asc' ? 'desc' : 'asc'
|
|
65
|
+
sortKey.value = column.key as TKey
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
const handleRowClick = (event: MouseEvent, rowIndex: number) => {
|
|
70
|
-
if (!props.selectable) return
|
|
71
69
|
const path = event.composedPath() as Element[]
|
|
72
70
|
const isInteractive = path.some(
|
|
73
71
|
(el) => el.tagName && INTERACTIVE.includes(el.tagName.toLowerCase()),
|
|
74
72
|
)
|
|
75
|
-
if (
|
|
73
|
+
if (isInteractive) return
|
|
74
|
+
emit('row-click', props.rows[rowIndex])
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
const getRowRoundedClass = (rowIndex: number) => {
|
|
79
|
-
if (!props.selectable || !
|
|
80
|
-
const prevSelected =
|
|
81
|
-
const nextSelected =
|
|
78
|
+
if (!props.selectable || !isRowSelected(props.rows[rowIndex])) return ''
|
|
79
|
+
const prevSelected = rowIndex > 0 && isRowSelected(props.rows[rowIndex - 1])
|
|
80
|
+
const nextSelected = rowIndex < props.rows.length - 1 && isRowSelected(props.rows[rowIndex + 1])
|
|
82
81
|
if (!prevSelected && !nextSelected) return 'rounded-md'
|
|
83
82
|
if (!prevSelected) return 'rounded-t-md'
|
|
84
83
|
if (!nextSelected) return 'rounded-b-md'
|
|
85
84
|
return ''
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
const rowRefs = ref<HTMLElement[]>([])
|
|
89
|
-
|
|
90
87
|
const handleRowKeydown = (event: KeyboardEvent, rowIndex: number) => {
|
|
91
88
|
if (event.key === 'ArrowDown') {
|
|
92
89
|
event.preventDefault()
|
|
@@ -176,18 +173,20 @@ const handleRowKeydown = (event: KeyboardEvent, rowIndex: number) => {
|
|
|
176
173
|
v-for="(row, rowIndex) in rows"
|
|
177
174
|
:key="rowIndex"
|
|
178
175
|
ref="rowRefs"
|
|
179
|
-
class="grid border-b border-gray-100 transition-colors duration-150 focus-visible:bg-slate-50 focus-visible:ring-2 focus-visible:ring-cornflower-blue-500 focus-visible:outline-none focus-visible:ring-inset"
|
|
176
|
+
class="grid border-b border-gray-100 transition-colors duration-150 hover:bg-cornflower-blue-50 focus-visible:bg-slate-50 focus-visible:ring-2 focus-visible:ring-cornflower-blue-500 focus-visible:outline-none focus-visible:ring-inset"
|
|
180
177
|
:class="[
|
|
181
178
|
{
|
|
182
|
-
'hover:
|
|
183
|
-
'border-white/80 bg-cornflower-blue-
|
|
179
|
+
'hover:rounded-md': !isRowSelected(rows[rowIndex]),
|
|
180
|
+
'border-white/80 bg-cornflower-blue-100':
|
|
181
|
+
selectable && isRowSelected(rows[rowIndex]),
|
|
182
|
+
'border-transparent': selectable && isRowSelected(rows[rowIndex + 1]),
|
|
184
183
|
},
|
|
185
184
|
getRowRoundedClass(rowIndex),
|
|
186
185
|
]"
|
|
187
186
|
:style="{ gridTemplateColumns: gridTemplate }"
|
|
188
187
|
role="row"
|
|
189
188
|
:aria-rowindex="rowIndex + 2"
|
|
190
|
-
:aria-selected="selectable ?
|
|
189
|
+
:aria-selected="selectable ? isRowSelected(row) : undefined"
|
|
191
190
|
tabindex="0"
|
|
192
191
|
@click="handleRowClick($event, rowIndex)"
|
|
193
192
|
@keydown="handleRowKeydown($event, rowIndex)"
|
|
@@ -199,9 +198,9 @@ const handleRowKeydown = (event: KeyboardEvent, rowIndex: number) => {
|
|
|
199
198
|
:aria-colindex="1"
|
|
200
199
|
>
|
|
201
200
|
<Checkbox
|
|
202
|
-
:model-value="
|
|
201
|
+
:model-value="isRowSelected(row)"
|
|
203
202
|
:aria-label="`Select row ${rowIndex + 1}`"
|
|
204
|
-
@update:model-value="toggleRow(
|
|
203
|
+
@update:model-value="toggleRow(row)"
|
|
205
204
|
/>
|
|
206
205
|
</div>
|
|
207
206
|
<div
|
package/src/components.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"NexxtHeader": "components/Header/Header.vue",
|
|
12
12
|
"NexxtIcon": "components/Icon/Icon.vue",
|
|
13
13
|
"NexxtInfoBlock": "components/InfoBlock/InfoBlock.vue",
|
|
14
|
+
"NexxtInputField": "components/InputField/InputField.vue",
|
|
14
15
|
"NexxtPagination": "components/Pagination/Pagination.vue",
|
|
15
16
|
"NexxtProgressBar": "components/ProgressBar/ProgressBar.vue",
|
|
16
17
|
"NexxtSocialIcons": "components/SocialIcons/SocialIcons.vue",
|
package/src/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { default as NexxtDropdownButton } from './components/DropdownButton/Drop
|
|
|
11
11
|
export { default as NexxtHeader } from './components/Header/Header.vue'
|
|
12
12
|
export { default as NexxtIcon } from './components/Icon/Icon.vue'
|
|
13
13
|
export { default as NexxtInfoBlock } from './components/InfoBlock/InfoBlock.vue'
|
|
14
|
+
export { default as NexxtInputField } from './components/InputField/InputField.vue'
|
|
14
15
|
export { default as NexxtPagination } from './components/Pagination/Pagination.vue'
|
|
15
16
|
export { default as NexxtProgressBar } from './components/ProgressBar/ProgressBar.vue'
|
|
16
17
|
export { default as NexxtSocialIcons } from './components/SocialIcons/SocialIcons.vue'
|