Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

How do I load multiple locales and update the <Time> using $locale? #31

Open
elron opened this issue Jul 15, 2023 · 1 comment
Open

Comments

@elron
Copy link

elron commented Jul 15, 2023

Hey

In my i18n supported website I have a store called $locale
and it changes the value from "en" (English) to "he" (Hebrew) and more.

I want that whenever a $locale change is made, all <Time> instances would be updated.

How do I achieve that?

Thanks

@elron
Copy link
Author

elron commented Jul 15, 2023

For now I found a custom solution, thanks for making this library!

I installed pnpm i dayjs -D
and added two files:
LocaleTime.svelte

<script lang="ts">
  import { locale } from '$lib/i18n/i18n';
  import Time from './Time.svelte';

  import 'dayjs/locale/he';

  export let timestamp: any;
  export let relative: boolean = true;
</script>

{#key $locale}
  <Time {...$$props} {timestamp} {relative} locale={$locale} />
{/key}

and Time.svelte (based on your code):

<script>
  /**
   * Thanks:
   * https://github.com/metonym/svelte-time 
  */
  import dayjs from 'dayjs';
  import { onMount } from 'svelte';
  import relativeTime from 'dayjs/plugin/relativeTime.js';

  dayjs.extend(relativeTime);

  export let locale;
  dayjs.locale(locale);

  /**
   * Original timestamp
   * @type {import("dayjs").ConfigType}
   */
  export let timestamp = new Date().toISOString();

  /**
   * Timestamp format for display.
   * It's also used as a title in the `relative` mode
   * @type {import("dayjs").OptionType}
   * @example "YYYY-MM-DD"
   */
  export let format = 'MMM DD, YYYY';

  /**
   * Set to `true` to display the relative time from the provided `timestamp`.
   * The value is displayed in a human-readable, relative format (e.g., "4 days ago", "Last week")
   * @type {boolean}
   */
  export let relative = false;

  /**
   * Set to `true` to update the relative time at 60 second interval.
   * Pass in a number (ms) to specify the interval length
   * @type {boolean | number}
   */
  export let live = false;

  /**
   * Formatted timestamp.
   * Result of invoking `dayjs().format()`
   * @type {string}
   */
  export let formatted = '';

  /** @type {undefined | NodeJS.Timer} */
  let interval = undefined;

  const DEFAULT_INTERVAL = 60 * 1_000;

  onMount(() => {
    if (relative && live !== false) {
      interval = setInterval(() => {
        formatted = dayjs(timestamp).from();
      }, Math.abs(typeof live === 'number' ? live : DEFAULT_INTERVAL));
    }

    return () => {
      if (typeof interval === 'number') {
        clearInterval(interval);
      }
    };
  });

  $: formatted = relative ? dayjs(timestamp).from() : dayjs(timestamp).format(format);
  $: title = relative ? dayjs(timestamp).format(format) : undefined;
</script>

<time {...$$restProps} {title} datetime={timestamp}>
  {formatted}
</time>

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant