accomadesc 0.3.35 → 0.3.36

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.
@@ -1,6 +1,5 @@
1
1
  <script lang="ts">
2
2
  import type { BookingRequestContent, I18nFacade } from './types.js';
3
- import { getContext } from 'svelte';
4
3
  import Button from './basic/Button.svelte';
5
4
  import Notes from './basic/Notes.svelte';
6
5
  import Spinner from './basic/Spinner.svelte';
@@ -55,7 +54,7 @@
55
54
  let sending = $state(false);
56
55
  let disabled = $derived(preview || errored || successfullySent);
57
56
 
58
- let occupationState: OccupationState = getOccupationState(calUrl);
57
+ let occupationState: OccupationState = $derived(getOccupationState(calUrl));
59
58
  let invalid = $derived(
60
59
  occupationState && arrival && leave ? !occupationState.validRequest(arrival, leave) : false,
61
60
  );
@@ -19,14 +19,13 @@
19
19
  close: () => void;
20
20
  } & I18nFacade = $props();
21
21
 
22
- let allTranslations = $state(supportedLangs);
23
22
  const pathForLang = (lang: string) => {
24
23
  const pathElements = currentPath.split('/');
25
24
  //initial slash results in empty string real first element
26
25
  if (pathElements.length == 1) return `/${lang}`;
27
26
 
28
27
  const firstElement = pathElements[1];
29
- if (allTranslations?.includes(firstElement)) {
28
+ if (supportedLangs?.includes(firstElement)) {
30
29
  return ['', lang, ...pathElements.slice(2)].join('/');
31
30
  } else {
32
31
  return ['', lang, ...pathElements.slice(1)].join('/');
@@ -46,11 +45,11 @@
46
45
  </li>
47
46
  {/each}
48
47
  </ul>
49
- {#if allTranslations && allTranslations.length > 1}
48
+ {#if supportedLangs && supportedLangs.length > 1}
50
49
  <fieldset>
51
50
  <legend>{translateFunc ? translateFunc('lang') : ''}</legend>
52
51
 
53
- {#each allTranslations as langKey}
52
+ {#each supportedLangs as langKey}
54
53
  <a
55
54
  data-sveltekit-keepfocus
56
55
  data-sveltekit-noscroll
@@ -17,7 +17,7 @@
17
17
  import Button from './basic/Button.svelte';
18
18
  import { fallbackCSS } from './style.js';
19
19
  import { GLOBAL_STATE, GlobalState } from './state.svelte';
20
- import { setContext } from 'svelte';
20
+ import { setContext, untrack } from 'svelte';
21
21
 
22
22
  let {
23
23
  hero,
@@ -44,12 +44,11 @@
44
44
  calendarTranslation,
45
45
  }: PageProps & I18nFacade = $props();
46
46
 
47
- setContext(GLOBAL_STATE, new GlobalState(disableLinks));
48
-
49
- let pageTitle = hero && hero.title ? hero.title : header ? header : title;
47
+ // initialize global state, use the initial value of disableLinks
48
+ setContext(GLOBAL_STATE, new GlobalState(untrack(() => disableLinks)));
50
49
 
50
+ let pageTitle = $derived(hero && hero.title ? hero.title : header ? header : title);
51
51
  let langSelectorOpen = $state(false);
52
- let allTranslations = $state(supportedLangs);
53
52
 
54
53
  let currentPath = $derived(page.url.pathname);
55
54
  const pathForLang = (lang: string) => {
@@ -58,7 +57,7 @@
58
57
  if (pathElements.length == 1) return `/${lang}`;
59
58
 
60
59
  const firstElement = pathElements[1];
61
- if (allTranslations?.includes(firstElement)) {
60
+ if (supportedLangs?.includes(firstElement)) {
62
61
  return ['', lang, ...pathElements.slice(2)].join('/');
63
62
  } else {
64
63
  return ['', lang, ...pathElements.slice(1)].join('/');
@@ -192,11 +191,11 @@
192
191
  {/if}
193
192
  {/if}
194
193
 
195
- {#if langSelectorOpen && allTranslations && allTranslations.length > 1}
194
+ {#if langSelectorOpen && supportedLangs && supportedLangs.length > 1}
196
195
  <fieldset class="lang-selector" transition:fade>
197
196
  <legend>{translateFunc ? translateFunc('lang') : ''}</legend>
198
197
 
199
- {#each allTranslations as langKey}
198
+ {#each supportedLangs as langKey}
200
199
  <a
201
200
  class={{
202
201
  'lang-link': true,
@@ -4,7 +4,7 @@
4
4
 
5
5
  let { nav, ref, translateFunc, currentLang }: { nav: Nav; ref?: string } & I18nFacade = $props();
6
6
 
7
- const contentRef = ref ?? 'footer_html';
7
+ const contentRef = $derived(ref ?? 'footer_html');
8
8
  </script>
9
9
 
10
10
  <footer>
@@ -24,9 +24,9 @@
24
24
  currentLang,
25
25
  }: PricingContent & I18nFacade = $props();
26
26
 
27
- if (!ranges || (ranges.length == 0 && entries)) {
28
- ranges = entries;
29
- }
27
+ $effect(() => {
28
+ if (!ranges || (ranges.length == 0 && entries)) ranges = entries;
29
+ });
30
30
 
31
31
  const colHeaderStyle: Record<PricingColumn, string> = {
32
32
  timeRange: 'width: 20%;',
@@ -14,7 +14,10 @@
14
14
  formatFunc,
15
15
  }: PricingShortContent & I18nFacade = $props();
16
16
 
17
- if (!ranges && entries) ranges = entries;
17
+ $effect(() => {
18
+ //unclear if this is even needed and working as expected
19
+ if (!ranges && entries) ranges = entries;
20
+ });
18
21
 
19
22
  let filteredEntries = $derived.by(() => {
20
23
  let now = DateTime.now();
@@ -53,7 +53,7 @@
53
53
 
54
54
  let translatedHeader = $derived(header && translateFunc ? translateFunc(header) : '');
55
55
 
56
- let gridTemplateColumns = $state(`repeat(${columnCount}, 1fr)`);
56
+ let gridTemplateColumns = $state(`repeat(2, 1fr)`);
57
57
 
58
58
  let originalPadding = $state(padding);
59
59
 
@@ -0,0 +1,31 @@
1
+ import { type I18nFacade, type OccuplanTranslations } from 'accomadesc';
2
+ import type { CookieSelection, Translation as CookieTranslation } from 'gdpr-cooco-banner';
3
+ import { DateTime } from 'luxon';
4
+ import type { SiteConfig } from './types.ts';
5
+ interface FullTranslation {
6
+ calendar: OccuplanTranslations;
7
+ cookies: CookieTranslation;
8
+ site: Record<string, string>;
9
+ }
10
+ export declare class SiteState implements I18nFacade {
11
+ fullTranslations: Record<string, FullTranslation>;
12
+ calendarTranslations: Record<string, OccuplanTranslations>;
13
+ cookieTranslations: Record<string, CookieTranslation>;
14
+ siteTranslations: Record<string, Record<string, string>>;
15
+ supportedLangs: string[];
16
+ isMenuOpen: boolean;
17
+ cookieSelection: CookieSelection;
18
+ currentLang: string;
19
+ translations: Record<string, Record<string, string>>;
20
+ calendarTranslation: OccuplanTranslations;
21
+ cookieTranslation: CookieTranslation;
22
+ formats: Record<string, Record<string, any>>;
23
+ selectedTheme: 'light' | 'dark';
24
+ selectedThemeInitialized: boolean;
25
+ constructor(siteConfig: SiteConfig, lang: string | undefined);
26
+ updateCurrentLang: (lang: string) => string;
27
+ translateFunc: (ref: string) => string;
28
+ formatFunc: (ref: string, props: Record<string, any>) => string;
29
+ formatDateFunc: (d: DateTime | string) => string;
30
+ }
31
+ export {};
@@ -0,0 +1,69 @@
1
+ import { format } from 'accomadesc';
2
+ import { DateTime } from 'luxon';
3
+ export class SiteState {
4
+ fullTranslations = {};
5
+ calendarTranslations = {};
6
+ cookieTranslations = {};
7
+ siteTranslations = {};
8
+ supportedLangs = $state(['en']);
9
+ isMenuOpen = $state(false);
10
+ cookieSelection = $state({
11
+ analytics: false,
12
+ marketing: false,
13
+ preferences: false,
14
+ necessary: true,
15
+ });
16
+ currentLang = $state('en');
17
+ translations = $state(this.siteTranslations);
18
+ calendarTranslation = $derived(this.calendarTranslations[this.currentLang]);
19
+ cookieTranslation = $state(this.cookieTranslations[this.currentLang]);
20
+ formats = $state({});
21
+ selectedTheme = $state('light');
22
+ selectedThemeInitialized = $state(false);
23
+ constructor(siteConfig, lang) {
24
+ if (!lang || !siteConfig.lang.supportedLangs.includes(lang)) {
25
+ this.currentLang = siteConfig.lang.defaultLang;
26
+ }
27
+ else {
28
+ this.currentLang = lang;
29
+ }
30
+ this.fullTranslations = siteConfig.lang.translations;
31
+ for (const lang in this.fullTranslations) {
32
+ this.calendarTranslations[lang] = this.fullTranslations[lang].calendar;
33
+ this.siteTranslations[lang] = this.fullTranslations[lang].site;
34
+ this.cookieTranslations[lang] = this.fullTranslations[lang].cookies;
35
+ }
36
+ this.supportedLangs = siteConfig.lang.supportedLangs;
37
+ this.formats = siteConfig.lang.formats;
38
+ }
39
+ updateCurrentLang = (lang) => (this.currentLang = lang);
40
+ translateFunc = (ref) => {
41
+ if (!ref)
42
+ return 'UNDEF';
43
+ const current = this.translations[this.currentLang];
44
+ if (!current[ref])
45
+ return '';
46
+ return this.translations[this.currentLang][ref];
47
+ };
48
+ formatFunc = (ref, props) => {
49
+ const fString = this.formats[this.currentLang][ref];
50
+ if (!fString) {
51
+ console.log('missing formatFunc', ref);
52
+ return '';
53
+ }
54
+ let formatted = format(fString, props);
55
+ return formatted;
56
+ };
57
+ formatDateFunc = (d) => {
58
+ let f = 'yyyy-MM-dd';
59
+ if (this.formats[this.currentLang]?.dateFormat) {
60
+ f = this.formats[this.currentLang].dateFormat;
61
+ }
62
+ let date;
63
+ if (typeof d === 'string')
64
+ date = DateTime.fromISO(d);
65
+ else
66
+ date = d;
67
+ return date.toFormat(f);
68
+ };
69
+ }
@@ -141,7 +141,7 @@
141
141
  let innerShadowWidth = $derived(activated ? size / 16 : size / 8);
142
142
  let outerShadowWidth = $derived(activated ? size / 8 : size / 4);
143
143
 
144
- const borderRadius = $state(size / 1.8);
144
+ const borderRadius = $derived(size / 1.8);
145
145
 
146
146
  let buttonWidth = $derived.by(() => {
147
147
  if (iconName && !text) {
@@ -23,8 +23,7 @@
23
23
  children: Snippet<[AvailableSpans]>;
24
24
  } = $props();
25
25
 
26
- let occupationState: OccupationState = getOccupationState(url, debug);
27
-
26
+ let occupationState: OccupationState = $derived(getOccupationState(url, debug));
28
27
  let av = $derived(occupationState ? occupationState.calcAvailability(search, maxFutureDate) : {});
29
28
 
30
29
  onMount(() => {
@@ -49,7 +49,7 @@
49
49
 
50
50
  const id = randomID();
51
51
 
52
- let occupationState: OccupationState = getOccupationState(url, debug);
52
+ let occupationState: OccupationState = $derived(getOccupationState(url, debug));
53
53
 
54
54
  //let formatFun = $derived(Sqrl.compile(monthHeaderFormat, { useWith: true }));
55
55
  const monthHeader = (monthNum: MonthNumbers, year: number): string => {
@@ -56,7 +56,7 @@
56
56
  dateSelected?: (arrival: DateTime, leave: DateTime) => void;
57
57
  } = $props();
58
58
 
59
- let occupationState: OccupationState = getOccupationState(url, debug);
59
+ let occupationState: OccupationState = $derived(getOccupationState(url, debug));
60
60
 
61
61
  const monthHeader = (monthNum: MonthNumbers, year: number): string => {
62
62
  const monthLabel = monthLabels[monthNum];
@@ -103,8 +103,17 @@
103
103
  page -= 1;
104
104
  };
105
105
 
106
- let requestStart: DateTime | undefined = $state(arrival);
107
- let requestEnd: DateTime | undefined = $state(leave);
106
+ let requestStart: DateTime | undefined = $state();
107
+ let requestEnd: DateTime | undefined = $state();
108
+
109
+ $effect(() => {
110
+ requestStart = arrival;
111
+ });
112
+
113
+ $effect(() => {
114
+ requestEnd = leave;
115
+ });
116
+
108
117
  let earliestStart: DateTime | undefined = $derived(
109
118
  occupationState ? occupationState.earliestRequestStart(requestEnd) : undefined,
110
119
  );
@@ -47,7 +47,7 @@
47
47
 
48
48
  const id = randomID();
49
49
 
50
- let occupationState: OccupationState = getOccupationState(url, debug);
50
+ let occupationState: OccupationState = $derived(getOccupationState(url, debug));
51
51
 
52
52
  let page: number = $state(0);
53
53
  let rfMonth: number | DateTime = $derived(
@@ -411,7 +411,7 @@ export class OccupationState {
411
411
  export const getOccupationState = (url, debug = false) => {
412
412
  if (debug)
413
413
  console.log('Get OState /w url', url);
414
- const stateID = `i-${url}-${OCCUPATION_STATE}`;
414
+ const stateID = Symbol(`i-${url}-${OCCUPATION_STATE}`);
415
415
  let _instance = getContext(stateID);
416
416
  if (_instance)
417
417
  return _instance;
@@ -1,4 +1,4 @@
1
- export declare const GLOBAL_STATE = "GLOBAL_STATE";
1
+ export declare const GLOBAL_STATE: unique symbol;
2
2
  export declare class GlobalState {
3
3
  disableLinks: boolean;
4
4
  constructor(disableLinks: boolean);
@@ -1,4 +1,4 @@
1
- export const GLOBAL_STATE = 'GLOBAL_STATE';
1
+ export const GLOBAL_STATE = Symbol('GLOBAL_STATE');
2
2
  export class GlobalState {
3
3
  disableLinks = $state(false);
4
4
  constructor(disableLinks) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "accomadesc",
3
- "version": "0.3.35",
3
+ "version": "0.3.36",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.test.*",
@@ -26,16 +26,16 @@
26
26
  "devDependencies": {
27
27
  "@sveltejs/adapter-auto": "^3.3.1",
28
28
  "@sveltejs/adapter-static": "^3.0.10",
29
- "@sveltejs/kit": "^2.49.0",
30
- "@sveltejs/package": "^2.5.6",
29
+ "@sveltejs/kit": "^2.49.2",
30
+ "@sveltejs/package": "^2.5.7",
31
31
  "@sveltejs/vite-plugin-svelte": "^5.1.1",
32
32
  "@types/luxon": "^3.7.1",
33
33
  "gdpr-cooco-banner": "^0.0.11",
34
- "prettier": "^3.6.2",
35
- "prettier-plugin-svelte": "^3.4.0",
36
- "publint": "^0.3.15",
37
- "svelte": "^5.43.14",
38
- "svelte-check": "^4.3.4",
34
+ "prettier": "^3.7.4",
35
+ "prettier-plugin-svelte": "^3.4.1",
36
+ "publint": "^0.3.16",
37
+ "svelte": "^5.46.1",
38
+ "svelte-check": "^4.3.5",
39
39
  "typescript": "^5.9.3",
40
40
  "vite": "^6.4.1"
41
41
  },