Skip to content
New issue

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

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

Already on GitHub? Sign in 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>

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

No branches or pull requests

1 participant