@willphan1712000/frontend 1.8.2 → 1.9.0

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.
package/dist/index.d.mts CHANGED
@@ -774,4 +774,24 @@ declare const LinearAlgebra: {
774
774
  getVectorMagnitude(vector: number[]): number;
775
775
  };
776
776
 
777
- export { type AuthInterface, Avatar, Button, Canvas, ColorPickerSlider, DropdownSelect, Image$1 as Image, ImageEditor, Image as ImageUtilities, InputFile, InputGoogle, LinearAlgebra, Modern as ModernButton, MultiSelect, OptionSlider, type Options$2 as Options, RangeSlider, SessionProvider, type SessionType, type Options$1 as SliderOptions, type StorageInterface, TextArea, Transform, UploadImage, tools, useAuthClient, useSession };
777
+ declare const ThemeStateArray: readonly ["light", "dark", "system"];
778
+ type ThemeState = (typeof ThemeStateArray)[number];
779
+ interface UseThemeState {
780
+ setThemeState: (mode: ThemeState) => void;
781
+ getThemeState: () => ThemeState;
782
+ }
783
+
784
+ /**
785
+ * Custom React hook for managing and modifying the theme state ('light', 'dark', or 'system') on the web.
786
+ * It interacts with the browser's `localStorage` and `document.body` to persist and apply theme choices.
787
+ *
788
+ * @returns {UseThemeState} An object containing the following theme control methods:
789
+ * - `setThemeState(mode: ThemeState)`: Sets the theme to the specified mode.
790
+ * - `'light'`: Sets the storage item to `'light'`, removes the dark theme class from the document body, and disables the OS color scheme change listener.
791
+ * - `'dark'`: Sets the storage item to `'dark'`, adds the dark theme class to the document body, and disables the OS color scheme change listener.
792
+ * - `'system'`: Sets the storage item to `'system'`, matches the document body class to the current OS color scheme preference, and registers a listener to react to future OS color scheme preference changes.
793
+ * - `getThemeState()`: Retrieves the stored theme value from `localStorage`. Defaults to `'light'` if empty or invalid.
794
+ */
795
+ declare function useThemeState(): UseThemeState;
796
+
797
+ export { type AuthInterface, Avatar, Button, Canvas, ColorPickerSlider, DropdownSelect, Image$1 as Image, ImageEditor, Image as ImageUtilities, InputFile, InputGoogle, LinearAlgebra, Modern as ModernButton, MultiSelect, OptionSlider, type Options$2 as Options, RangeSlider, SessionProvider, type SessionType, type Options$1 as SliderOptions, type StorageInterface, TextArea, Transform, UploadImage, tools, useAuthClient, useSession, useThemeState };
package/dist/index.d.ts CHANGED
@@ -774,4 +774,24 @@ declare const LinearAlgebra: {
774
774
  getVectorMagnitude(vector: number[]): number;
775
775
  };
776
776
 
777
- export { type AuthInterface, Avatar, Button, Canvas, ColorPickerSlider, DropdownSelect, Image$1 as Image, ImageEditor, Image as ImageUtilities, InputFile, InputGoogle, LinearAlgebra, Modern as ModernButton, MultiSelect, OptionSlider, type Options$2 as Options, RangeSlider, SessionProvider, type SessionType, type Options$1 as SliderOptions, type StorageInterface, TextArea, Transform, UploadImage, tools, useAuthClient, useSession };
777
+ declare const ThemeStateArray: readonly ["light", "dark", "system"];
778
+ type ThemeState = (typeof ThemeStateArray)[number];
779
+ interface UseThemeState {
780
+ setThemeState: (mode: ThemeState) => void;
781
+ getThemeState: () => ThemeState;
782
+ }
783
+
784
+ /**
785
+ * Custom React hook for managing and modifying the theme state ('light', 'dark', or 'system') on the web.
786
+ * It interacts with the browser's `localStorage` and `document.body` to persist and apply theme choices.
787
+ *
788
+ * @returns {UseThemeState} An object containing the following theme control methods:
789
+ * - `setThemeState(mode: ThemeState)`: Sets the theme to the specified mode.
790
+ * - `'light'`: Sets the storage item to `'light'`, removes the dark theme class from the document body, and disables the OS color scheme change listener.
791
+ * - `'dark'`: Sets the storage item to `'dark'`, adds the dark theme class to the document body, and disables the OS color scheme change listener.
792
+ * - `'system'`: Sets the storage item to `'system'`, matches the document body class to the current OS color scheme preference, and registers a listener to react to future OS color scheme preference changes.
793
+ * - `getThemeState()`: Retrieves the stored theme value from `localStorage`. Defaults to `'light'` if empty or invalid.
794
+ */
795
+ declare function useThemeState(): UseThemeState;
796
+
797
+ export { type AuthInterface, Avatar, Button, Canvas, ColorPickerSlider, DropdownSelect, Image$1 as Image, ImageEditor, Image as ImageUtilities, InputFile, InputGoogle, LinearAlgebra, Modern as ModernButton, MultiSelect, OptionSlider, type Options$2 as Options, RangeSlider, SessionProvider, type SessionType, type Options$1 as SliderOptions, type StorageInterface, TextArea, Transform, UploadImage, tools, useAuthClient, useSession, useThemeState };
package/dist/index.js CHANGED
@@ -90,7 +90,8 @@ __export(index_exports, {
90
90
  UploadImage: () => UploadImage_default,
91
91
  tools: () => tools_default,
92
92
  useAuthClient: () => useAuthClient_default,
93
- useSession: () => useSession
93
+ useSession: () => useSession,
94
+ useThemeState: () => useThemeState
94
95
  });
95
96
  module.exports = __toCommonJS(index_exports);
96
97
 
@@ -1703,30 +1704,35 @@ var InputGoogle = (_a) => {
1703
1704
  const [isFocus, setFocus] = (0, import_react13.useState)(false);
1704
1705
  const spanRef = (0, import_react13.useRef)(null);
1705
1706
  const inputRef = (0, import_react13.useRef)(null);
1706
- function transitionOnFocus() {
1707
- setFocus(true);
1707
+ const borderWhenFocused = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${others2.borderRelease}`;
1708
+ const labelColorWhenFocused = isFocus ? `${options ? options.focusColor : others2.textFocus}` : `${others2.textRelease}`;
1709
+ function spanPositionWhenFocused() {
1708
1710
  if (spanRef.current) {
1709
1711
  spanRef.current.style.top = others2.topFocus;
1710
1712
  spanRef.current.style.fontSize = others2.fontSizeFocus;
1711
1713
  }
1712
1714
  }
1713
- function transitionOffFocus() {
1714
- setFocus(false);
1715
- if (value) return;
1715
+ function spanPositionWhenNotFocused() {
1716
1716
  if (spanRef.current) {
1717
1717
  spanRef.current.style.top = others2.topRelease;
1718
1718
  spanRef.current.style.fontSize = others2.fontSizeRelease;
1719
1719
  }
1720
1720
  }
1721
- function handleClickOnLabel() {
1721
+ function onFocus() {
1722
+ setFocus(true);
1723
+ spanPositionWhenFocused();
1724
+ }
1725
+ function offFocus() {
1726
+ setFocus(false);
1727
+ if (value) return;
1728
+ spanPositionWhenNotFocused();
1729
+ }
1730
+ function focus() {
1722
1731
  var _a2;
1723
1732
  (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
1724
1733
  }
1725
- const inputBorder = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${others2.borderRelease}`;
1726
- const labelTextColor = isFocus ? `${options ? options.focusColor : others2.textFocus}` : `${others2.textRelease}`;
1727
1734
  (0, import_react13.useEffect)(() => {
1728
- transitionOnFocus();
1729
- transitionOffFocus();
1735
+ if (value) spanPositionWhenFocused();
1730
1736
  }, [value]);
1731
1737
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { style: InputGoogle_styles_default.container, children: [
1732
1738
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -1736,13 +1742,15 @@ var InputGoogle = (_a) => {
1736
1742
  name: "will-input-google",
1737
1743
  ref: inputRef,
1738
1744
  value,
1739
- onChange: (e) => setValue(e.target.value),
1745
+ onChange: (e) => {
1746
+ setValue(e.target.value);
1747
+ },
1740
1748
  type: "text",
1741
1749
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.input), {
1742
- border: inputBorder
1750
+ border: borderWhenFocused
1743
1751
  }),
1744
- onFocus: transitionOnFocus,
1745
- onBlur: transitionOffFocus
1752
+ onFocus,
1753
+ onBlur: offFocus
1746
1754
  }, props)
1747
1755
  ),
