accomadesc 0.3.41 → 0.4.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/README.md +130 -34
- package/dist/AccoCard.svelte +1 -1
- package/dist/CalendarAvailable.svelte +1 -1
- package/dist/MainNav.svelte +1 -2
- package/dist/PageComponent.svelte +1 -2
- package/dist/PhotoGallery.svelte +5 -1
- package/dist/Pricing.svelte +81 -168
- package/dist/SiteState.svelte.d.ts +1 -1
- package/dist/SiteState.svelte.js +21 -13
- package/dist/basic/TextInput.svelte +69 -116
- package/dist/basic/TextInput.svelte.d.ts +2 -0
- package/dist/basic/icons/actions.d.ts +13 -0
- package/dist/basic/icons/actions.js +44 -0
- package/dist/basic/icons/navigation.d.ts +6 -0
- package/dist/basic/icons/navigation.js +16 -0
- package/dist/basic/icons/ui.d.ts +13 -0
- package/dist/basic/icons/ui.js +44 -0
- package/dist/basic/icons.d.ts +4 -0
- package/dist/basic/icons.js +51 -413
- package/dist/helpers/debounce.js +8 -2
- package/dist/helpers/format.js +2 -1
- package/dist/helpers/normalizeDate.d.ts +1 -1
- package/dist/helpers/normalizeDate.js +25 -16
- package/dist/helpers/readICS.js +21 -4
- package/dist/index.d.ts +1 -1
- package/dist/names/README.md +1 -1
- package/dist/names/gen.js +10 -1
- package/dist/occuplan/state.svelte.js +7 -3
- package/dist/occusplan-link/OccuPlanAvailableInfo.svelte +38 -0
- package/dist/occusplan-link/OccuPlanGrid.svelte +375 -0
- package/dist/occusplan-link/OccuPlanPicker.svelte +575 -0
- package/dist/occusplan-link/OccuPlanRows.svelte +368 -0
- package/dist/occusplan-link/OccuPlanWrapper.svelte +108 -0
- package/dist/occusplan-link/defaultTranslations.js +157 -0
- package/dist/occusplan-link/state.svelte.d.ts +92 -0
- package/dist/occusplan-link/state.svelte.js +424 -0
- package/dist/svg/LogoSVG.svelte +0 -1
- package/dist/types.d.ts +2 -1
- package/package.json +12 -6
package/README.md
CHANGED
|
@@ -1,64 +1,160 @@
|
|
|
1
|
-
#
|
|
1
|
+
# accomadesc (Accomade Svelte Components)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A collection of Svelte 5 components used throughout Accomade products and websites. Provides reusable UI components for accommodation listings including calendars, pricing displays, photo galleries, booking forms, and more.
|
|
4
4
|
|
|
5
|
+
## Installation
|
|
5
6
|
|
|
7
|
+
```bash
|
|
8
|
+
npm install accomadesc
|
|
9
|
+
```
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
Peer dependencies (must be installed separately):
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npm install svelte @sveltejs/kit
|
|
15
|
+
```
|
|
10
16
|
|
|
11
|
-
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```svelte
|
|
20
|
+
<script>
|
|
21
|
+
import { Button, AccoCard } from 'accomadesc';
|
|
22
|
+
|
|
23
|
+
const card = {
|
|
24
|
+
id: '1',
|
|
25
|
+
kind: 'acco-card',
|
|
26
|
+
content: {
|
|
27
|
+
title: 'Beach House',
|
|
28
|
+
photos: [{ url: '/house.jpg', alt: 'Beach house' }],
|
|
29
|
+
prices: { from: 150, to: 300, currency: 'EUR' },
|
|
30
|
+
amenities: ['wifi', 'parking'],
|
|
31
|
+
url: '/beach-house',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<AccoCard {...card} />
|
|
37
|
+
<Button variant="primary">Book Now</Button>
|
|
38
|
+
```
|
|
12
39
|
|
|
13
|
-
##
|
|
40
|
+
## Block System
|
|
14
41
|
|
|
15
|
-
|
|
42
|
+
The library uses a block-based content system. Each block has:
|
|
16
43
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
44
|
+
- `id: string` - Unique identifier
|
|
45
|
+
- `kind: string` - Block type discriminator
|
|
46
|
+
- `content: T` - Block-specific content
|
|
47
|
+
|
|
48
|
+
Use type guards for type narrowing:
|
|
20
49
|
|
|
21
|
-
|
|
22
|
-
|
|
50
|
+
```typescript
|
|
51
|
+
import { isBookingRequest, type AccoBlock } from 'accomadesc';
|
|
52
|
+
|
|
53
|
+
function processBlock(block: AccoBlock) {
|
|
54
|
+
if (isBookingRequest(block)) {
|
|
55
|
+
// TypeScript knows block is BookingRequest
|
|
56
|
+
}
|
|
57
|
+
}
|
|
23
58
|
```
|
|
24
59
|
|
|
25
|
-
##
|
|
60
|
+
## Core Components
|
|
26
61
|
|
|
27
|
-
|
|
62
|
+
### Basic UI
|
|
28
63
|
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
- `Button` - Multi-variant button component
|
|
65
|
+
- `TextInput` - Form text input with validation
|
|
66
|
+
- `Icon` - SVG icon renderer
|
|
67
|
+
- `Avatar` - User avatar display
|
|
68
|
+
- `Spinner` - Loading indicator
|
|
69
|
+
- `Notes` - Annotations and notes
|
|
31
70
|
|
|
32
|
-
|
|
33
|
-
npm run dev -- --open
|
|
34
|
-
```
|
|
71
|
+
### Content Display
|
|
35
72
|
|
|
36
|
-
|
|
73
|
+
- `AccoCard` - Accommodation summary card
|
|
74
|
+
- `AccoDescription` - Property description
|
|
75
|
+
- `AmenitiesCore` - Amenities display
|
|
76
|
+
- `Photo` / `PhotoGallery` - Image handling
|
|
77
|
+
- `Section` / `Text` - Content sections
|
|
78
|
+
- `LeafletMap` - Location map
|
|
79
|
+
- `Weather` - Weather information
|
|
37
80
|
|
|
38
|
-
|
|
81
|
+
### Booking & Calendar
|
|
39
82
|
|
|
40
|
-
|
|
83
|
+
- `Calendar` - Availability calendar
|
|
84
|
+
- `CalendarGrid` - Grid-based calendar view
|
|
85
|
+
- `CalendarRows` - Row-based calendar view
|
|
86
|
+
- `CalendarAvailable` - Availability summary
|
|
87
|
+
- `BookingRequest` - Booking request form
|
|
88
|
+
- `ContactForm` - Contact form
|
|
41
89
|
|
|
42
|
-
|
|
43
|
-
npm run package
|
|
44
|
-
```
|
|
90
|
+
### Pricing
|
|
45
91
|
|
|
46
|
-
|
|
92
|
+
- `Pricing` - Detailed pricing table
|
|
93
|
+
- `PricingShort` - Compact pricing display
|
|
47
94
|
|
|
48
|
-
|
|
49
|
-
|
|
95
|
+
### Layout
|
|
96
|
+
|
|
97
|
+
- `PageComponent` - Full page wrapper
|
|
98
|
+
- `PageHeader` / `PageFooter` - Page sections
|
|
99
|
+
- `MainNav` / `NavItem` - Navigation
|
|
100
|
+
|
|
101
|
+
## Internationalization
|
|
102
|
+
|
|
103
|
+
Components accept i18n functions as props:
|
|
104
|
+
|
|
105
|
+
```svelte
|
|
106
|
+
<script>
|
|
107
|
+
import { BookingRequest } from 'accomadesc';
|
|
108
|
+
|
|
109
|
+
let props = {
|
|
110
|
+
translateFunc: (key: string) => translations[key],
|
|
111
|
+
formatMoneyFunc: (amount: number, currency: string) =>
|
|
112
|
+
new Intl.NumberFormat().format(amount) + ' ' + currency,
|
|
113
|
+
formatDateFunc: (date: Date) => date.toLocaleDateString(),
|
|
114
|
+
};
|
|
115
|
+
</script>
|
|
116
|
+
|
|
117
|
+
<BookingRequest {...props} />
|
|
50
118
|
```
|
|
51
119
|
|
|
52
|
-
|
|
120
|
+
## State Management
|
|
53
121
|
|
|
54
|
-
|
|
122
|
+
Use `SiteState` for application state:
|
|
55
123
|
|
|
56
|
-
|
|
124
|
+
```typescript
|
|
125
|
+
import { SiteState } from 'accomadesc';
|
|
57
126
|
|
|
58
|
-
|
|
127
|
+
const site = new SiteState({
|
|
128
|
+
lang: 'en',
|
|
129
|
+
siteConfig: { ... },
|
|
130
|
+
translateFunc: (key) => ...,
|
|
131
|
+
formatMoneyFunc: (amount, currency) => ...,
|
|
132
|
+
formatDateFunc: (date) => ...,
|
|
133
|
+
});
|
|
134
|
+
```
|
|
59
135
|
|
|
60
|
-
|
|
136
|
+
## Development
|
|
61
137
|
|
|
62
138
|
```bash
|
|
63
|
-
|
|
139
|
+
# Install dependencies
|
|
140
|
+
pnpm install
|
|
141
|
+
|
|
142
|
+
# Start dev server
|
|
143
|
+
pnpm run dev
|
|
144
|
+
|
|
145
|
+
# Run tests
|
|
146
|
+
pnpm run test
|
|
147
|
+
|
|
148
|
+
# Type check
|
|
149
|
+
pnpm run check
|
|
150
|
+
|
|
151
|
+
# Format code
|
|
152
|
+
pnpm run format
|
|
153
|
+
|
|
154
|
+
# Build library
|
|
155
|
+
pnpm run package
|
|
64
156
|
```
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|
package/dist/AccoCard.svelte
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
let translatedSlug = $derived(translateFunc && slug ? translateFunc(slug) : '');
|
|
22
22
|
</script>
|
|
23
23
|
|
|
24
|
-
<div class="accocard-wrapper">
|
|
24
|
+
<div class="accocard-wrapper" data-testid="accocard-wrapper">
|
|
25
25
|
<div class="title-with-slug">
|
|
26
26
|
<h2>{displayName}</h2>
|
|
27
27
|
{#if slug}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
DateTime.utc().set({ day: 31, month: 12 }).plus({ years: maxFutureYears }),
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
-
const formatAvailability = (from: DateTime | null, forDays: number): string => {
|
|
23
|
+
const formatAvailability = (from: DateTime | null | undefined, forDays: number): string => {
|
|
24
24
|
if (!formatFunc || !formatDateFunc) return '';
|
|
25
25
|
if (from == null) {
|
|
26
26
|
const formattedFutureDate = formatDateFunc(maxFutureDate);
|
package/dist/MainNav.svelte
CHANGED
|
@@ -21,11 +21,10 @@
|
|
|
21
21
|
|
|
22
22
|
const pathForLang = (lang: string) => {
|
|
23
23
|
const pathElements = currentPath.split('/');
|
|
24
|
-
//initial slash results in empty string real first element
|
|
25
24
|
if (pathElements.length == 1) return `/${lang}`;
|
|
26
25
|
|
|
27
26
|
const firstElement = pathElements[1];
|
|
28
|
-
if (supportedLangs?.includes(firstElement)) {
|
|
27
|
+
if (firstElement && supportedLangs?.includes(firstElement)) {
|
|
29
28
|
return ['', lang, ...pathElements.slice(2)].join('/');
|
|
30
29
|
} else {
|
|
31
30
|
return ['', lang, ...pathElements.slice(1)].join('/');
|
|
@@ -53,11 +53,10 @@
|
|
|
53
53
|
let currentPath = $derived(page.url.pathname);
|
|
54
54
|
const pathForLang = (lang: string) => {
|
|
55
55
|
const pathElements = currentPath.split('/');
|
|
56
|
-
//initial slash results in empty string real first element
|
|
57
56
|
if (pathElements.length == 1) return `/${lang}`;
|
|
58
57
|
|
|
59
58
|
const firstElement = pathElements[1];
|
|
60
|
-
if (supportedLangs?.includes(firstElement)) {
|
|
59
|
+
if (firstElement && supportedLangs?.includes(firstElement)) {
|
|
61
60
|
return ['', lang, ...pathElements.slice(2)].join('/');
|
|
62
61
|
} else {
|
|
63
62
|
return ['', lang, ...pathElements.slice(1)].join('/');
|
package/dist/PhotoGallery.svelte
CHANGED
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
let zoomed: number | null = $state(0);
|
|
26
|
-
let zoomedPhoto: Photo | null = $derived(
|
|
26
|
+
let zoomedPhoto: Photo | null = $derived.by(() => {
|
|
27
|
+
if (zoomed === null) return null;
|
|
28
|
+
const photo = photos[zoomed];
|
|
29
|
+
return photo ?? null;
|
|
30
|
+
});
|
|
27
31
|
|
|
28
32
|
const zoom = (i: number) => {
|
|
29
33
|
zoomed = i;
|
package/dist/Pricing.svelte
CHANGED
|
@@ -155,42 +155,20 @@
|
|
|
155
155
|
return result;
|
|
156
156
|
};
|
|
157
157
|
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const entry = range.entry;
|
|
163
|
-
switch (col) {
|
|
164
|
-
case 'timeRange':
|
|
165
|
-
result = formatRangeCol(range);
|
|
166
|
-
break;
|
|
167
|
-
case 'firstNight':
|
|
168
|
-
result = formatFirstNightPriceCol(entry);
|
|
169
|
-
break;
|
|
170
|
-
case 'eachNight':
|
|
171
|
-
result = formatEachNightCol(entry);
|
|
172
|
-
break;
|
|
173
|
-
case 'extraPerson':
|
|
174
|
-
result = formatExtraPersonCol(entry);
|
|
175
|
-
break;
|
|
176
|
-
case 'minNumNights':
|
|
177
|
-
result = formatMinNightsCol(entry);
|
|
178
|
-
break;
|
|
179
|
-
case 'peopleNum':
|
|
180
|
-
result = formatPeopleNum(entry);
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
return result;
|
|
158
|
+
const isStaticRange = (range: PricingRange | StaticPricingRange): range is StaticPricingRange => {
|
|
159
|
+
return (
|
|
160
|
+
'from' in range && 'to' in range && typeof range.from === 'object' && 'month' in range.from
|
|
161
|
+
);
|
|
184
162
|
};
|
|
185
163
|
|
|
186
|
-
const
|
|
164
|
+
const colOutput = (range: PricingRange | StaticPricingRange, col: PricingColumn): string => {
|
|
187
165
|
let result = '';
|
|
188
166
|
if (!formatDateFunc || !translateFunc || !formatMoneyFunc || !formatFunc) return result;
|
|
189
167
|
|
|
190
168
|
const entry = range.entry;
|
|
191
169
|
switch (col) {
|
|
192
170
|
case 'timeRange':
|
|
193
|
-
result = formatStaticRangeCol(range);
|
|
171
|
+
result = isStaticRange(range) ? formatStaticRangeCol(range) : formatRangeCol(range);
|
|
194
172
|
break;
|
|
195
173
|
case 'firstNight':
|
|
196
174
|
result = formatFirstNightPriceCol(entry);
|
|
@@ -235,6 +213,79 @@
|
|
|
235
213
|
</thead>
|
|
236
214
|
{/snippet}
|
|
237
215
|
|
|
216
|
+
{#snippet pricingTable(data: PricingRange[] | StaticPricingRange[])}
|
|
217
|
+
{#if w > 799}
|
|
218
|
+
<table class="pricing-table">
|
|
219
|
+
{@render wideTableHead()}
|
|
220
|
+
<tbody>
|
|
221
|
+
{#each data as e}
|
|
222
|
+
<tr>
|
|
223
|
+
{#each columns as h}
|
|
224
|
+
<td style={colCellStyle[h]}>
|
|
225
|
+
{@html colOutput(e, h)}
|
|
226
|
+
</td>
|
|
227
|
+
{/each}
|
|
228
|
+
</tr>
|
|
229
|
+
{/each}
|
|
230
|
+
</tbody>
|
|
231
|
+
</table>
|
|
232
|
+
{:else if w > 400 && w < 800}
|
|
233
|
+
<table class="pricing-table">
|
|
234
|
+
{#each data as e}
|
|
235
|
+
<thead>
|
|
236
|
+
<tr>
|
|
237
|
+
<th colspan="2" scope="col">
|
|
238
|
+
{@html colOutput(e, 'timeRange')}
|
|
239
|
+
</th>
|
|
240
|
+
</tr>
|
|
241
|
+
</thead>
|
|
242
|
+
<tbody>
|
|
243
|
+
{#each columns as h}
|
|
244
|
+
{#if h !== 'timeRange'}
|
|
245
|
+
<tr>
|
|
246
|
+
<th scope="row">
|
|
247
|
+
{@html translateFunc ? translateFunc(h) : ''}:
|
|
248
|
+
</th>
|
|
249
|
+
<td>
|
|
250
|
+
{@html colOutput(e, h)}
|
|
251
|
+
</td></tr
|
|
252
|
+
>
|
|
253
|
+
{/if}
|
|
254
|
+
{/each}
|
|
255
|
+
</tbody>
|
|
256
|
+
{/each}
|
|
257
|
+
</table>
|
|
258
|
+
{:else}
|
|
259
|
+
<table class="pricing-table">
|
|
260
|
+
{#each data as e}
|
|
261
|
+
<thead>
|
|
262
|
+
<tr>
|
|
263
|
+
<th scope="col" class="main-header">
|
|
264
|
+
{@html colOutput(e, 'timeRange')}
|
|
265
|
+
</th>
|
|
266
|
+
</tr>
|
|
267
|
+
</thead>
|
|
268
|
+
<tbody>
|
|
269
|
+
{#each columns as h}
|
|
270
|
+
{#if h !== 'timeRange'}
|
|
271
|
+
<tr>
|
|
272
|
+
<th scope="row">
|
|
273
|
+
{@html translateFunc ? translateFunc(h) : h}:
|
|
274
|
+
</th>
|
|
275
|
+
</tr>
|
|
276
|
+
<tr>
|
|
277
|
+
<td>
|
|
278
|
+
{@html colOutput(e, h)}
|
|
279
|
+
</td>
|
|
280
|
+
</tr>
|
|
281
|
+
{/if}
|
|
282
|
+
{/each}
|
|
283
|
+
</tbody>
|
|
284
|
+
{/each}
|
|
285
|
+
</table>
|
|
286
|
+
{/if}
|
|
287
|
+
{/snippet}
|
|
288
|
+
|
|
238
289
|
{#key currentLang}
|
|
239
290
|
<figure bind:clientWidth={w} class="pricing-wrapper">
|
|
240
291
|
{#if global}
|
|
@@ -281,148 +332,10 @@
|
|
|
281
332
|
</table>
|
|
282
333
|
{/if}
|
|
283
334
|
{#if staticRanges.length > 0}
|
|
284
|
-
{
|
|
285
|
-
<table class="pricing-table">
|
|
286
|
-
{@render wideTableHead()}
|
|
287
|
-
<tbody>
|
|
288
|
-
{#each staticRanges as e}
|
|
289
|
-
<tr>
|
|
290
|
-
{#each columns as h}
|
|
291
|
-
<td style={colCellStyle[h]}>
|
|
292
|
-
{@html colOutputStaticRange(e, h)}
|
|
293
|
-
</td>
|
|
294
|
-
{/each}
|
|
295
|
-
</tr>
|
|
296
|
-
{/each}
|
|
297
|
-
</tbody>
|
|
298
|
-
</table>
|
|
299
|
-
{:else if w > 400 && w < 800}
|
|
300
|
-
<table class="pricing-table">
|
|
301
|
-
{#each staticRanges as e}
|
|
302
|
-
<thead>
|
|
303
|
-
<tr>
|
|
304
|
-
<th colspan="2" scope="col">
|
|
305
|
-
{@html colOutputStaticRange(e, 'timeRange')}
|
|
306
|
-
</th>
|
|
307
|
-
</tr>
|
|
308
|
-
</thead>
|
|
309
|
-
<tbody>
|
|
310
|
-
{#each columns as h}
|
|
311
|
-
{#if h !== 'timeRange'}
|
|
312
|
-
<tr>
|
|
313
|
-
<th scope="row">
|
|
314
|
-
{@html translateFunc ? translateFunc(h) : ''}:
|
|
315
|
-
</th>
|
|
316
|
-
<td>
|
|
317
|
-
{@html colOutputStaticRange(e, h)}
|
|
318
|
-
</td></tr
|
|
319
|
-
>
|
|
320
|
-
{/if}
|
|
321
|
-
{/each}
|
|
322
|
-
</tbody>
|
|
323
|
-
{/each}
|
|
324
|
-
</table>
|
|
325
|
-
{:else}
|
|
326
|
-
<table class="pricing-table">
|
|
327
|
-
{#each staticRanges as e}
|
|
328
|
-
<thead>
|
|
329
|
-
<tr>
|
|
330
|
-
<th scope="col" class="main-header">
|
|
331
|
-
{@html colOutputStaticRange(e, 'timeRange')}
|
|
332
|
-
</th>
|
|
333
|
-
</tr>
|
|
334
|
-
</thead>
|
|
335
|
-
<tbody>
|
|
336
|
-
{#each columns as h}
|
|
337
|
-
{#if h !== 'timeRange'}
|
|
338
|
-
<tr>
|
|
339
|
-
<th scope="row">
|
|
340
|
-
{@html translateFunc ? translateFunc(h) : h}:
|
|
341
|
-
</th>
|
|
342
|
-
</tr>
|
|
343
|
-
<tr>
|
|
344
|
-
<td>
|
|
345
|
-
{@html colOutputStaticRange(e, h)}
|
|
346
|
-
</td>
|
|
347
|
-
</tr>
|
|
348
|
-
{/if}
|
|
349
|
-
{/each}
|
|
350
|
-
</tbody>
|
|
351
|
-
{/each}
|
|
352
|
-
</table>
|
|
353
|
-
{/if}
|
|
335
|
+
{@render pricingTable(staticRanges)}
|
|
354
336
|
{/if}
|
|
355
337
|
{#if filteredRanges.length > 0}
|
|
356
|
-
{
|
|
357
|
-
<table class="pricing-table">
|
|
358
|
-
{@render wideTableHead()}
|
|
359
|
-
<tbody>
|
|
360
|
-
{#each filteredRanges as e}
|
|
361
|
-
<tr>
|
|
362
|
-
{#each columns as h}
|
|
363
|
-
<td style={colCellStyle[h]}>
|
|
364
|
-
{@html colOutputRange(e, h)}
|
|
365
|
-
</td>
|
|
366
|
-
{/each}
|
|
367
|
-
</tr>
|
|
368
|
-
{/each}
|
|
369
|
-
</tbody>
|
|
370
|
-
</table>
|
|
371
|
-
{:else if w > 400 && w < 800}
|
|
372
|
-
<table class="pricing-table">
|
|
373
|
-
{#each filteredRanges as e}
|
|
374
|
-
<thead>
|
|
375
|
-
<tr>
|
|
376
|
-
<th colspan="2" scope="col">
|
|
377
|
-
{@html colOutputRange(e, 'timeRange')}
|
|
378
|
-
</th>
|
|
379
|
-
</tr>
|
|
380
|
-
</thead>
|
|
381
|
-
<tbody>
|
|
382
|
-
{#each columns as h}
|
|
383
|
-
{#if h !== 'timeRange'}
|
|
384
|
-
<tr>
|
|
385
|
-
<th scope="row">
|
|
386
|
-
{@html translateFunc ? translateFunc(h) : ''}:
|
|
387
|
-
</th>
|
|
388
|
-
<td>
|
|
389
|
-
{@html colOutputRange(e, h)}
|
|
390
|
-
</td></tr
|
|
391
|
-
>
|
|
392
|
-
{/if}
|
|
393
|
-
{/each}
|
|
394
|
-
</tbody>
|
|
395
|
-
{/each}
|
|
396
|
-
</table>
|
|
397
|
-
{:else}
|
|
398
|
-
<table class="pricing-table">
|
|
399
|
-
{#each filteredRanges as e}
|
|
400
|
-
<thead>
|
|
401
|
-
<tr>
|
|
402
|
-
<th scope="col" class="main-header">
|
|
403
|
-
{@html colOutputRange(e, 'timeRange')}
|
|
404
|
-
</th>
|
|
405
|
-
</tr>
|
|
406
|
-
</thead>
|
|
407
|
-
<tbody>
|
|
408
|
-
{#each columns as h}
|
|
409
|
-
{#if h !== 'timeRange'}
|
|
410
|
-
<tr>
|
|
411
|
-
<th scope="row">
|
|
412
|
-
{@html translateFunc ? translateFunc(h) : h}:
|
|
413
|
-
</th>
|
|
414
|
-
</tr>
|
|
415
|
-
<tr>
|
|
416
|
-
<td>
|
|
417
|
-
{@html colOutputRange(e, h)}
|
|
418
|
-
</td>
|
|
419
|
-
</tr>
|
|
420
|
-
{/if}
|
|
421
|
-
{/each}
|
|
422
|
-
</tbody>
|
|
423
|
-
{/each}
|
|
424
|
-
</table>
|
|
425
|
-
{/if}
|
|
338
|
+
{@render pricingTable(filteredRanges)}
|
|
426
339
|
{/if}
|
|
427
340
|
|
|
428
341
|
{#if footnote}
|
|
@@ -25,7 +25,7 @@ export declare class SiteState implements I18nFacade {
|
|
|
25
25
|
constructor(getSiteConfig: () => SiteConfig, lang: string | undefined);
|
|
26
26
|
updateCurrentLang: (lang: string) => string;
|
|
27
27
|
translateFunc: (ref: string) => string;
|
|
28
|
-
formatFunc: (ref: string, props: Record<string,
|
|
28
|
+
formatFunc: (ref: string, props: Record<string, unknown>) => string;
|
|
29
29
|
formatDateFunc: (d: DateTime | string) => string;
|
|
30
30
|
translateWithLangFunc: (ref: string, lang: string) => string;
|
|
31
31
|
}
|
package/dist/SiteState.svelte.js
CHANGED
|
@@ -12,7 +12,6 @@ export class SiteState {
|
|
|
12
12
|
return s;
|
|
13
13
|
}, {});
|
|
14
14
|
}
|
|
15
|
-
;
|
|
16
15
|
get cookieTranslations() {
|
|
17
16
|
return Object.entries(this.fullTranslations).reduce((s, e) => {
|
|
18
17
|
s[e[0]] = e[1].cookies;
|
|
@@ -39,10 +38,10 @@ export class SiteState {
|
|
|
39
38
|
return this.siteTranslations;
|
|
40
39
|
}
|
|
41
40
|
get calendarTranslation() {
|
|
42
|
-
return this.calendarTranslations[this.currentLang];
|
|
41
|
+
return this.calendarTranslations[this.currentLang] ?? {};
|
|
43
42
|
}
|
|
44
43
|
get cookieTranslation() {
|
|
45
|
-
return this.cookieTranslations[this.currentLang];
|
|
44
|
+
return this.cookieTranslations[this.currentLang] ?? {};
|
|
46
45
|
}
|
|
47
46
|
get formats() {
|
|
48
47
|
return this._getSiteConfigFn().lang.formats;
|
|
@@ -63,12 +62,20 @@ export class SiteState {
|
|
|
63
62
|
if (!ref)
|
|
64
63
|
return '[UNDEF]';
|
|
65
64
|
const current = this.translations[this.currentLang];
|
|
66
|
-
if (!current
|
|
65
|
+
if (!current)
|
|
67
66
|
return '';
|
|
68
|
-
|
|
67
|
+
const value = current[ref];
|
|
68
|
+
if (!value)
|
|
69
|
+
return '';
|
|
70
|
+
return value;
|
|
69
71
|
};
|
|
70
72
|
formatFunc = (ref, props) => {
|
|
71
|
-
const
|
|
73
|
+
const langFormats = this.formats[this.currentLang];
|
|
74
|
+
if (!langFormats) {
|
|
75
|
+
console.warn(`[Missing format language: ${this.currentLang}]`);
|
|
76
|
+
return '[UNDEF]';
|
|
77
|
+
}
|
|
78
|
+
const fString = langFormats[ref];
|
|
72
79
|
if (!fString) {
|
|
73
80
|
console.warn(`[Missing formatFunc: ${ref}]`);
|
|
74
81
|
return '[UNDEF]';
|
|
@@ -78,10 +85,13 @@ export class SiteState {
|
|
|
78
85
|
};
|
|
79
86
|
formatDateFunc = (d) => {
|
|
80
87
|
if (!d)
|
|
81
|
-
return this.translateFunc(
|
|
88
|
+
return this.translateFunc('invalid');
|
|
82
89
|
const formatSpecs = this.formats[this.currentLang];
|
|
90
|
+
if (!formatSpecs) {
|
|
91
|
+
return this.translateFunc('invalid');
|
|
92
|
+
}
|
|
83
93
|
let f = 'yyyy-MM-dd';
|
|
84
|
-
if (formatSpecs
|
|
94
|
+
if (formatSpecs.dateFormat) {
|
|
85
95
|
f = formatSpecs.dateFormat;
|
|
86
96
|
}
|
|
87
97
|
let date;
|
|
@@ -89,17 +99,15 @@ export class SiteState {
|
|
|
89
99
|
date = DateTime.fromISO(d);
|
|
90
100
|
else
|
|
91
101
|
date = d;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (date.isValid)
|
|
95
|
-
return this.translateFunc("invalid");
|
|
102
|
+
if (!date.isValid)
|
|
103
|
+
return this.translateFunc('invalid');
|
|
96
104
|
return date.setLocale(formatSpecs.locale).toFormat(f);
|
|
97
105
|
};
|
|
98
106
|
translateWithLangFunc = (ref, lang) => {
|
|
99
107
|
const translation = this.translations[lang];
|
|
100
108
|
if (!translation) {
|
|
101
109
|
console.error(`[Tried to access unknown translation: ${lang}]`);
|
|
102
|
-
return
|
|
110
|
+
return '[UNDEF]';
|
|
103
111
|
}
|
|
104
112
|
const res = translation[ref];
|
|
105
113
|
if (res === undefined) {
|