@nexxtmove/ui 1.1.4 → 1.1.6

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
@@ -47522,6 +47522,7 @@ var Yw, Xw, Zw, Qw, $w, eT = d((() => {
47522
47522
  NexxtProgressBar: "components/ProgressBar/ProgressBar.vue",
47523
47523
  NexxtPropertyCard: "components/PropertyCard/PropertyCard.vue",
47524
47524
  NexxtPropertyListing: "components/PropertyListing/PropertyListing.vue",
47525
+ NexxtReferenceCard: "components/ReferenceCard/ReferenceCard.vue",
47525
47526
  NexxtSelect: "components/Select/Select.vue",
47526
47527
  NexxtSidebarMenuItem: "components/SidebarMenuItem/SidebarMenuItem.vue",
47527
47528
  NexxtSkeleton: "components/Skeleton/Skeleton.vue",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexxtmove/ui",
3
3
  "type": "module",
4
- "version": "1.1.4",
4
+ "version": "1.1.6",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -0,0 +1,179 @@
1
+ <script lang="ts" setup>
2
+ import { computed } from 'vue'
3
+ import NexxtButton from '../Button/Button.vue'
4
+ import NexxtCheckbox from '../Checkbox/Checkbox.vue'
5
+ import NexxtEnergyLabel, { type EnergyLabelLetter } from '../EnergyLabel/EnergyLabel.vue'
6
+ import NexxtIcon from '../Icon/Icon.vue'
7
+
8
+ export interface ProposalReference {
9
+ index: number
10
+ postalCode: string
11
+ streetName: string
12
+ houseNumber: number
13
+ houseType: string
14
+ city: string
15
+ mainImageUrl: string | null
16
+ latitude: number
17
+ longitude: number
18
+ useSurface: number | null
19
+ parcelSurface: number | null
20
+ buildYear: number | null
21
+ volume: number | null
22
+ energyLabel: string | null
23
+ garage: string | null
24
+ insulation: string | null
25
+ shedStorageType: string | null
26
+ saleDate: string | null
27
+ dateOnOfferSince: string | null
28
+ transportDate: string | null
29
+ salePrice: string | null
30
+ indexedSalePrice: string | null
31
+ pricePerSquareMeter: string | null
32
+ }
33
+
34
+ export type NexxtReferenceCardMessage = 'selected' | 'unselected' | 'details' | 'energyLabel'
35
+
36
+ export interface NexxtReferenceCardProps {
37
+ reference: ProposalReference
38
+ messages?: Partial<Record<NexxtReferenceCardMessage, string>>
39
+ locale?: string
40
+ currency?: string
41
+ }
42
+
43
+ const DEFAULT_MESSAGES: Record<NexxtReferenceCardMessage, string> = {
44
+ selected: 'Meegenomen in advies',
45
+ unselected: 'Selecteer deze woning',
46
+ details: 'Meer details',
47
+ energyLabel: 'Energielabel',
48
+ }
49
+
50
+ defineOptions({ name: 'NexxtReferenceCard' })
51
+
52
+ const {
53
+ reference,
54
+ messages = {},
55
+ locale = 'nl-NL',
56
+ currency = 'EUR',
57
+ } = defineProps<NexxtReferenceCardProps>()
58
+
59
+ const label = computed<Record<NexxtReferenceCardMessage, string>>(() => ({
60
+ ...DEFAULT_MESSAGES,
61
+ ...messages,
62
+ }))
63
+
64
+ const selected = defineModel<boolean>({ default: false })
65
+
66
+ defineEmits<{ details: [reference: ProposalReference] }>()
67
+
68
+ const address = computed(() => `${reference.streetName} ${reference.houseNumber}`)
69
+
70
+ const location = computed(() => `${reference.postalCode} ${reference.city}`)
71
+
72
+ const energyLabel = computed(() => (reference.energyLabel ?? null) as EnergyLabelLetter | null)
73
+
74
+ const salePrice = computed(() => {
75
+ if (!reference.salePrice) return null
76
+
77
+ const amount = Number(reference.salePrice)
78
+ if (Number.isNaN(amount)) return reference.salePrice
79
+
80
+ return new Intl.NumberFormat(locale, {
81
+ style: 'currency',
82
+ currency,
83
+ maximumFractionDigits: 0,
84
+ }).format(amount)
85
+ })
86
+
87
+ const saleDate = computed(() => {
88
+ if (!reference.saleDate) return null
89
+
90
+ const date = new Date(reference.saleDate)
91
+ if (Number.isNaN(date.getTime())) return reference.saleDate
92
+
93
+ return new Intl.DateTimeFormat('nl-NL', {
94
+ day: '2-digit',
95
+ month: '2-digit',
96
+ year: 'numeric',
97
+ }).format(date)
98
+ })
99
+ </script>
100
+
101
+ <template>
102
+ <div
103
+ role="checkbox"
104
+ :aria-checked="selected"
105
+ :aria-label="`${address}, ${location}`"
106
+ tabindex="0"
107
+ :class="[
108
+ '@container flex w-full cursor-pointer flex-col overflow-hidden rounded-lg border transition-colors duration-200',
109
+ 'focus-visible:ring-2 focus-visible:ring-cornflower-blue-400 focus-visible:ring-offset-2 focus-visible:outline-none',
110
+ selected
111
+ ? 'border-cornflower-blue-500 hover:border-cornflower-blue-600'
112
+ : 'border-gray-200 hover:border-cornflower-blue-300',
113
+ ]"
114
+ @click="selected = !selected"
115
+ @keydown.space.prevent="selected = !selected"
116
+ @keydown.enter.prevent="selected = !selected"
117
+ >
118
+ <div class="flex flex-col items-stretch bg-white @lg:flex-row">
119
+ <div
120
+ class="relative h-40 w-full self-stretch overflow-hidden bg-gray-100 @lg:h-auto @lg:min-h-32 @lg:w-48 @lg:shrink-0"
121
+ >
122
+ <img
123
+ v-if="reference.mainImageUrl"
124
+ :src="reference.mainImageUrl"
125
+ :alt="address"
126
+ loading="lazy"
127
+ class="absolute inset-0 size-full object-cover"
128
+ />
129
+ <div v-else class="absolute inset-0 flex items-center justify-center">
130
+ <NexxtIcon name="house" class="text-4xl text-gray-500" />
131
+ </div>
132
+ </div>
133
+
134
+ <div
135
+ class="flex min-w-0 flex-1 flex-col justify-center gap-1 border-t border-gray-200 p-4 @lg:border-t-0 @lg:border-l"
136
+ >
137
+ <p class="truncate heading-4">{{ address }}</p>
138
+ <p class="truncate body-normal text-gray-800">{{ location }}</p>
139
+ <div v-if="energyLabel" class="mt-2 flex items-center justify-between gap-2">
140
+ <span class="small-normal text-gray-700">{{ label.energyLabel }}</span>
141
+ <NexxtEnergyLabel :label="energyLabel" />
142
+ </div>
143
+ </div>
144
+
145
+ <div
146
+ v-if="salePrice"
147
+ class="flex flex-col justify-center gap-1 border-t border-gray-200 p-4 text-left @lg:min-w-56 @lg:shrink-0 @lg:border-t-0 @lg:border-l"
148
+ >
149
+ <p class="heading-4 whitespace-nowrap">{{ salePrice }}</p>
150
+ <p v-if="saleDate" class="body-normal text-gray-800">{{ saleDate }}</p>
151
+ </div>
152
+ </div>
153
+
154
+ <div
155
+ :class="[
156
+ 'flex flex-col-reverse gap-3 border-t px-4 py-3',
157
+ '@lg:flex-row @lg:flex-wrap @lg:items-center @lg:justify-between @lg:gap-x-4 @lg:gap-y-2 @lg:py-2',
158
+ selected
159
+ ? 'border-cornflower-blue-500 bg-cornflower-blue-50'
160
+ : 'border-gray-200 bg-gray-50',
161
+ ]"
162
+ >
163
+ <div aria-hidden="true" class="pointer-events-none flex min-w-0 items-center gap-3">
164
+ <NexxtCheckbox :model-value="selected" tabindex="-1" />
165
+ <span class="truncate body-normal">
166
+ {{ selected ? label.selected : label.unselected }}
167
+ </span>
168
+ </div>
169
+
170
+ <NexxtButton
171
+ variant="secondary"
172
+ class="w-full @lg:w-auto"
173
+ @click.stop="$emit('details', reference)"
174
+ >
175
+ {{ label.details }}
176
+ </NexxtButton>
177
+ </div>
178
+ </div>
179
+ </template>
@@ -29,6 +29,7 @@
29
29
  "NexxtProgressBar": "components/ProgressBar/ProgressBar.vue",
30
30
  "NexxtPropertyCard": "components/PropertyCard/PropertyCard.vue",
31
31
  "NexxtPropertyListing": "components/PropertyListing/PropertyListing.vue",
32
+ "NexxtReferenceCard": "components/ReferenceCard/ReferenceCard.vue",
32
33
  "NexxtSelect": "components/Select/Select.vue",
33
34
  "NexxtSidebarMenuItem": "components/SidebarMenuItem/SidebarMenuItem.vue",
34
35
  "NexxtSkeleton": "components/Skeleton/Skeleton.vue",
package/src/index.ts CHANGED
@@ -32,6 +32,7 @@ export { default as NexxtPresenceIndicator } from './components/PresenceIndicato
32
32
  export { default as NexxtProgressBar } from './components/ProgressBar/ProgressBar.vue'
33
33
  export { default as NexxtPropertyCard } from './components/PropertyCard/PropertyCard.vue'
34
34
  export { default as NexxtPropertyListing } from './components/PropertyListing/PropertyListing.vue'
35
+ export { default as NexxtReferenceCard } from './components/ReferenceCard/ReferenceCard.vue'
35
36
  export { default as NexxtSelect } from './components/Select/Select.vue'
36
37
  export { default as NexxtSidebarMenuItem } from './components/SidebarMenuItem/SidebarMenuItem.vue'
37
38
  export { default as NexxtSkeleton } from './components/Skeleton/Skeleton.vue'