1748
1756
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
@@ -1750,9 +1758,9 @@ var InputGoogle = (_a) => {
1750
1758
  {
1751
1759
  ref: spanRef,
1752
1760
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.label), {
1753
- color: labelTextColor
1761
+ color: labelColorWhenFocused
1754
1762
  }),
1755
- onClick: handleClickOnLabel,
1763
+ onClick: focus,
1756
1764
  children: label
1757
1765
  }
1758
1766
  )
@@ -1824,30 +1832,35 @@ var TextArea = (_a) => {
1824
1832
  const [isFocus, setFocus] = (0, import_react14.useState)(false);
1825
1833
  const spanRef = (0, import_react14.useRef)(null);
1826
1834
  const inputRef = (0, import_react14.useRef)(null);
1827
- function transitionOnFocus() {
1828
- setFocus(true);
1835
+ const inputBorder = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${others3.borderRelease}`;
1836
+ const labelTextColor = isFocus ? `${options ? options.focusColor : others3.textFocus}` : `${others3.textRelease}`;
1837
+ function spanPositionWhenFocused() {
1829
1838
  if (spanRef.current) {
1830
1839
  spanRef.current.style.top = others3.topFocus;
1831
1840
  spanRef.current.style.fontSize = others3.fontSizeFocus;
1832
1841
  }
1833
1842
  }
1834
- function transitionOffFocus() {
1835
- setFocus(false);
1836
- if (value) return;
1843
+ function spanPositionWhenNotFocused() {
1837
1844
  if (spanRef.current) {
1838
1845
  spanRef.current.style.top = others3.topRelease;
1839
1846
  spanRef.current.style.fontSize = others3.fontSizeRelease;
1840
1847
  }
1841
1848
  }
1842
- function handleClickOnLabel() {
1849
+ function onFocus() {
1850
+ setFocus(true);
1851
+ spanPositionWhenFocused();
1852
+ }
1853
+ function offFocus() {
1854
+ setFocus(false);
1855
+ if (value) return;
1856
+ spanPositionWhenNotFocused();
1857
+ }
1858
+ function focus() {
1843
1859
  var _a2;
1844
1860
  (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
1845
1861
  }
1846
- const inputBorder = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${others3.borderRelease}`;
1847
- const labelTextColor = isFocus ? `${options ? options.focusColor : others3.textFocus}` : `${others3.textRelease}`;
1848
1862
  (0, import_react14.useEffect)(() => {
1849
- transitionOnFocus();
1850
- transitionOffFocus();
1863
+ if (value) spanPositionWhenFocused();
1851
1864
  }, [value]);
1852
1865
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { style: TextArea_styles_default.container, children: [
1853
1866
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
@@ -1861,8 +1874,8 @@ var TextArea = (_a) => {
1861
1874
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.input), {
1862
1875
  border: inputBorder
1863
1876
  }),
1864
- onFocus: transitionOnFocus,
1865
- onBlur: transitionOffFocus
1877
+ onFocus,
1878
+ onBlur: offFocus
1866
1879
  }, props)
1867
1880
  ),
1868
1881
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
@@ -1872,7 +1885,7 @@ var TextArea = (_a) => {
1872
1885
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.label), {
1873
1886
  color: labelTextColor
1874
1887
  }),
