@nexxtmove/ui 1.0.2 → 1.0.4
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 +56 -24
- package/dist/index.js +864 -754
- package/dist/nuxt.js +1 -0
- package/package.json +8 -8
- package/src/components/Announcement/Announcement.vue +13 -7
- package/src/components/InputSelect/InputSelect.vue +139 -0
- package/src/components.json +1 -0
- package/src/index.ts +1 -0
- package/tailwind/nexxtmove.tailwind.components.css +20 -0
- package/tailwind/nexxtmove.tailwind.theme.css +6 -0
package/dist/nuxt.js
CHANGED
|
@@ -42958,6 +42958,7 @@ var Vw, Hw, Uw, Ww, Gw, Kw = t((() => {
|
|
|
42958
42958
|
NexxtIcon: "components/Icon/Icon.vue",
|
|
42959
42959
|
NexxtInfoBlock: "components/InfoBlock/InfoBlock.vue",
|
|
42960
42960
|
NexxtInputField: "components/InputField/InputField.vue",
|
|
42961
|
+
NexxtInputSelect: "components/InputSelect/InputSelect.vue",
|
|
42961
42962
|
NexxtModal: "components/Modal/Modal.vue",
|
|
42962
42963
|
NexxtPagination: "components/Pagination/Pagination.vue",
|
|
42963
42964
|
NexxtPresenceIndicator: "components/PresenceIndicator/PresenceIndicator.vue",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexxtmove/ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.4",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"@eslint/js": "^10.0.1",
|
|
35
35
|
"@nuxt/kit": "^4.4.4",
|
|
36
36
|
"@nuxt/schema": "^4.4.4",
|
|
37
|
-
"@storybook/addon-a11y": "^10.
|
|
37
|
+
"@storybook/addon-a11y": "^10.4.0",
|
|
38
38
|
"@storybook/addon-designs": "^11.1.3",
|
|
39
|
-
"@storybook/addon-docs": "^10.
|
|
40
|
-
"@storybook/addon-vitest": "^10.
|
|
41
|
-
"@storybook/builder-vite": "^10.
|
|
42
|
-
"@storybook/vue3-vite": "^10.
|
|
39
|
+
"@storybook/addon-docs": "^10.4.0",
|
|
40
|
+
"@storybook/addon-vitest": "^10.4.0",
|
|
41
|
+
"@storybook/builder-vite": "^10.4.0",
|
|
42
|
+
"@storybook/vue3-vite": "^10.4.0",
|
|
43
43
|
"@tailwindcss/vite": "^4.2.4",
|
|
44
44
|
"@types/node": "^25.6.0",
|
|
45
45
|
"@types/react": "^19.2.14",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"eslint": "^10.2.1",
|
|
54
54
|
"eslint-config-prettier": "^10.1.8",
|
|
55
55
|
"eslint-plugin-prettier": "^5.5.5",
|
|
56
|
-
"eslint-plugin-storybook": "10.
|
|
56
|
+
"eslint-plugin-storybook": "10.4.0",
|
|
57
57
|
"eslint-plugin-vue": "^10.9.0",
|
|
58
58
|
"globals": "^17.5.0",
|
|
59
59
|
"jsdom": "^29.1.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"react": "^19.2.5",
|
|
63
63
|
"react-dom": "^19.2.5",
|
|
64
64
|
"remark-frontmatter": "^5.0.0",
|
|
65
|
-
"storybook": "^10.
|
|
65
|
+
"storybook": "^10.4.0",
|
|
66
66
|
"typescript-eslint": "^8.59.1",
|
|
67
67
|
"vite": "^8.0.10",
|
|
68
68
|
"vite-plugin-dts": "^4.5.4",
|
|
@@ -4,24 +4,30 @@ import NexxtIcon from '../Icon/Icon.vue'
|
|
|
4
4
|
interface NexxtAnnouncementProps {
|
|
5
5
|
color?: string
|
|
6
6
|
text_color?: string
|
|
7
|
+
icon?: InstanceType<typeof NexxtIcon>['name']
|
|
8
|
+
showHideButton?: boolean
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
color = 'blue',
|
|
13
|
+
text_color = 'white',
|
|
14
|
+
icon = 'megaphone',
|
|
15
|
+
showHideButton = true,
|
|
16
|
+
} = defineProps<NexxtAnnouncementProps>()
|
|
10
17
|
|
|
11
18
|
const emit = defineEmits<{ hide: [] }>()
|
|
12
19
|
</script>
|
|
13
20
|
|
|
14
21
|
<template>
|
|
15
22
|
<div
|
|
16
|
-
class="
|
|
23
|
+
class="grid items-center gap-x-3 overflow-hidden rounded-md px-4 py-3"
|
|
24
|
+
:class="showHideButton ? 'grid-cols-[auto_1fr_auto]' : 'grid-cols-[auto_1fr]'"
|
|
17
25
|
:style="{ background: color, color: text_color }"
|
|
18
26
|
>
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
<slot />
|
|
22
|
-
</div>
|
|
23
|
-
|
|
27
|
+
<NexxtIcon class="text-lg" :name="icon" />
|
|
28
|
+
<slot />
|
|
24
29
|
<button
|
|
30
|
+
v-if="showHideButton"
|
|
25
31
|
type="button"
|
|
26
32
|
class="cursor-pointer text-2xl leading-none opacity-70 hover:opacity-100"
|
|
27
33
|
@click="emit('hide')"
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import NexxtIcon from '../Icon/Icon.vue'
|
|
4
|
+
import NexxtFloatingPanel from '../FloatingPanel/FloatingPanel.vue'
|
|
5
|
+
import type Icon from '../Icon/Icon.vue'
|
|
6
|
+
import type { SelectOption } from '../Select/Select.vue'
|
|
7
|
+
|
|
8
|
+
export type { SelectOption }
|
|
9
|
+
|
|
10
|
+
const generateId = () => 'input-select-' + Math.random().toString(36).slice(2, 10)
|
|
11
|
+
const fieldId = generateId()
|
|
12
|
+
const selectId = generateId()
|
|
13
|
+
|
|
14
|
+
defineOptions({ name: 'NexxtInputSelect' })
|
|
15
|
+
|
|
16
|
+
export interface NexxtInputSelectProps {
|
|
17
|
+
options: SelectOption[]
|
|
18
|
+
label?: string
|
|
19
|
+
placeholder?: string
|
|
20
|
+
selectPlaceholder?: string
|
|
21
|
+
selectPosition?: 'before' | 'after'
|
|
22
|
+
error?: boolean
|
|
23
|
+
errorMessage?: string
|
|
24
|
+
required?: boolean
|
|
25
|
+
leftIcon?: InstanceType<typeof Icon>['name']
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const props = withDefaults(defineProps<NexxtInputSelectProps>(), {
|
|
29
|
+
selectPlaceholder: 'Selecteer...',
|
|
30
|
+
selectPosition: 'after',
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const getLabel = (opt: SelectOption) => (typeof opt === 'string' ? opt : opt.label)
|
|
34
|
+
const getValue = (opt: SelectOption): string | number => (typeof opt === 'string' ? opt : opt.value)
|
|
35
|
+
|
|
36
|
+
const inputModel = defineModel<string | number>('input')
|
|
37
|
+
const selectModel = defineModel<string | number | null>('select', { default: null })
|
|
38
|
+
|
|
39
|
+
const selectedLabel = computed(() => {
|
|
40
|
+
if (selectModel.value === null || selectModel.value === undefined) return null
|
|
41
|
+
const found = props.options.find((opt) => getValue(opt) === selectModel.value)
|
|
42
|
+
return found ? getLabel(found) : null
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const select = (opt: SelectOption, close: () => void) => {
|
|
46
|
+
selectModel.value = getValue(opt)
|
|
47
|
+
close()
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template>
|
|
52
|
+
<div class="inline-flex flex-col gap-1">
|
|
53
|
+
<label
|
|
54
|
+
v-if="label"
|
|
55
|
+
class="text-color-gray-700 justify-start body-normal text-sm"
|
|
56
|
+
:for="fieldId"
|
|
57
|
+
>
|
|
58
|
+
{{ label }}
|
|
59
|
+
<span v-if="required" class="text-brick-500">*</span>
|
|
60
|
+
</label>
|
|
61
|
+
|
|
62
|
+
<div
|
|
63
|
+
class="group flex items-center overflow-hidden rounded-lg ring transition-colors ease-out focus-within:ring-cornflower-blue-500"
|
|
64
|
+
:class="[
|
|
65
|
+
error ? 'ring-brick-400' : 'ring-gray-200',
|
|
66
|
+
selectPosition === 'after' ? 'flex-row-reverse' : 'flex-row',
|
|
67
|
+
]"
|
|
68
|
+
>
|
|
69
|
+
<NexxtFloatingPanel :placement="selectPosition === 'after' ? 'bottom-end' : 'bottom-start'">
|
|
70
|
+
<template #trigger="{ isOpen, toggle }">
|
|
71
|
+
<div
|
|
72
|
+
:id="selectId"
|
|
73
|
+
role="combobox"
|
|
74
|
+
:aria-expanded="isOpen"
|
|
75
|
+
aria-haspopup="listbox"
|
|
76
|
+
tabindex="0"
|
|
77
|
+
class="flex h-10 shrink-0 cursor-pointer items-center gap-1.5 px-3 text-sm transition-colors focus:outline-none"
|
|
78
|
+
:class="[
|
|
79
|
+
selectedLabel ? 'text-gray-900' : 'text-gray-400',
|
|
80
|
+
selectPosition === 'after' ? 'border-l border-gray-200' : 'border-r border-gray-200',
|
|
81
|
+
]"
|
|
82
|
+
@click="toggle"
|
|
83
|
+
@keydown.enter.prevent="toggle"
|
|
84
|
+
@keydown.space.prevent="toggle"
|
|
85
|
+
>
|
|
86
|
+
<NexxtIcon v-if="leftIcon" :name="leftIcon" class="text-gray-400" />
|
|
87
|
+
<span>{{ selectedLabel ?? selectPlaceholder }}</span>
|
|
88
|
+
<NexxtIcon
|
|
89
|
+
name="chevron-down"
|
|
90
|
+
class="shrink-0 text-gray-400 transition-all duration-200"
|
|
91
|
+
:class="{ 'rotate-180': isOpen }"
|
|
92
|
+
/>
|
|
93
|
+
</div>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<template #content="{ close }">
|
|
97
|
+
<ul
|
|
98
|
+
role="listbox"
|
|
99
|
+
class="overflow-hidden rounded-lg bg-white shadow-xs ring ring-gray-100"
|
|
100
|
+
>
|
|
101
|
+
<li
|
|
102
|
+
v-for="opt in options"
|
|
103
|
+
:key="getValue(opt)"
|
|
104
|
+
role="option"
|
|
105
|
+
:aria-selected="selectModel === getValue(opt)"
|
|
106
|
+
class="flex cursor-pointer items-center justify-between px-4 py-3 text-sm text-gray-900 transition-colors duration-150 hover:bg-gray-50 hover:text-purple-600"
|
|
107
|
+
:class="{ 'font-medium text-cornflower-blue-600': selectModel === getValue(opt) }"
|
|
108
|
+
@click="select(opt, close)"
|
|
109
|
+
>
|
|
110
|
+
{{ getLabel(opt) }}
|
|
111
|
+
<NexxtIcon v-if="selectModel === getValue(opt)" name="check" class="text-xs" />
|
|
112
|
+
</li>
|
|
113
|
+
</ul>
|
|
114
|
+
</template>
|
|
115
|
+
</NexxtFloatingPanel>
|
|
116
|
+
|
|
117
|
+
<input
|
|
118
|
+
:id="fieldId"
|
|
119
|
+
v-model="inputModel"
|
|
120
|
+
:placeholder="placeholder"
|
|
121
|
+
v-bind="$attrs"
|
|
122
|
+
class="bg-transparant h-10 w-full min-w-40 px-3 text-sm text-gray-900 placeholder-gray-400 focus:outline-none"
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<Transition
|
|
127
|
+
enter-active-class="transition-all duration-200 ease-out"
|
|
128
|
+
enter-from-class="opacity-0 -translate-y-1"
|
|
129
|
+
enter-to-class="opacity-100 translate-y-0"
|
|
130
|
+
leave-active-class="transition-all duration-150 ease-in"
|
|
131
|
+
leave-from-class="opacity-100 translate-y-0"
|
|
132
|
+
leave-to-class="opacity-0 -translate-y-1"
|
|
133
|
+
>
|
|
134
|
+
<p v-if="error && errorMessage" class="text-sm text-brick-400">
|
|
135
|
+
{{ errorMessage }}
|
|
136
|
+
</p>
|
|
137
|
+
</Transition>
|
|
138
|
+
</div>
|
|
139
|
+
</template>
|
package/src/components.json
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"NexxtIcon": "components/Icon/Icon.vue",
|
|
21
21
|
"NexxtInfoBlock": "components/InfoBlock/InfoBlock.vue",
|
|
22
22
|
"NexxtInputField": "components/InputField/InputField.vue",
|
|
23
|
+
"NexxtInputSelect": "components/InputSelect/InputSelect.vue",
|
|
23
24
|
"NexxtModal": "components/Modal/Modal.vue",
|
|
24
25
|
"NexxtPagination": "components/Pagination/Pagination.vue",
|
|
25
26
|
"NexxtPresenceIndicator": "components/PresenceIndicator/PresenceIndicator.vue",
|
package/src/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { default as NexxtHeader } from './components/Header/Header.vue'
|
|
|
20
20
|
export { default as NexxtIcon } from './components/Icon/Icon.vue'
|
|
21
21
|
export { default as NexxtInfoBlock } from './components/InfoBlock/InfoBlock.vue'
|
|
22
22
|
export { default as NexxtInputField } from './components/InputField/InputField.vue'
|
|
23
|
+
export { default as NexxtInputSelect } from './components/InputSelect/InputSelect.vue'
|
|
23
24
|
export { default as NexxtModal } from './components/Modal/Modal.vue'
|
|
24
25
|
export { default as NexxtPagination } from './components/Pagination/Pagination.vue'
|
|
25
26
|
export { default as NexxtPresenceIndicator } from './components/PresenceIndicator/PresenceIndicator.vue'
|
|
@@ -143,6 +143,26 @@
|
|
|
143
143
|
@apply bg-card-bg;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
.toast {
|
|
147
|
+
@apply px-(--toast-padding-x) py-(--toast-padding-y);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.toast-error {
|
|
151
|
+
@apply border-toast-border-error border border-solid;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.toast-info {
|
|
155
|
+
@apply border-toast-border-info border border-solid;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.toast-success {
|
|
159
|
+
@apply border-toast-border-success border border-solid;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.toast-warning {
|
|
163
|
+
@apply border-toast-border-warning border border-solid;
|
|
164
|
+
}
|
|
165
|
+
|
|
146
166
|
.info-block {
|
|
147
167
|
@apply p-(--info-block-padding);
|
|
148
168
|
}
|
|
@@ -170,6 +170,10 @@
|
|
|
170
170
|
--color-social-media-template-info-bg: var(--color-cornflower-blue-500);
|
|
171
171
|
--color-card-content-border: var(--color-gray-200);
|
|
172
172
|
--color-card-bg: var(--color-white);
|
|
173
|
+
--color-toast-border-info: var(--color-cornflower-blue-300);
|
|
174
|
+
--color-toast-border-success: var(--color-green-300);
|
|
175
|
+
--color-toast-border-warning: var(--color-orange-300);
|
|
176
|
+
--color-toast-border-error: var(--color-brick-300);
|
|
173
177
|
--text-xs: 0.75rem;
|
|
174
178
|
--text-base: 1rem;
|
|
175
179
|
--text-lg: 1.125rem;
|
|
@@ -241,6 +245,8 @@
|
|
|
241
245
|
--card-content-padding-x: var(--spacing-5);
|
|
242
246
|
--card-content-padding-y: var(--spacing-4);
|
|
243
247
|
--card-content-border-radius: var(--radius-lg);
|
|
248
|
+
--toast-padding-x: var(--spacing-5);
|
|
249
|
+
--toast-padding-y: var(--spacing-5);
|
|
244
250
|
--font-sans: 'Poppins', ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
245
251
|
--font-serif: 'Playfair Display', ui-serif, Georgia, Cambria, "Times New Roman", Times, serif;
|
|
246
252
|
--font-mono: 'Space Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|