+
- {children}
+
+ {children}
+
+
+
);
}
diff --git a/src/apps/sorting-visualizer/models/interfaces.ts b/src/apps/sorting-visualizer/models/interfaces.ts
index 1404897..8611a28 100644
--- a/src/apps/sorting-visualizer/models/interfaces.ts
+++ b/src/apps/sorting-visualizer/models/interfaces.ts
@@ -19,10 +19,10 @@ export interface MovingCellProps {
export interface UIProps {
array: number[];
- swapPositions: number[];
- sortPositions: number[];
- highlightPositions: number[];
- movePositions?: number[];
+ swaps: number[];
+ sorts: number[];
+ highlights: number[];
+ moves?: number[];
pivot?: number;
}
diff --git a/src/apps/sorting-visualizer/styles/_cell-colors.scss b/src/apps/sorting-visualizer/styles/_cell-colors.scss
new file mode 100644
index 0000000..a6fe30b
--- /dev/null
+++ b/src/apps/sorting-visualizer/styles/_cell-colors.scss
@@ -0,0 +1,13 @@
+@mixin sort-status-colors {
+ .pivot {
+ background-color: var(--color-pivot);
+ }
+
+ .sort {
+ background-color: var(--color-sort);
+ }
+
+ .highlight {
+ background-color: var(--color-highlight);
+ }
+}
diff --git a/src/index.scss b/src/index.scss
index a5a75f8..e81ac5a 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -1,11 +1,34 @@
-/* stylelint-disable */
-@use "./styles/tooltip.scss";
-@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap");
-
+/* stylelint-disable scss/at-rule-no-unknown */
+@use "./styles/tooltip";
+@use "./styles/themes/light";
+@use "./styles/themes/dark";
+@use "./styles/theme";
+@import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";
@tailwind base;
@tailwind components;
@tailwind utilities;
+:root {
+ @include light.light-theme;
+}
+
+@media screen and (prefers-color-scheme: dark) {
+ :root {
+ @include dark.dark-theme;
+ }
+}
+
+html[data-theme="light"] {
+ @include light.light-theme;
+}
+
+html[data-theme="dark"] {
+ @include dark.dark-theme;
+}
+
body {
- font-family: "Inter", sans-serif;
+ font-family: Inter, sans-serif;
+ color: theme.$base;
+ background-color: theme.$background;
+ transition: all 0.25s;
}
diff --git a/src/store/app.slice.ts b/src/store/app.slice.ts
new file mode 100644
index 0000000..8ee7453
--- /dev/null
+++ b/src/store/app.slice.ts
@@ -0,0 +1,22 @@
+import { AppState, Theme } from "@/types/interfaces";
+
+import type { PayloadAction } from "@reduxjs/toolkit";
+import { createSlice } from "@reduxjs/toolkit";
+
+const initialState: AppState = {
+ theme: null,
+};
+
+export const appSlice = createSlice({
+ name: "app",
+ initialState,
+ reducers: {
+ setTheme: (state, action: PayloadAction
) => {
+ state.theme = action.payload;
+ document.documentElement.setAttribute("data-theme", action.payload);
+ },
+ },
+});
+
+export const { setTheme } = appSlice.actions;
+export default appSlice.reducer;
diff --git a/src/store/store.ts b/src/store/store.ts
index f043222..294065a 100644
--- a/src/store/store.ts
+++ b/src/store/store.ts
@@ -9,19 +9,25 @@ import {
persistStore,
} from "redux-persist";
+import appReducer from "./app.slice";
import { configureStore } from "@reduxjs/toolkit";
import sortingVisualizerReducer from "@/apps/sorting-visualizer/store/sorting-visualizer.slice";
import storage from "redux-persist/lib/storage";
-const persistConfig = {
- key: "sorting-viz",
- storage,
-};
-
export const store = configureStore({
reducer: {
+ app: persistReducer>(
+ {
+ key: "app",
+ storage,
+ },
+ appReducer
+ ),
sortViz: persistReducer>(
- persistConfig,
+ {
+ key: "sorting-viz",
+ storage,
+ },
sortingVisualizerReducer
),
},
diff --git a/src/styles/_colors.scss b/src/styles/_colors.scss
new file mode 100644
index 0000000..eef5f56
--- /dev/null
+++ b/src/styles/_colors.scss
@@ -0,0 +1,7 @@
+$white: white;
+$black: black;
+$white1: rgb(256 256 256 / 15%);
+$white2: rgb(256 256 256 / 40%);
+$black1: rgb(0 0 0 / 15%);
+$black2: rgb(0 0 0 / 40%);
+$blue1: #2b4bfe;
diff --git a/src/styles/theme.scss b/src/styles/theme.scss
new file mode 100644
index 0000000..d385e75
--- /dev/null
+++ b/src/styles/theme.scss
@@ -0,0 +1,5 @@
+$base: var(--base);
+$background: var(--background);
+$primary: var(--primary);
+$shadow1: var(--shadow1);
+$shadow2: var(--shadow2);
diff --git a/src/styles/themes/_dark.scss b/src/styles/themes/_dark.scss
new file mode 100644
index 0000000..82565c5
--- /dev/null
+++ b/src/styles/themes/_dark.scss
@@ -0,0 +1,9 @@
+@use "../colors";
+
+@mixin dark-theme {
+ --base: #{colors.$white};
+ --background: #{colors.$black};
+ --primary: #{colors.$blue1};
+ --shadow1: #{colors.$white1};
+ --shadow2: #{colors.$white2};
+}
diff --git a/src/styles/themes/_light.scss b/src/styles/themes/_light.scss
new file mode 100644
index 0000000..c2f2f82
--- /dev/null
+++ b/src/styles/themes/_light.scss
@@ -0,0 +1,9 @@
+@use "../colors";
+
+@mixin light-theme {
+ --base: #{colors.$black};
+ --background: #{colors.$white};
+ --primary: #{colors.$blue1};
+ --shadow1: #{colors.$black1};
+ --shadow2: #{colors.$black2};
+}
diff --git a/src/styles/tooltip.scss b/src/styles/tooltip.scss
index 136af26..7d08122 100644
--- a/src/styles/tooltip.scss
+++ b/src/styles/tooltip.scss
@@ -1,30 +1,32 @@
-[data-tooltip] {
- position: relative;
-}
+@media screen and (width >= 960px) {
+ [data-tooltip] {
+ position: relative;
+ }
-[data-tooltip]:hover:after {
- content: attr(data-tooltip);
- position: absolute;
- background-color: #333;
- padding: 5px;
- border-radius: 4px;
- transform: translate(-50%, 100%);
- color: #fff;
- bottom: -6px;
- left: 50%;
- text-align: center;
- font-size: 0.75rem;
- transition: opacity 0.3s ease-in-out;
- z-index: 1;
-}
+ [data-tooltip]:hover::after {
+ position: absolute;
+ bottom: -6px;
+ left: 50%;
+ z-index: 1;
+ padding: 5px;
+ font-size: 0.75rem;
+ color: #fff;
+ text-align: center;
+ content: attr(data-tooltip);
+ background-color: #333;
+ border-radius: 4px;
+ transition: opacity 0.3s ease-in-out;
+ transform: translate(-50%, 100%);
+ }
-[data-tooltip]:hover:before {
- content: "";
- position: absolute;
- bottom: -6px;
- left: 50%;
- transform: translateX(-50%);
- border-width: 0 6px 10px 6px;
- border-style: solid;
- border-color: transparent transparent #333 transparent;
+ [data-tooltip]:hover::before {
+ position: absolute;
+ bottom: -6px;
+ left: 50%;
+ content: "";
+ border-color: transparent transparent #333;
+ border-style: solid;
+ border-width: 0 6px 10px;
+ transform: translateX(-50%);
+ }
}
diff --git a/src/types/interfaces.ts b/src/types/interfaces.ts
new file mode 100644
index 0000000..06da05b
--- /dev/null
+++ b/src/types/interfaces.ts
@@ -0,0 +1,8 @@
+export const enum Theme {
+ LIGHT = "light",
+ DARK = "dark",
+}
+
+export interface AppState {
+ theme: null | Theme;
+}