1875
- onClick: handleClickOnLabel,
1888
+ onClick: focus,
1876
1889
  children: label
1877
1890
  }
1878
1891
  )
@@ -3734,6 +3747,52 @@ var LinearAlgebra = {
3734
3747
  }
3735
3748
  };
3736
3749
  var LinearAlgebra_default = LinearAlgebra;
3750
+
3751
+ // src/utilities/theme/types.ts
3752
+ var ThemeStateArray = ["light", "dark", "system"];
3753
+ var config = {
3754
+ localStorageName: "will-theme",
3755
+ bodyClass: "will-dark"
3756
+ };
3757
+
3758
+ // src/utilities/theme/useThemeState.ts
3759
+ function useThemeState() {
3760
+ const { bodyClass, localStorageName } = config;
3761
+ const htmlClassProcess = (isDark) => {
3762
+ isDark ? document.body.classList.add(bodyClass) : document.body.classList.remove(bodyClass);
3763
+ };
3764
+ const themeCallback = (event) => htmlClassProcess(event.matches);
3765
+ const setLightTheme = () => {
3766
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeCallback);
3767
+ localStorage.setItem(localStorageName, ThemeStateArray[0]);
3768
+ document.body.classList.remove(bodyClass);
3769
+ };
3770
+ const setDarkTheme = () => {
3771
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeCallback);
3772
+ localStorage.setItem(localStorageName, ThemeStateArray[1]);
3773
+ document.body.classList.add(bodyClass);
3774
+ };
3775
+ const setSystem = () => {
3776
+ localStorage.setItem(localStorageName, ThemeStateArray[2]);
3777
+ htmlClassProcess(
3778
+ window.matchMedia("(prefers-color-scheme: dark)").matches
3779
+ );
3780
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeCallback);
3781
+ };
3782
+ return {
3783
+ setThemeState: (mode) => {
3784
+ if (mode === "system") return setSystem();
3785
+ if (mode === "light") return setLightTheme();
3786
+ if (mode === "dark") return setDarkTheme();
3787
+ },
3788
+ getThemeState: () => {
3789
+ const theme = localStorage.getItem(localStorageName);
3790
+ if (!theme) return "light";
3791
+ if (!ThemeStateArray.includes(theme)) return "light";
3792
+ return theme;
3793
+ }
3794
+ };
3795
+ }
3737
3796
  // Annotate the CommonJS export names for ESM import in node:
3738
3797
  0 && (module.exports = {
3739
3798
  Avatar,
@@ -3757,5 +3816,6 @@ var LinearAlgebra_default = LinearAlgebra;
3757
3816
  UploadImage,
3758
3817
  tools,
3759
3818
  useAuthClient,
3760
- useSession
3819
+ useSession,
3820
+ useThemeState
3761
3821
  });
package/dist/index.mjs CHANGED
@@ -1664,30 +1664,35 @@ var InputGoogle = (_a) => {
1664
1664
  const [isFocus, setFocus] = useState9(false);
1665
1665
  const spanRef = useRef8(null);
1666
1666
  const inputRef = useRef8(null);
1667
- function transitionOnFocus() {
1668
- setFocus(true);
1667
+ const borderWhenFocused = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${others2.borderRelease}`;
1668
+ const labelColorWhenFocused = isFocus ? `${options ? options.focusColor : others2.textFocus}` : `${others2.textRelease}`;
1669
+ function spanPositionWhenFocused() {
1669
1670
  if (spanRef.current) {
1670
1671
  spanRef.current.style.top = others2.topFocus;
1671
1672
  spanRef.current.style.fontSize = others2.fontSizeFocus;
1672
1673
  }
1673
1674
  }
1674
- function transitionOffFocus() {
1675
- setFocus(false);
1676
- if (value) return;
1675
+ function spanPositionWhenNotFocused() {
1677
1676
  if (spanRef.current) {
1678
1677
  spanRef.current.style.top = others2.topRelease;
1679
1678
  spanRef.current.style.fontSize = others2.fontSizeRelease;
1680
1679
  }
1681
1680
  }
1682
- function handleClickOnLabel() {
1681
+ function onFocus() {
1682
+ setFocus(true);
1683
+ spanPositionWhenFocused();
1684
+ }
1685
+ function offFocus() {
1686
+ setFocus(false);
1687
+ if (value) return;
1688
+ spanPositionWhenNotFocused();
1689
+ }
1690
+ function focus() {
1683
1691
  var _a2;
1684
1692
  (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
1685
1693
  }
1686
- const inputBorder = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${others2.borderRelease}`;
1687
- const labelTextColor = isFocus ? `${options ? options.focusColor : others2.textFocus}` : `${others2.textRelease}`;
1688
1694
  useEffect9(() => {
1689
- transitionOnFocus();
1690
- transitionOffFocus();
1695
+ if (value) spanPositionWhenFocused();
1691
1696
  }, [value]);
1692
1697
  return /* @__PURE__ */ jsxs12("div", { style: InputGoogle_styles_default.container, children: [
1693
1698
  /* @__PURE__ */ jsx15(
@@ -1697,13 +1702,15 @@ var InputGoogle = (_a) => {
1697
1702
  name: "will-input-google",
1698
1703
  ref: inputRef,
1699
1704
  value,
1700
- onChange: (e) => setValue(e.target.value),
1705
+ onChange: (e) => {
1706
+ setValue(e.target.value);
1707
+ },
1701
1708
  type: "text",
1702
1709
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.input), {
1703
- border: inputBorder
1710
+ border: borderWhenFocused
1704
1711
  }),
1705
- onFocus: transitionOnFocus,
1706
- onBlur: transitionOffFocus
1712
+ onFocus,
1713
+ onBlur: offFocus
1707
1714
  }, props)
1708
1715
  ),
1709
1716
  /* @__PURE__ */ jsx15(
@@ -1711,9 +1718,9 @@ var InputGoogle = (_a) => {
1711
1718
  {
1712
1719
  ref: spanRef,
1713
1720
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.label), {
1714
- color: labelTextColor
1721
+ color: labelColorWhenFocused
1715
1722
  }),
1716
- onClick: handleClickOnLabel,
1723
+ onClick: focus,
1717
1724
  children: label
1718
1725
  }
1719
1726
  )
@@ -1785,30 +1792,35 @@ var TextArea = (_a) => {
1785
1792
  const [isFocus, setFocus] = useState10(false);
1786
1793
  const spanRef = useRef9(null);
1787
1794
  const inputRef = useRef9(null);
1788
- function transitionOnFocus() {
1789
- setFocus(true);
1795
+ const inputBorder = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${others3.borderRelease}`;
1796
+ const labelTextColor = isFocus ? `${options ? options.focusColor : others3.textFocus}` : `${others3.textRelease}`;
1797
+ function spanPositionWhenFocused() {
1790
1798
  if (spanRef.current) {
1791
1799
  spanRef.current.style.top = others3.topFocus;
1792
1800
  spanRef.current.style.fontSize = others3.fontSizeFocus;
1793
1801
  }
1794
1802
  }
1795
- function transitionOffFocus() {
1796
- setFocus(false);
1797
- if (value) return;
1803
+ function spanPositionWhenNotFocused() {
1798
1804
  if (spanRef.current) {
1799
1805
  spanRef.current.style.top = others3.topRelease;
1800
1806
  spanRef.current.style.fontSize = others3.fontSizeRelease;
1801
1807
  }
1802
1808
  }
1803
- function handleClickOnLabel() {
1809
+ function onFocus() {
1810
+ setFocus(true);
1811
+ spanPositionWhenFocused();
1812
+ }
1813
+ function offFocus() {
1814
+ setFocus(false);
1815
+ if (value) return;
1816
+ spanPositionWhenNotFocused();
1817
+ }
1818
+ function focus() {
1804
1819
  var _a2;
1805
1820
  (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
1806
1821
  }
1807
- const inputBorder = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${others3.borderRelease}`;
1808
- const labelTextColor = isFocus ? `${options ? options.focusColor : others3.textFocus}` : `${others3.textRelease}`;
1809
1822
  useEffect10(() => {
1810
- transitionOnFocus();
1811
- transitionOffFocus();
1823
+ if (value) spanPositionWhenFocused();
1812
1824
  }, [value]);
1813
1825
  return /* @__PURE__ */ jsxs13("div", { style: TextArea_styles_default.container, children: [
1814
1826
  /* @__PURE__ */ jsx16(
@@ -1822,8 +1834,8 @@ var TextArea = (_a) => {
1822
1834
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.input), {
1823
1835
  border: inputBorder
1824
1836
  }),
1825
- onFocus: transitionOnFocus,
1826
- onBlur: transitionOffFocus
1837
+ onFocus,
1838
+ onBlur: offFocus
1827
1839
  }, props)
1828
1840
  ),
1829
1841
  /* @__PURE__ */ jsx16(
@@ -1833,7 +1845,7 @@ var TextArea = (_a) => {
1833
1845
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.label), {
1834
1846
  color: labelTextColor
1835
1847
  }),
1836
- onClick: handleClickOnLabel,
1848
+ onClick: focus,
1837
1849
  children: label
1838
1850
  }
1839
1851
  )
@@ -3695,6 +3707,52 @@ var LinearAlgebra = {
3695
3707
  }
3696
3708
  };
