@abhir9/pd-design-system 0.1.14 → 0.1.16

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.cjs CHANGED
@@ -31,10 +31,10 @@ var React__default = /*#__PURE__*/_interopDefault(React);
31
31
  var LucideIcons__namespace = /*#__PURE__*/_interopNamespace(LucideIcons);
32
32
 
33
33
  // src/theme/types.ts
34
- var THEME_MODES = ["light", "dark"];
34
+ var THEME_MODES = ["light", "dark", "system"];
35
35
  var THEME_NAMES = ["base", "brand"];
36
36
  var ADAPTER_TYPES = ["shadcn", "material"];
37
- var DEFAULT_MODE = "light";
37
+ var DEFAULT_MODE = "system";
38
38
  var [DEFAULT_THEME] = THEME_NAMES;
39
39
  var [DEFAULT_ADAPTER] = ADAPTER_TYPES;
40
40
 
@@ -296,11 +296,6 @@ var ShadcnButton = React.forwardRef(
296
296
  children,
297
297
  ...props
298
298
  }, ref) => {
299
- if (process.env.NODE_ENV !== "production" && !children && (startIcon || endIcon) && !props["aria-label"]) {
300
- console.warn(
301
- "[pd-design] Icon-only buttons should have an aria-label for accessibility. Add aria-label prop to describe the button action."
302
- );
303
- }
304
299
  const buttonClasses = cn(
305
300
  buttonVariants({ variant, intent, size }),
306
301
  fullWidth && "w-full"
@@ -1023,9 +1018,19 @@ function createSemanticTokens(mode) {
1023
1018
  }
1024
1019
 
1025
1020
  // src/theme/theme.ts
1021
+ function resolveThemeMode(mode) {
1022
+ if (mode !== "system") {
1023
+ return mode;
1024
+ }
1025
+ if (typeof window !== "undefined" && window.matchMedia) {
1026
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1027
+ }
1028
+ return "light";
1029
+ }
1026
1030
  function createTheme(name, mode) {
1027
- const semantic = createSemanticTokens(mode);
1028
- const isLight = mode === "light";
1031
+ const resolvedMode = resolveThemeMode(mode);
1032
+ const semantic = createSemanticTokens(resolvedMode);
1033
+ const isLight = resolvedMode === "light";
1029
1034
  const border = isLight ? borderTokens.light : borderTokens.dark;
1030
1035
  const content = isLight ? contentTokens.light : contentTokens.dark;
1031
1036
  const background = isLight ? backgroundTokens.light : backgroundTokens.dark;
@@ -1193,7 +1198,8 @@ function createTheme(name, mode) {
1193
1198
  };
1194
1199
  return {
1195
1200
  name,
1196
- mode,
1201
+ mode: resolvedMode,
1202
+ // Store the resolved mode (light/dark) not 'system'
1197
1203
  cssVariables
1198
1204
  };
1199
1205
  }
@@ -1204,12 +1210,46 @@ function ThemeProvider({
1204
1210
  theme: themeName = DEFAULT_THEME,
1205
1211
  mode = DEFAULT_MODE
1206
1212
  }) {
1207
- const theme = React.useMemo(() => createTheme(themeName, mode), [themeName, mode]);
1213
+ const [resolvedMode, setResolvedMode] = React.useState(
1214
+ () => resolveThemeMode(mode)
1215
+ );
1216
+ React.useEffect(() => {
1217
+ if (mode !== "system" || typeof window === "undefined" || !window.matchMedia) {
1218
+ return;
1219
+ }
1220
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1221
+ const handleChange = (e) => {
1222
+ setResolvedMode(e.matches ? "dark" : "light");
1223
+ };
1224
+ handleChange(mediaQuery);
1225
+ if (mediaQuery.addEventListener) {
1226
+ mediaQuery.addEventListener("change", handleChange);
1227
+ return () => mediaQuery.removeEventListener("change", handleChange);
1228
+ } else {
1229
+ mediaQuery.addListener(handleChange);
1230
+ return () => mediaQuery.removeListener(handleChange);
1231
+ }
1232
+ }, [mode]);
1233
+ React.useEffect(() => {
1234
+ if (mode !== "system") {
1235
+ setResolvedMode(mode === "dark" ? "dark" : "light");
1236
+ }
1237
+ }, [mode]);
1238
+ const theme = React.useMemo(() => {
1239
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1240
+ return createTheme(themeName, effectiveMode);
1241
+ }, [themeName, mode, resolvedMode]);
1208
1242
  React.useEffect(() => {
1209
1243
  setDesignSystemConfig({ adapter, theme: themeName, mode });
1210
1244
  }, [adapter, themeName, mode]);
1211
1245
  React.useEffect(() => {
1212
1246
  const root = document.documentElement;
1247
+ const effectiveMode = mode === "system" ? resolvedMode : mode;
1248
+ if (effectiveMode === "dark") {
1249
+ root.classList.add("dark");
1250
+ } else {
1251
+ root.classList.remove("dark");
1252
+ }
1213
1253
  Object.entries(theme.cssVariables).forEach(([key, value]) => {
1214
1254
  root.style.setProperty(key, value);
1215
1255
  });
@@ -1218,7 +1258,7 @@ function ThemeProvider({
1218
1258
  root.style.removeProperty(key);
1219
1259
  });
1220
1260
  };
1221
- }, [theme]);
1261
+ }, [theme, mode, resolvedMode]);
1222
1262
  const contextValue = React.useMemo(() => ({
1223
1263
  config: getDesignSystemConfig(),
1224
1264
  setConfig: setDesignSystemConfig
@@ -1344,6 +1384,7 @@ exports.orange = orange;
1344
1384
  exports.radius = radius;
1345
1385
  exports.red = red;
1346
1386
  exports.renderIcon = renderIcon;
1387
+ exports.resolveThemeMode = resolveThemeMode;
1347
1388
  exports.semanticTokens = semanticTokens;
1348
1389
  exports.setDesignSystemConfig = setDesignSystemConfig;
1349
1390
  exports.shadows = shadows;