@willphan1712000/frontend 1.9.0 → 1.9.1

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/README.md CHANGED
@@ -28,6 +28,7 @@ Reusable React UI components and frontend utilities packaged for application dev
28
28
  - `Transform`
29
29
  - `tools`
30
30
  - `LinearAlgebra`
31
+ - `useThemeState`
31
32
 
32
33
  ### Auth helpers
33
34
  - `useSession`
@@ -249,6 +250,44 @@ function AppProviders({ children }: { children: React.ReactNode }) {
249
250
  - `session`
250
251
  - `auth`
251
252
 
253
+ ## Theme management usage
254
+
255
+ ### `useThemeState`
256
+
257
+ A custom React hook for managing, persisting, and applying the application's theme state (`'light'`, `'dark'`, or `'system'`). It synchronizes state with browser `localStorage` and applies/removes the theme class on `document.body`.
258
+
259
+ ```tsx
260
+ import { useThemeState } from '@willphan1712000/frontend';
261
+
262
+ const Example = () => {
263
+ const { setThemeState, getThemeState } = useThemeState();
264
+
265
+ return (
266
+ <div>
267
+ <p>Current Theme: {getThemeState()}</p>
268
+ <button onClick={() => setThemeState('light')}>Light</button>
269
+ <button onClick={() => setThemeState('dark')}>Dark</button>
270
+ <button onClick={() => setThemeState('system')}>System</button>
271
+ </div>
272
+ );
273
+ };
274
+ ```
275
+
276
+ #### API Reference
277
+
278
+ - `getThemeState(): 'light' | 'dark' | 'system'`
279
+ Retrieves the active theme setting from `localStorage`. Defaults to `'light'`.
280
+ - `setThemeState(mode: 'light' | 'dark' | 'system'): void`
281
+ Sets the active theme setting.
282
+ - `'light'`: Stores `'light'`, removes `'will-dark'` class from `document.body`, and disables OS preference event listeners.
283
+ - `'dark'`: Stores `'dark'`, adds `'will-dark'` class to `document.body`, and disables OS preference event listeners.
284
+ - `'system'`: Stores `'system'`, automatically toggles `'will-dark'` based on OS preferences, and registers a listener to react to future OS preference changes.
285
+
286
+ #### Configuration Details
287
+
288
+ - **Local Storage Key:** `'will-theme'`
289
+ - **CSS Class Applied to `<body>`:** `'will-dark'`
290
+
252
291
  ## Exported utilities
253
292
 
254
293
  ```ts
package/dist/index.d.mts CHANGED
@@ -174,7 +174,10 @@ interface Props$5 {
174
174
  setValue?: (value?: string) => void;
175
175
  label?: string;
176
176
  options?: {
177
- focusColor: string;
177
+ focusColor?: string;
178
+ backgroundColor?: string;
179
+ textColor?: string;
180
+ borderColor?: string;
178
181
  };
179
182
  }
180
183
  /**
@@ -203,7 +206,10 @@ interface Props$4 {
203
206
  setValue?: (value?: string) => void;
204
207
  label?: string;
205
208
  options?: {
206
- focusColor: string;
209
+ focusColor?: string;
210
+ backgroundColor?: string;
211
+ textColor?: string;
212
+ borderColor?: string;
207
213
  };
208
214
  }
209
215
  /**
package/dist/index.d.ts CHANGED
@@ -174,7 +174,10 @@ interface Props$5 {
174
174
  setValue?: (value?: string) => void;
175
175
  label?: string;
176
176
  options?: {
177
- focusColor: string;
177
+ focusColor?: string;
178
+ backgroundColor?: string;
179
+ textColor?: string;
180
+ borderColor?: string;
178
181
  };
179
182
  }
180
183
  /**
@@ -203,7 +206,10 @@ interface Props$4 {
203
206
  setValue?: (value?: string) => void;
204
207
  label?: string;
205
208
  options?: {
206
- focusColor: string;
209
+ focusColor?: string;
210
+ backgroundColor?: string;
211
+ textColor?: string;
212
+ borderColor?: string;
207
213
  };
208
214
  }
209
215
  /**
package/dist/index.js CHANGED
@@ -1657,7 +1657,8 @@ var others2 = {
1657
1657
  borderFocus: "#0957d0",
1658
1658
  textRelease: "#000",
1659
1659
  textFocus: "#0957d0",
1660
- border: "solid 1px"
1660
+ border: "solid 1px",
1661
+ backgroundColor: "#fff"
1661
1662
  };
1662
1663
  var styles10 = {
1663
1664
  input: {
@@ -1667,7 +1668,9 @@ var styles10 = {
1667
1668
  border: `${others2.border} ${others2.borderRelease}`,
1668
1669
  borderRadius: "6px",
1669
1670
  padding: "10px",
1670
- outline: "none"
1671
+ outline: "none",
1672
+ backgroundColor: others2.backgroundColor,
1673
+ color: others2.textRelease
1671
1674
  },
1672
1675
  container: {
1673
1676
  width: "100%",
@@ -1681,7 +1684,8 @@ var styles10 = {
1681
1684
  transform: "translateY(-50%)",
1682
1685
  transition: "all .1s linear",
1683
1686
  padding: "0px 5px",
1684
- backgroundColor: "white"
1687
+ backgroundColor: others2.backgroundColor,
1688
+ color: others2.textRelease
1685
1689
  }
1686
1690
  };
1687
1691
  var InputGoogle_styles_default = styles10;
@@ -1704,8 +1708,11 @@ var InputGoogle = (_a) => {
1704
1708
  const [isFocus, setFocus] = (0, import_react13.useState)(false);
1705
1709
  const spanRef = (0, import_react13.useRef)(null);
1706
1710
  const inputRef = (0, import_react13.useRef)(null);
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}`;
1711
+ const backgroundColor = (options == null ? void 0 : options.backgroundColor) ? options.backgroundColor : others2.backgroundColor;
1712
+ const textColor = (options == null ? void 0 : options.textColor) ? options.textColor : others2.textRelease;
1713
+ const borderColor = (options == null ? void 0 : options.borderColor) ? options.borderColor : others2.borderRelease;
1714
+ const borderWhenFocused = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${borderColor}`;
1715
+ const labelColorWhenFocused = isFocus ? `${(options == null ? void 0 : options.focusColor) ? options.focusColor : others2.textFocus}` : `${textColor}`;
1709
1716
  function spanPositionWhenFocused() {
1710
1717
  if (spanRef.current) {
1711
1718
  spanRef.current.style.top = others2.topFocus;
@@ -1747,7 +1754,9 @@ var InputGoogle = (_a) => {
1747
1754
  },
1748
1755
  type: "text",
1749
1756
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.input), {
1750
- border: borderWhenFocused
1757
+ border: borderWhenFocused,
1758
+ backgroundColor,
1759
+ color: textColor
1751
1760
  }),
1752
1761
  onFocus,
1753
1762
  onBlur: offFocus
@@ -1758,7 +1767,8 @@ var InputGoogle = (_a) => {
1758
1767
  {
1759
1768
  ref: spanRef,
1760
1769
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.label), {
1761
- color: labelColorWhenFocused
1770
+ color: labelColorWhenFocused,
1771
+ backgroundColor
1762
1772
  }),
1763
1773
  onClick: focus,
1764
1774
  children: label
@@ -1782,7 +1792,8 @@ var others3 = {
1782
1792
  borderFocus: "#0957d0",
1783
1793
  textRelease: "#000",
1784
1794
  textFocus: "#0957d0",
1785
- border: "solid 1px"
1795
+ border: "solid 1px",
1796
+ backgroundColor: "#fff"
1786
1797
  };
1787
1798
  var styles11 = {
1788
1799
  input: {
@@ -1793,7 +1804,9 @@ var styles11 = {
1793
1804
  borderRadius: "6px",
1794
1805
  padding: "10px",
1795
1806
  outline: "none",
1796
- resize: "none"
1807
+ resize: "none",
1808
+ backgroundColor: others3.backgroundColor,
1809
+ color: others3.textRelease
1797
1810
  },
1798
1811
  container: {
1799
1812
  width: "100%",
@@ -1809,7 +1822,8 @@ var styles11 = {
1809
1822
  transform: "translateY(-50%)",
1810
1823
  transition: "all .1s linear",
1811
1824
  padding: "0px 5px",
1812
- backgroundColor: "white"
1825
+ backgroundColor: others3.backgroundColor,
1826
+ color: others3.textRelease
1813
1827
  }
1814
1828
  };
1815
1829
  var TextArea_styles_default = styles11;
@@ -1832,8 +1846,11 @@ var TextArea = (_a) => {
1832
1846
  const [isFocus, setFocus] = (0, import_react14.useState)(false);
1833
1847
  const spanRef = (0, import_react14.useRef)(null);
1834
1848
  const inputRef = (0, import_react14.useRef)(null);
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}`;
1849
+ const backgroundColor = (options == null ? void 0 : options.backgroundColor) ? options.backgroundColor : others3.backgroundColor;
1850
+ const textColor = (options == null ? void 0 : options.textColor) ? options.textColor : others3.textRelease;
1851
+ const borderColor = (options == null ? void 0 : options.borderColor) ? options.borderColor : others3.borderRelease;
1852
+ const borderWhenFocused = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${borderColor}`;
1853
+ const labelColorWhenFocused = isFocus ? `${(options == null ? void 0 : options.focusColor) ? options.focusColor : others3.textFocus}` : `${textColor}`;
1837
1854
  function spanPositionWhenFocused() {
1838
1855
  if (spanRef.current) {
1839
1856
  spanRef.current.style.top = others3.topFocus;
@@ -1872,7 +1889,9 @@ var TextArea = (_a) => {
1872
1889
  value,
1873
1890
  onChange: (e) => setValue(e.target.value),
1874
1891
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.input), {
1875
- border: inputBorder
1892
+ border: borderWhenFocused,
1893
+ backgroundColor,
1894
+ color: textColor
1876
1895
  }),
1877
1896
  onFocus,
1878
1897
  onBlur: offFocus
@@ -1883,7 +1902,8 @@ var TextArea = (_a) => {
1883
1902
  {
1884
1903
  ref: spanRef,
1885
1904
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.label), {
1886
- color: labelTextColor
1905
+ color: labelColorWhenFocused,
1906
+ backgroundColor
1887
1907
  }),
1888
1908
  onClick: focus,
1889
1909
  children: label
package/dist/index.mjs CHANGED
@@ -1617,7 +1617,8 @@ var others2 = {
1617
1617
  borderFocus: "#0957d0",
1618
1618
  textRelease: "#000",
1619
1619
  textFocus: "#0957d0",
1620
- border: "solid 1px"
1620
+ border: "solid 1px",
1621
+ backgroundColor: "#fff"
1621
1622
  };
1622
1623
  var styles10 = {
1623
1624
  input: {
@@ -1627,7 +1628,9 @@ var styles10 = {
1627
1628
  border: `${others2.border} ${others2.borderRelease}`,
1628
1629
  borderRadius: "6px",
1629
1630
  padding: "10px",
1630
- outline: "none"
1631
+ outline: "none",
1632
+ backgroundColor: others2.backgroundColor,
1633
+ color: others2.textRelease
1631
1634
  },
1632
1635
  container: {
1633
1636
  width: "100%",
@@ -1641,7 +1644,8 @@ var styles10 = {
1641
1644
  transform: "translateY(-50%)",
1642
1645
  transition: "all .1s linear",
1643
1646
  padding: "0px 5px",
1644
- backgroundColor: "white"
1647
+ backgroundColor: others2.backgroundColor,
1648
+ color: others2.textRelease
1645
1649
  }
1646
1650
  };
1647
1651
  var InputGoogle_styles_default = styles10;
@@ -1664,8 +1668,11 @@ var InputGoogle = (_a) => {
1664
1668
  const [isFocus, setFocus] = useState9(false);
1665
1669
  const spanRef = useRef8(null);
1666
1670
  const inputRef = useRef8(null);
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}`;
1671
+ const backgroundColor = (options == null ? void 0 : options.backgroundColor) ? options.backgroundColor : others2.backgroundColor;
1672
+ const textColor = (options == null ? void 0 : options.textColor) ? options.textColor : others2.textRelease;
1673
+ const borderColor = (options == null ? void 0 : options.borderColor) ? options.borderColor : others2.borderRelease;
1674
+ const borderWhenFocused = isFocus ? `${others2.border} ${options ? options.focusColor : others2.borderFocus}` : `${others2.border} ${borderColor}`;
1675
+ const labelColorWhenFocused = isFocus ? `${(options == null ? void 0 : options.focusColor) ? options.focusColor : others2.textFocus}` : `${textColor}`;
1669
1676
  function spanPositionWhenFocused() {
1670
1677
  if (spanRef.current) {
1671
1678
  spanRef.current.style.top = others2.topFocus;
@@ -1707,7 +1714,9 @@ var InputGoogle = (_a) => {
1707
1714
  },
1708
1715
  type: "text",
1709
1716
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.input), {
1710
- border: borderWhenFocused
1717
+ border: borderWhenFocused,
1718
+ backgroundColor,
1719
+ color: textColor
1711
1720
  }),
1712
1721
  onFocus,
1713
1722
  onBlur: offFocus
@@ -1718,7 +1727,8 @@ var InputGoogle = (_a) => {
1718
1727
  {
1719
1728
  ref: spanRef,
1720
1729
  style: __spreadProps(__spreadValues({}, InputGoogle_styles_default.label), {
1721
- color: labelColorWhenFocused
1730
+ color: labelColorWhenFocused,
1731
+ backgroundColor
1722
1732
  }),
1723
1733
  onClick: focus,
1724
1734
  children: label
@@ -1742,7 +1752,8 @@ var others3 = {
1742
1752
  borderFocus: "#0957d0",
1743
1753
  textRelease: "#000",
1744
1754
  textFocus: "#0957d0",
1745
- border: "solid 1px"
1755
+ border: "solid 1px",
1756
+ backgroundColor: "#fff"
1746
1757
  };
1747
1758
  var styles11 = {
1748
1759
  input: {
@@ -1753,7 +1764,9 @@ var styles11 = {
1753
1764
  borderRadius: "6px",
1754
1765
  padding: "10px",
1755
1766
  outline: "none",
1756
- resize: "none"
1767
+ resize: "none",
1768
+ backgroundColor: others3.backgroundColor,
1769
+ color: others3.textRelease
1757
1770
  },
1758
1771
  container: {
1759
1772
  width: "100%",
@@ -1769,7 +1782,8 @@ var styles11 = {
1769
1782
  transform: "translateY(-50%)",
1770
1783
  transition: "all .1s linear",
1771
1784
  padding: "0px 5px",
1772
- backgroundColor: "white"
1785
+ backgroundColor: others3.backgroundColor,
1786
+ color: others3.textRelease
1773
1787
  }
1774
1788
  };
1775
1789
  var TextArea_styles_default = styles11;
@@ -1792,8 +1806,11 @@ var TextArea = (_a) => {
1792
1806
  const [isFocus, setFocus] = useState10(false);
1793
1807
  const spanRef = useRef9(null);
1794
1808
  const inputRef = useRef9(null);
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}`;
1809
+ const backgroundColor = (options == null ? void 0 : options.backgroundColor) ? options.backgroundColor : others3.backgroundColor;
1810
+ const textColor = (options == null ? void 0 : options.textColor) ? options.textColor : others3.textRelease;
1811
+ const borderColor = (options == null ? void 0 : options.borderColor) ? options.borderColor : others3.borderRelease;
1812
+ const borderWhenFocused = isFocus ? `${others3.border} ${options ? options.focusColor : others3.borderFocus}` : `${others3.border} ${borderColor}`;
1813
+ const labelColorWhenFocused = isFocus ? `${(options == null ? void 0 : options.focusColor) ? options.focusColor : others3.textFocus}` : `${textColor}`;
1797
1814
  function spanPositionWhenFocused() {
1798
1815
  if (spanRef.current) {
1799
1816
  spanRef.current.style.top = others3.topFocus;
@@ -1832,7 +1849,9 @@ var TextArea = (_a) => {
1832
1849
  value,
1833
1850
  onChange: (e) => setValue(e.target.value),
1834
1851
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.input), {
1835
- border: inputBorder
1852
+ border: borderWhenFocused,
1853
+ backgroundColor,
1854
+ color: textColor
1836
1855
  }),
1837
1856
  onFocus,
1838
1857
  onBlur: offFocus
@@ -1843,7 +1862,8 @@ var TextArea = (_a) => {
1843
1862
  {
1844
1863
  ref: spanRef,
1845
1864
  style: __spreadProps(__spreadValues({}, TextArea_styles_default.label), {
1846
- color: labelTextColor
1865
+ color: labelColorWhenFocused,
1866
+ backgroundColor
1847
1867
  }),
1848
1868
  onClick: focus,
1849
1869
  children: label
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@willphan1712000/frontend",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Frontend Library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",