3697
3709
  var LinearAlgebra_default = LinearAlgebra;
3710
+
3711
+ // src/utilities/theme/types.ts
3712
+ var ThemeStateArray = ["light", "dark", "system"];
3713
+ var config = {
3714
+ localStorageName: "will-theme",
3715
+ bodyClass: "will-dark"
3716
+ };
3717
+
3718
+ // src/utilities/theme/useThemeState.ts
3719
+ function useThemeState() {
3720
+ const { bodyClass, localStorageName } = config;
3721
+ const htmlClassProcess = (isDark) => {
3722
+ isDark ? document.body.classList.add(bodyClass) : document.body.classList.remove(bodyClass);
3723
+ };
3724
+ const themeCallback = (event) => htmlClassProcess(event.matches);
3725
+ const setLightTheme = () => {
3726
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeCallback);
3727
+ localStorage.setItem(localStorageName, ThemeStateArray[0]);
3728
+ document.body.classList.remove(bodyClass);
3729
+ };
3730
+ const setDarkTheme = () => {
3731
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", themeCallback);
3732
+ localStorage.setItem(localStorageName, ThemeStateArray[1]);
3733
+ document.body.classList.add(bodyClass);
3734
+ };
3735
+ const setSystem = () => {
3736
+ localStorage.setItem(localStorageName, ThemeStateArray[2]);
3737
+ htmlClassProcess(
3738
+ window.matchMedia("(prefers-color-scheme: dark)").matches
3739
+ );
3740
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", themeCallback);
3741
+ };
3742
+ return {
3743
+ setThemeState: (mode) => {
3744
+ if (mode === "system") return setSystem();
3745
+ if (mode === "light") return setLightTheme();
3746
+ if (mode === "dark") return setDarkTheme();
3747
+ },
3748
+ getThemeState: () => {
3749
+ const theme = localStorage.getItem(localStorageName);
3750
+ if (!theme) return "light";
3751
+ if (!ThemeStateArray.includes(theme)) return "light";
3752
+ return theme;
3753
+ }
3754
+ };
3755
+ }
3698
3756
  export {
3699
3757
  Avatar_default as Avatar,
3700
3758
  Button_default as Button,
@@ -3717,5 +3775,6 @@ export {
3717
3775
  UploadImage_default as UploadImage,
3718
3776
  tools_default as tools,
3719
3777
  useAuthClient_default as useAuthClient,
3720
- useSession
3778
+ useSession,
3779
+ useThemeState
3721
3780
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willphan1712000/frontend",
3
- "version": "1.8.2",
3
+ "version": "1.9.0",
4
4
  "description": "Frontend Library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",