@nexxtmove/ui 1.10.0 → 1.12.0

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
@@ -11,6 +11,7 @@ var s = {
11
11
  NexxtEnergyLabel: "components/atoms/EnergyLabel/EnergyLabel.vue",
12
12
  NexxtFloatingPanel: "components/atoms/FloatingPanel/FloatingPanel.vue",
13
13
  NexxtIcon: "components/atoms/Icon/Icon.vue",
14
+ NexxtLoader: "components/atoms/Loader/Loader.vue",
14
15
  NexxtPresenceIndicator: "components/atoms/PresenceIndicator/PresenceIndicator.vue",
15
16
  NexxtPropertyListing: "components/atoms/PropertyListing/PropertyListing.vue",
16
17
  NexxtSelectableOption: "components/atoms/SelectableOption/SelectableOption.vue",
@@ -27,6 +28,7 @@ var s = {
27
28
  NexxtInputField: "components/molecules/InputField/InputField.vue",
28
29
  NexxtInputSelect: "components/molecules/InputSelect/InputSelect.vue",
29
30
  NexxtModalFooter: "components/molecules/ModalFooter/ModalFooter.vue",
31
+ NexxtPageContainer: "components/molecules/PageContainer/PageContainer.vue",
30
32
  NexxtPagination: "components/molecules/Pagination/Pagination.vue",
31
33
  NexxtPropertyCard: "components/molecules/PropertyCard/PropertyCard.vue",
32
34
  NexxtSelect: "components/molecules/Select/Select.vue",
package/dist/ui.css CHANGED
@@ -1,2 +1,2 @@
1
- .timer-circle[data-v-d13bb383]{stroke-dashoffset:0;animation:linear forwards toast-timer-d13bb383}@keyframes toast-timer-d13bb383{to{stroke-dashoffset:var(--b622135e)}}
1
+ rect[data-v-0a5d9b21]{animation-duration:4s;animation-timing-function:cubic-bezier(.77,0,.175,1);animation-iteration-count:infinite}rect[data-v-0a5d9b21]:first-child{animation-name:load-1-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(2){animation-name:load-2-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(3){animation-name:load-3-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(4){animation-name:load-4-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(5){animation-name:load-5-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(6){animation-name:load-6-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(7){animation-name:load-7-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(8){animation-name:load-8-0a5d9b21}@media (prefers-reduced-motion:reduce){rect[data-v-0a5d9b21]{animation:none}svg[data-v-0a5d9b21]{animation:2.5s ease-in-out infinite pulse-0a5d9b21}}@keyframes pulse-0a5d9b21{0%,to{opacity:1}50%{opacity:.65}}@keyframes load-1-0a5d9b21{0%,80%{transform:translate(0)}5%,20%,60%,75%{transform:translate(-25px,25px)}30%,50%{transform:translate(-75px,75px)}}@keyframes load-2-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(50px)}30%,50%{transform:translateY(50px)}}@keyframes load-3-0a5d9b21{10%,70%{transform:translate(0%)}15%,65%{transform:translateY(-50px)}20%,60%{fill:var(--color-sapphire-500);transform:translateY(-50px)}30%,50%{fill:var(--color-purple-500);transform:translate(-50px)}}@keyframes load-4-0a5d9b21{20%,60%{transform:translate(0%)}30%,50%{transform:translate(50px,-50px)}}@keyframes load-5-0a5d9b21{0%,80%{transform:translate(0%)}5%,20%,60%,75%{transform:translateY(50px)}30%,50%{transform:translate(50px)}}@keyframes load-6-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(-50px)}30%,50%{transform:translateY(-50px)}}@keyframes load-7-0a5d9b21{10%,70%{transform:translate(0%)}15%,20%,60%,65%{transform:translate(50px)}30%,50%{transform:translate(100px,-50px)}}@keyframes load-8-0a5d9b21{15%,65%{transform:translate(0%)}20%,60%{transform:translateY(-50px)}30%,50%{transform:translate(50px,-100px)}}.timer-circle[data-v-d13bb383]{stroke-dashoffset:0;animation:linear forwards toast-timer-d13bb383}@keyframes toast-timer-d13bb383{to{stroke-dashoffset:var(--b622135e)}}
2
2
  /*$vite$:1*/
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexxtmove/ui",
3
3
  "type": "module",
4
- "version": "1.10.0",
4
+ "version": "1.12.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -0,0 +1,241 @@
1
+ <script setup lang="ts">
2
+ interface NexxtLoaderProps {
3
+ /** Read out by screen readers while the loader is visible. */
4
+ label?: string
5
+ }
6
+
7
+ defineOptions({
8
+ name: 'NexxtLoader',
9
+ })
10
+
11
+ const { label = 'Bezig met laden' } = defineProps<NexxtLoaderProps>()
12
+ </script>
13
+
14
+ <template>
15
+ <svg
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ viewBox="-20 0 283 142"
18
+ role="status"
19
+ :aria-label="label"
20
+ width="96"
21
+ height="96"
22
+ >
23
+ <g transform="rotate(45)">
24
+ <rect class="fill-orange-500" x="175" y="-150" width="50" height="50" />
25
+ <rect
26
+ class="fill-cornflower-blue-500 stroke-cornflower-blue-500 stroke-1"
27
+ x="100"
28
+ y="-125"
29
+ width="50"
30
+ height="50"
31
+ />
32
+ <rect
33
+ class="fill-sapphire-500 stroke-sapphire-500 stroke-1"
34
+ x="150"
35
+ y="-75"
36
+ width="50"
37
+ height="50"
38
+ />
39
+ <rect class="fill-purple-500" x="50" y="-25" width="50" height="50" />
40
+
41
+ <rect class="fill-orange-500" x="50" y="-75" width="50" height="50" />
42
+ <rect class="fill-orange-500" x="100" y="-25" width="50" height="50" />
43
+
44
+ <rect class="fill-rose-500" x="0" y="-25" width="50" height="50" />
45
+ <rect class="fill-purple-500" x="50" y="25" width="50" height="50" />
46
+ </g>
47
+ </svg>
48
+ </template>
49
+
50
+ <style scoped>
51
+ rect {
52
+ animation-iteration-count: infinite;
53
+ animation-duration: 4s;
54
+ animation-timing-function: cubic-bezier(0.77, 0, 0.175, 1);
55
+
56
+ &:nth-child(1) {
57
+ animation-name: load-1;
58
+ }
59
+ &:nth-child(2) {
60
+ animation-name: load-2;
61
+ }
62
+ &:nth-child(3) {
63
+ animation-name: load-3;
64
+ }
65
+ &:nth-child(4) {
66
+ animation-name: load-4;
67
+ }
68
+ &:nth-child(5) {
69
+ animation-name: load-5;
70
+ }
71
+ &:nth-child(6) {
72
+ animation-name: load-6;
73
+ }
74
+ &:nth-child(7) {
75
+ animation-name: load-7;
76
+ }
77
+ &:nth-child(8) {
78
+ animation-name: load-8;
79
+ }
80
+ }
81
+
82
+ /* Reduced motion is gentler feedback, not none: the blocks hold their resting
83
+ layout (still the logo) while a slow opacity pulse keeps signalling that
84
+ something is happening, without any movement. */
85
+ @media (prefers-reduced-motion: reduce) {
86
+ rect {
87
+ animation: none;
88
+ }
89
+
90
+ svg {
91
+ animation: pulse 2.5s ease-in-out infinite;
92
+ }
93
+ }
94
+
95
+ @keyframes pulse {
96
+ 0%,
97
+ 100% {
98
+ opacity: 1;
99
+ }
100
+ 50% {
101
+ opacity: 0.65;
102
+ }
103
+ }
104
+
105
+ @keyframes load-1 {
106
+ 0%,
107
+ 80% {
108
+ transform: translate(0, 0);
109
+ }
110
+ 5%,
111
+ 20%,
112
+ 60%,
113
+ 75% {
114
+ transform: translate(-25px, 25px);
115
+ }
116
+ 30%,
117
+ 50% {
118
+ transform: translate(-75px, 75px);
119
+ }
120
+ }
121
+
122
+ @keyframes load-2 {
123
+ 5%,
124
+ 75% {
125
+ transform: translate(0%, 0%);
126
+ }
127
+ 10%,
128
+ 20%,
129
+ 60%,
130
+ 70% {
131
+ transform: translate(50px, 0px);
132
+ }
133
+ 30%,
134
+ 50% {
135
+ transform: translate(0, 50px);
136
+ }
137
+ }
138
+
139
+ /* All eight blocks converge on one cell at 30-50%, and rect 8 paints last, so
140
+ the merged block reads as rect 8's purple. This block makes the horizontal
141
+ slide in and out of that stack; its fill morphs to purple on the way in and
142
+ back to its own sapphire on the way out, so it appears to take on and shed
143
+ the stack's color. */
144
+ @keyframes load-3 {
145
+ 10%,
146
+ 70% {
147
+ transform: translate(0%, 0%);
148
+ }
149
+ 15%,
150
+ 65% {
151
+ transform: translate(0, -50px);
152
+ }
153
+ 20%,
154
+ 60% {
155
+ fill: var(--color-sapphire-500);
156
+ transform: translate(0, -50px);
157
+ }
158
+ 30%,
159
+ 50% {
160
+ fill: var(--color-purple-500);
161
+ transform: translate(-50px, 0);
162
+ }
163
+ }
164
+
165
+ @keyframes load-4 {
166
+ 20%,
167
+ 60% {
168
+ transform: translate(0%, 0%);
169
+ }
170
+ 30%,
171
+ 50% {
172
+ transform: translate(50px, -50px);
173
+ }
174
+ }
175
+
176
+ @keyframes load-5 {
177
+ 0%,
178
+ 80% {
179
+ transform: translate(0%, 0%);
180
+ }
181
+ 5%,
182
+ 20%,
183
+ 60%,
184
+ 75% {
185
+ transform: translate(0, 50px);
186
+ }
187
+ 30%,
188
+ 50% {
189
+ transform: translate(50px, -0);
190
+ }
191
+ }
192
+
193
+ @keyframes load-6 {
194
+ 5%,
195
+ 75% {
196
+ transform: translate(0%, 0%);
197
+ }
198
+ 10%,
199
+ 20%,
200
+ 60%,
201
+ 70% {
202
+ transform: translate(-50px, 0);
203
+ }
204
+ 30%,
205
+ 50% {
206
+ transform: translate(0, -50px);
207
+ }
208
+ }
209
+
210
+ @keyframes load-7 {
211
+ 10%,
212
+ 70% {
213
+ transform: translate(0%, 0%);
214
+ }
215
+ 15%,
216
+ 20%,
217
+ 60%,
218
+ 65% {
219
+ transform: translate(50px, 0);
220
+ }
221
+ 30%,
222
+ 50% {
223
+ transform: translate(100px, -50px);
224
+ }
225
+ }
226
+
227
+ @keyframes load-8 {
228
+ 15%,
229
+ 65% {
230
+ transform: translate(0%, 0%);
231
+ }
232
+ 20%,
233
+ 60% {
234
+ transform: translate(0, -50px);
235
+ }
236
+ 30%,
237
+ 50% {
238
+ transform: translate(50px, -100px);
239
+ }
240
+ }
241
+ </style>
@@ -0,0 +1,63 @@
1
+ <script setup lang="ts">
2
+ type ContentWidth = keyof typeof CONTENT_WIDTHS
3
+
4
+ interface NexxtPageContainerProps {
5
+ /** Maximum width of the content area; the content is centered within it. */
6
+ maxWidth?: ContentWidth
7
+ }
8
+
9
+ defineOptions({
10
+ name: 'NexxtPageContainer',
11
+ })
12
+
13
+ const { maxWidth = '7xl' } = defineProps<NexxtPageContainerProps>()
14
+
15
+ // Full class names so Tailwind and the no-unknown-classes lint rule see them.
16
+ const CONTENT_WIDTHS = {
17
+ xs: 'max-w-xs',
18
+ sm: 'max-w-sm',
19
+ md: 'max-w-md',
20
+ lg: 'max-w-lg',
21
+ xl: 'max-w-xl',
22
+ '2xl': 'max-w-2xl',
23
+ '3xl': 'max-w-3xl',
24
+ '4xl': 'max-w-4xl',
25
+ '5xl': 'max-w-5xl',
26
+ '6xl': 'max-w-6xl',
27
+ '7xl': 'max-w-7xl',
28
+ '8xl': 'max-w-8xl',
29
+ full: 'max-w-full-width',
30
+ } as const
31
+ </script>
32
+
33
+ <template>
34
+ <div class="flex h-full min-h-0 flex-1">
35
+ <div class="h-full min-w-0 grow overflow-y-auto p-8">
36
+ <div :class="['mx-auto', CONTENT_WIDTHS[maxWidth]]">
37
+ <slot />
38
+ </div>
39
+ </div>
40
+
41
+ <Transition
42
+ enter-active-class="transition-[max-width,opacity] duration-300 ease-[cubic-bezier(0.77,0,0.175,1)] motion-reduce:transition-none"
43
+ enter-from-class="max-w-0 opacity-0"
44
+ enter-to-class="max-w-105 opacity-100"
45
+ leave-active-class="transition-[max-width,opacity] duration-300 ease-[cubic-bezier(0.77,0,0.175,1)] motion-reduce:transition-none"
46
+ leave-from-class="max-w-105 opacity-100"
47
+ leave-to-class="max-w-0 opacity-0"
48
+ >
49
+ <aside
50
+ v-if="$slots.sidebar"
51
+ class="h-full w-105 shrink-0 overflow-hidden border-l border-gray-100 bg-white"
52
+ >
53
+ <!-- Fixed width on purpose: the transition shrinks the aside's
54
+ max-width, and a w-full wrapper would reflow (rewrap) the content
55
+ every frame. At w-105 the content keeps its layout and the
56
+ aside's overflow-hidden clips it instead. -->
57
+ <div class="h-full w-105 overflow-y-auto p-8">
58
+ <slot name="sidebar" />
59
+ </div>
60
+ </aside>
61
+ </Transition>
62
+ </div>
63
+ </template>
@@ -8,6 +8,7 @@
8
8
  "NexxtEnergyLabel": "components/atoms/EnergyLabel/EnergyLabel.vue",
9
9
  "NexxtFloatingPanel": "components/atoms/FloatingPanel/FloatingPanel.vue",
10
10
  "NexxtIcon": "components/atoms/Icon/Icon.vue",
11
+ "NexxtLoader": "components/atoms/Loader/Loader.vue",
11
12
  "NexxtPresenceIndicator": "components/atoms/PresenceIndicator/PresenceIndicator.vue",
12
13
  "NexxtPropertyListing": "components/atoms/PropertyListing/PropertyListing.vue",
13
14
  "NexxtSelectableOption": "components/atoms/SelectableOption/SelectableOption.vue",
@@ -24,6 +25,7 @@
24
25
  "NexxtInputField": "components/molecules/InputField/InputField.vue",
25
26
  "NexxtInputSelect": "components/molecules/InputSelect/InputSelect.vue",
26
27
  "NexxtModalFooter": "components/molecules/ModalFooter/ModalFooter.vue",
28
+ "NexxtPageContainer": "components/molecules/PageContainer/PageContainer.vue",
27
29
  "NexxtPagination": "components/molecules/Pagination/Pagination.vue",
28
30
  "NexxtPropertyCard": "components/molecules/PropertyCard/PropertyCard.vue",
29
31
  "NexxtSelect": "components/molecules/Select/Select.vue",
package/src/index.ts CHANGED
@@ -38,8 +38,10 @@ export { default as NexxtIcon } from './components/atoms/Icon/Icon.vue'
38
38
  export { default as NexxtInfoBlock } from './components/molecules/InfoBlock/InfoBlock.vue'
39
39
  export { default as NexxtInputField } from './components/molecules/InputField/InputField.vue'
40
40
  export { default as NexxtInputSelect } from './components/molecules/InputSelect/InputSelect.vue'
41
+ export { default as NexxtLoader } from './components/atoms/Loader/Loader.vue'
41
42
  export { default as NexxtModal } from './components/organisms/Modal/Modal.vue'
42
43
  export { default as NexxtModalFooter } from './components/molecules/ModalFooter/ModalFooter.vue'
44
+ export { default as NexxtPageContainer } from './components/molecules/PageContainer/PageContainer.vue'
43
45
  export { default as NexxtPagination } from './components/molecules/Pagination/Pagination.vue'
44
46
  export { default as NexxtPresenceIndicator } from './components/atoms/PresenceIndicator/PresenceIndicator.vue'
45
47
  export { default as NexxtProgressBar } from './components/organisms/ProgressBar/ProgressBar.vue'
@@ -37,3 +37,11 @@
37
37
  display: none;
38
38
  }
39
39
  }
40
+
41
+ /* Layout tokens for NexxtPageContainer. Moved over from the app theme
42
+ (app/assets/css/main.css); the app drops its copies once it adopts the
43
+ version that ships these. */
44
+ @theme {
45
+ --spacing-8xl: 100rem;
46
+ --spacing-full-width: 116rem; /* 1920px (full hd) minus the sidebar: max app width */
47
+ }