@nexxtmove/ui 1.0.1 → 1.0.3

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/nuxt.js CHANGED
@@ -42938,6 +42938,7 @@ var Vw, Hw, Uw, Ww, Gw, Kw = t((() => {
42938
42938
  }, t.exports.default = t.exports;
42939
42939
  })))(), 1), kk = {
42940
42940
  NexxtAnimatedNumber: "components/AnimatedNumber/AnimatedNumber.vue",
42941
+ NexxtAnnouncement: "components/Announcement/Announcement.vue",
42941
42942
  NexxtAvatar: "components/Avatar/Avatar.vue",
42942
42943
  NexxtButton: "components/Button/Button.vue",
42943
42944
  NexxtCalendar: "components/Calendar/Calendar.vue",
@@ -42957,6 +42958,7 @@ var Vw, Hw, Uw, Ww, Gw, Kw = t((() => {
42957
42958
  NexxtIcon: "components/Icon/Icon.vue",
42958
42959
  NexxtInfoBlock: "components/InfoBlock/InfoBlock.vue",
42959
42960
  NexxtInputField: "components/InputField/InputField.vue",
42961
+ NexxtInputSelect: "components/InputSelect/InputSelect.vue",
42960
42962
  NexxtModal: "components/Modal/Modal.vue",
42961
42963
  NexxtPagination: "components/Pagination/Pagination.vue",
42962
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.1",
4
+ "version": "1.0.3",
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.3.6",
37
+ "@storybook/addon-a11y": "^10.4.0",
38
38
  "@storybook/addon-designs": "^11.1.3",
39
- "@storybook/addon-docs": "^10.3.6",
40
- "@storybook/addon-vitest": "^10.3.6",
41
- "@storybook/builder-vite": "^10.3.6",
42
- "@storybook/vue3-vite": "^10.3.6",
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.3.6",
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.3.6",
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",
@@ -0,0 +1,38 @@
1
+ <script lang="ts" setup>
2
+ import NexxtIcon from '../Icon/Icon.vue'
3
+
4
+ interface NexxtAnnouncementProps {
5
+ color?: string
6
+ text_color?: string
7
+ icon?: InstanceType<typeof NexxtIcon>['name']
8
+ showHideButton?: boolean
9
+ }
10
+
11
+ const {
12
+ color = 'blue',
13
+ text_color = 'white',
14
+ icon = 'megaphone',
15
+ showHideButton = true,
16
+ } = defineProps<NexxtAnnouncementProps>()
17
+
18
+ const emit = defineEmits<{ hide: [] }>()
19
+ </script>
20
+
21
+ <template>
22
+ <div
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]'"
25
+ :style="{ background: color, color: text_color }"
26
+ >
27
+ <NexxtIcon class="text-lg" :name="icon" />
28
+ <slot />
29
+ <button
30
+ v-if="showHideButton"
31
+ type="button"
32
+ class="cursor-pointer text-2xl leading-none opacity-70 hover:opacity-100"
33
+ @click="emit('hide')"
34
+ >
35
+ &times;
36
+ </button>
37
+ </div>
38
+ </template>
@@ -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>
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "NexxtAnimatedNumber": "components/AnimatedNumber/AnimatedNumber.vue",
3
+ "NexxtAnnouncement": "components/Announcement/Announcement.vue",
3
4
  "NexxtAvatar": "components/Avatar/Avatar.vue",
4
5
  "NexxtButton": "components/Button/Button.vue",
5
6
  "NexxtCalendar": "components/Calendar/Calendar.vue",
@@ -19,6 +20,7 @@
19
20
  "NexxtIcon": "components/Icon/Icon.vue",
20
21
  "NexxtInfoBlock": "components/InfoBlock/InfoBlock.vue",
21
22
  "NexxtInputField": "components/InputField/InputField.vue",
23
+ "NexxtInputSelect": "components/InputSelect/InputSelect.vue",
22
24
  "NexxtModal": "components/Modal/Modal.vue",
23
25
  "NexxtPagination": "components/Pagination/Pagination.vue",
24
26
  "NexxtPresenceIndicator": "components/PresenceIndicator/PresenceIndicator.vue",
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  // This file is auto-generated by scripts/generate-index.ts
2
2
  export { default as NexxtAnimatedNumber } from './components/AnimatedNumber/AnimatedNumber.vue'
3
+ export { default as NexxtAnnouncement } from './components/Announcement/Announcement.vue'
3
4
  export { default as NexxtAvatar } from './components/Avatar/Avatar.vue'
4
5
  export { default as NexxtButton } from './components/Button/Button.vue'
5
6
  export { default as NexxtCalendar } from './components/Calendar/Calendar.vue'
@@ -19,6 +20,7 @@ export { default as NexxtHeader } from './components/Header/Header.vue'
19
20
  export { default as NexxtIcon } from './components/Icon/Icon.vue'
20
21
  export { default as NexxtInfoBlock } from './components/InfoBlock/InfoBlock.vue'
21
22
  export { default as NexxtInputField } from './components/InputField/InputField.vue'
23
+ export { default as NexxtInputSelect } from './components/InputSelect/InputSelect.vue'
22
24
  export { default as NexxtModal } from './components/Modal/Modal.vue'
23
25
  export { default as NexxtPagination } from './components/Pagination/Pagination.vue'
24
26
  export { default as NexxtPresenceIndicator } from './components/PresenceIndicator/PresenceIndicator.vue'