Modo oscuro

DayFlow Calendar incluye soporte completo para el modo oscuro desde el primer momento. El calendario adapta su aspecto automáticamente a tu preferencia de tema, incluidos todos los componentes de la interfaz, los colores de los eventos y los elementos interactivos.

Características

  • Tres modos de tema: claro, oscuro y automático (preferencia del sistema)
  • Ajuste automático de color: colores de evento optimizados para fondos claros y oscuros
  • Cambio fluido: el tema cambia al instante, sin parpadeos
  • Sincronización con el sistema: el modo automático sigue la preferencia de tema del sistema operativo
  • Colores propios: define colores distintos para el modo claro y el oscuro

Inicio rápido

Configuración básica

Activa el modo oscuro definiendo la configuración theme:

import { useCalendarApp, DayFlowCalendar } from '@dayflow/react';

function MyCalendar() {
  const calendar = useCalendarApp({
    theme: {
      mode: 'dark', // 'light' | 'dark' | 'auto'
    },
  });

  return <DayFlowCalendar calendar={calendar} />;
}
<template>
  <DayFlowCalendar :calendar="calendar" />
</template>

<script setup>
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';

const calendar = useCalendarApp({
  theme: {
    mode: 'dark', // 'light' | 'dark' | 'auto'
  },
});
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `<dayflow-calendar [calendar]="calendar"></dayflow-calendar>`
})
export class AppComponent {
  calendar = {
    theme: {
      mode: 'dark', // 'light' | 'dark' | 'auto'
    },
  };
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';

  const calendar = useCalendarApp({
    theme: {
      mode: 'dark', // 'light' | 'dark' | 'auto'
    },
  });
</script>

<DayFlowCalendar {calendar} />

Modos de tema

Modo claro

Tema predeterminado, con fondos claros y texto oscuro.

const calendar = useCalendarApp({
  theme: {
    mode: 'light',
  },
});
const calendar = useCalendarApp({
  theme: {
    mode: 'light',
  },
});
calendar = {
  theme: {
    mode: 'light',
  },
};
const calendar = useCalendarApp({
  theme: {
    mode: 'light',
  },
});

Modo oscuro

Tema oscuro, con fondos oscuros y texto claro.

const calendar = useCalendarApp({
  theme: {
    mode: 'dark',
  },
});
const calendar = useCalendarApp({
  theme: {
    mode: 'dark',
  },
});
calendar = {
  theme: {
    mode: 'dark',
  },
};
const calendar = useCalendarApp({
  theme: {
    mode: 'dark',
  },
});

Modo automático

Sigue automáticamente la preferencia de tema del sistema y se actualiza cuando esta cambia.

const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
});
const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
});
calendar = {
  theme: {
    mode: 'auto',
  },
};
const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
});

Cambiar de tema

Cambios de tema por código

Usa la API del calendario para cambiar de tema dinámicamente:

import { useCalendarApp } from '@dayflow/react';

function ThemeToggle() {
  const calendar = useCalendarApp({
    theme: { mode: 'light' },
  });

  const toggleTheme = () => {
    const currentTheme = calendar.app.getTheme();
    const nextTheme = currentTheme === 'light' ? 'dark' : 'light';
    calendar.app.setTheme(nextTheme);
  };

  return <button onClick={toggleTheme}>Toggle Theme</button>;
}
<template>
  <button @click="toggleTheme()">Toggle Theme</button>
</template>

<script setup>
import { useCalendarApp } from '@dayflow/vue';

const calendar = useCalendarApp({
  theme: { mode: 'light' },
});

const toggleTheme = () => {
  const currentTheme = calendar.app.getTheme();
  const nextTheme = currentTheme === 'light' ? 'dark' : 'light';
  calendar.app.setTheme(nextTheme);
};
</script>
import { Component } from '@angular/core';

@Component({
  selector: 'app-theme-toggle',
  standalone: true,
  template: `<button (click)="toggleTheme()">Toggle Theme</button>`
})
export class ThemeToggleComponent {
  calendar = {
    theme: { mode: 'light' },
  };

  toggleTheme() {
    const currentTheme = this.calendar.app.getTheme();
    const nextTheme = currentTheme === 'light' ? 'dark' : 'light';
    this.calendar.app.setTheme(nextTheme);
  }
}
<script>
  import { useCalendarApp } from '@dayflow/svelte';

  const calendar = useCalendarApp({
    theme: { mode: 'light' },
  });

  function toggleTheme() {
    const currentTheme = calendar.app.getTheme();
    const nextTheme = currentTheme === 'light' ? 'dark' : 'light';
    calendar.app.setTheme(nextTheme);
  }
</script>

<button onclick={toggleTheme}>Toggle Theme</button>

Suscribirse a los cambios de tema

Escucha los cambios de tema para actualizar tu interfaz:

import { useEffect, useState } from 'react';
import type { ThemeMode } from '@dayflow/core';

function MyComponent({ calendar }) {
  const [theme, setTheme] = useState<ThemeMode>('light');

  useEffect(() => {
    const handleThemeChange = (newTheme: ThemeMode) => {
      setTheme(newTheme);
    };

    // Subscribe to theme changes
    calendar.app.subscribeThemeChange(handleThemeChange);

    // Cleanup
    return () => {
      calendar.app.unsubscribeThemeChange(handleThemeChange);
    };
  }, [calendar.app]);

  return <div>Current theme: {theme}</div>;
}
<template>
  <div>Current theme: {{ theme }}</div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

const props = defineProps({
  calendar: Object,
});

const theme = ref('light');

const handleThemeChange = (newTheme) => {
  theme.value = newTheme;
};

onMounted(() => {
  props.calendar.app.subscribeThemeChange(handleThemeChange);
});

onUnmounted(() => {
  props.calendar.app.unsubscribeThemeChange(handleThemeChange);
});
</script>
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import type { ThemeMode } from '@dayflow/core';

@Component({
  selector: 'app-my-component',
  standalone: true,
  template: `<div>Current theme: {{ theme }}</div>`
})
export class MyComponent implements OnInit, OnDestroy {
  @Input() calendar!: any;
  theme: ThemeMode = 'light';

  handleThemeChange = (newTheme: ThemeMode) => {
    this.theme = newTheme;
  };

  ngOnInit() {
    this.calendar.app.subscribeThemeChange(this.handleThemeChange);
  }

  ngOnDestroy() {
    this.calendar.app.unsubscribeThemeChange(this.handleThemeChange);
  }
}
<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import type { ThemeMode } from '@dayflow/core';

  let { calendar } = $props<{ calendar: any }>();
  let theme = $state<ThemeMode>('light');

  const handleThemeChange = (newTheme: ThemeMode) => {
    theme = newTheme;
  };

  onMount(() => {
    calendar.app.subscribeThemeChange(handleThemeChange);
  });

  onDestroy(() => {
    calendar.app.unsubscribeThemeChange(handleThemeChange);
  });
</script>

<div>Current theme: {theme}</div>

Colores de tema propios

Define colores distintos para el modo claro y el oscuro en cada tipo de calendario:

const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
  calendars: [
    {
      id: 'work',
      name: 'Work',
      colors: {
        // Light mode colors
        lineColor: '#0066cc',
        eventColor: '#e6f2ff',
        eventSelectedColor: '#cce4ff',
        textColor: '#003d7a',
      },
      darkColors: {
        // Dark mode colors
        lineColor: '#4da6ff',
        eventColor: '#1a3d5c',
        eventSelectedColor: '#2a5a8a',
        textColor: '#b3d9ff',
      },
    },
  ],
});
const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
  calendars: [
    {
      id: 'work',
      name: 'Work',
      colors: {
        // Light mode colors
        lineColor: '#0066cc',
        eventColor: '#e6f2ff',
        eventSelectedColor: '#cce4ff',
        textColor: '#003d7a',
      },
      darkColors: {
        // Dark mode colors
        lineColor: '#4da6ff',
        eventColor: '#1a3d5c',
        eventSelectedColor: '#2a5a8a',
        textColor: '#b3d9ff',
      },
    },
  ],
});
calendar = {
  theme: {
    mode: 'auto',
  },
  calendars: [
    {
      id: 'work',
      name: 'Work',
      colors: {
        // Light mode colors
        lineColor: '#0066cc',
        eventColor: '#e6f2ff',
        eventSelectedColor: '#cce4ff',
        textColor: '#003d7a',
      },
      darkColors: {
        // Dark mode colors
        lineColor: '#4da6ff',
        eventColor: '#1a3d5c',
        eventSelectedColor: '#2a5a8a',
        textColor: '#b3d9ff',
      },
    },
  ],
};
const calendar = useCalendarApp({
  theme: {
    mode: 'auto',
  },
  calendars: [
    {
      id: 'work',
      name: 'Work',
      colors: {
        // Light mode colors
        lineColor: '#0066cc',
        eventColor: '#e6f2ff',
        eventSelectedColor: '#cce4ff',
        textColor: '#003d7a',
      },
      darkColors: {
        // Dark mode colors
        lineColor: '#4da6ff',
        eventColor: '#1a3d5c',
        eventSelectedColor: '#2a5a8a',
        textColor: '#b3d9ff',
      },
    },
  ],
});

Recomendaciones de color

Para una legibilidad y accesibilidad óptimas:

Modo claro:

  • Colores de línea: colores vivos y saturados (#0066cc, #16a34a)
  • Colores de evento: tintes suaves (#e6f2ff, #dcfce7)
  • Colores de texto: tonos oscuros para contrastar (#003d7a, #14532d)

Modo oscuro:

  • Colores de línea: variantes más claras y luminosas (#4da6ff, #4ade80)
  • Colores de evento: fondos oscuros y desaturados (#1a3d5c, #1e4d2b)
  • Colores de texto: tonos claros para poder leer bien (#b3d9ff, #bbf7d0)

Colores predeterminados de los tipos de calendario

DayFlow incluye 10 tipos de calendario predeterminados con colores de modo oscuro ya configurados:

Blue
#3b82f6
Light
#60a5fa
Dark
Green
#22c55e
Light
#4ade80
Dark
Purple
#a855f7
Light
#c084fc
Dark
Yellow
#eab308
Light
#facc15
Dark
Red
#ef4444
Light
#f87171
Dark
Orange
#f97316
Light
#fb923c
Dark
Pink
#ec4899
Light
#f472b6
Dark
Teal
#14b8a6
Light
#2dd4bf
Dark
Indigo
#6366f1
Light
#818cf8
Dark
Gray
#6b7280
Light
#9ca3af
Dark
Tip: All colors meet WCAG AA contrast requirements for both light and dark backgrounds, ensuring good readability.

Referencia de la API

Configuración del tema

interface ThemeConfig {
  mode: 'light' | 'dark' | 'auto';
}

Métodos de la app del calendario

// Get current theme mode
app.getTheme(): ThemeMode

// Set theme mode
app.setTheme(mode: ThemeMode): void

// Subscribe to theme changes
app.subscribeThemeChange(callback: (theme: ThemeMode) => void): void

// Unsubscribe from theme changes
app.unsubscribeThemeChange(callback: (theme: ThemeMode) => void): void

Colores de los tipos de calendario

interface CalendarTypeColors {
  lineColor: string; // Border and accent color
  eventColor: string; // Event background color
  eventSelectedColor: string; // Selected event background color
  textColor: string; // Text color
}

interface CalendarType {
  id: string;
  name: string;
  colors: CalendarTypeColors; // Light mode colors
  darkColors?: CalendarTypeColors; // Dark mode colors (optional)
}

Ejemplos

Conmutador de tema sencillo

import { DayFlowCalendar, useCalendarApp } from '@dayflow/react';
import { useState } from 'react';
import { Sun, Moon } from 'lucide-react';

function SimpleThemeToggle() {
  const calendar = useCalendarApp({
    theme: { mode: 'light' },
  });

  const [isDark, setIsDark] = useState(false);

  const toggleTheme = () => {
    const nextTheme = isDark ? 'light' : 'dark';
    calendar.app.setTheme(nextTheme);
    setIsDark(!isDark);
  };

  return (
    <div>
      <button onClick={toggleTheme}>{isDark ? <Sun /> : <Moon />}</button>
      <DayFlowCalendar calendar={calendar} />
    </div>
  );
}
<template>
  <div>
    <button @click="toggleTheme()">
      <Sun v-if="isDark" />
      <Moon v-else />
    </button>
    <DayFlowCalendar :calendar="calendar" />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { DayFlowCalendar, useCalendarApp } from '@dayflow/vue';
import { Sun, Moon } from 'lucide-vue-next';

const calendar = useCalendarApp({
  theme: { mode: 'light' },
});

const isDark = ref(false);

const toggleTheme = () => {
  const nextTheme = isDark.value ? 'light' : 'dark';
  calendar.app.setTheme(nextTheme);
  isDark.value = !isDark.value;
};
</script>
import { Component } from '@angular/core';
import { DayFlowCalendarModule } from '@dayflow/angular';

@Component({
  selector: 'app-theme-toggle',
  standalone: true,
  imports: [DayFlowCalendarModule],
  template: `
    <div>
      <button (click)="toggleTheme()">
        {{ isDark ? 'Sun' : 'Moon' }}
      </button>
      <dayflow-calendar [calendar]="calendar"></dayflow-calendar>
    </div>
  `
})
export class SimpleThemeToggleComponent {
  calendar = {
    theme: { mode: 'light' },
  };
  isDark = false;

  toggleTheme() {
    this.isDark = !this.isDark;
    const nextTheme = this.isDark ? 'dark' : 'light';
    this.calendar.app.setTheme(nextTheme);
  }
}
<script>
  import { DayFlowCalendar, useCalendarApp } from '@dayflow/svelte';
  import { Sun, Moon } from 'lucide-svelte';

  const calendar = useCalendarApp({
    theme: { mode: 'light' },
  });

  let isDark = $state(false);

  function toggleTheme() {
    isDark = !isDark;
    const nextTheme = isDark ? 'dark' : 'light';
    calendar.app.setTheme(nextTheme);
  }
</script>

<div>
  <button onclick={toggleTheme}>
    {#if isDark}
      <Sun />
    {:else}
      <Moon />
    {/if}
  </button>
  <DayFlowCalendar {calendar} />
</div>

Documentación relacionada