@okshaun/components 0.3.2 → 0.3.4

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.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
- import { forwardRef, useMemo, createElement, useEffect, createContext, useState, useContext, useRef } from "react";
2
+ import { forwardRef, useMemo, createElement, useEffect, useState, useRef, createContext, useContext, useSyncExternalStore } from "react";
3
3
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
4
+ import { b as breakpoints, c as containerSizes } from "./size.primitives-j2MFgtrT.js";
4
5
  function isObject(value) {
5
6
  return typeof value === "object" && value != null && !Array.isArray(value);
6
7
  }
@@ -97,10 +98,10 @@ function mapObject(obj, fn) {
97
98
  if (!isObject(obj)) return fn(obj);
98
99
  return walkObject(obj, (value) => fn(value));
99
100
  }
100
- function toResponsiveObject(values, breakpoints) {
101
+ function toResponsiveObject(values, breakpoints2) {
101
102
  return values.reduce(
102
103
  (acc, current, index) => {
103
- const key = breakpoints[index];
104
+ const key = breakpoints2[index];
104
105
  if (current != null) {
105
106
  acc[key] = current;
106
107
  }
@@ -2034,9 +2035,7 @@ const Icon = ({
2034
2035
  fill = "current",
2035
2036
  ...props
2036
2037
  }) => {
2037
- const [cssProps, otherProps] = splitCssProps(props);
2038
- const { css: cssProp, ...styleProps } = cssProps;
2039
- const className = css(cssProp, styleProps);
2038
+ const [className, otherProps] = splitProps(props);
2040
2039
  useEffect(() => {
2041
2040
  injectSprite();
2042
2041
  }, []);
@@ -2350,10 +2349,26 @@ const IconNames = {
2350
2349
  "zoom-out": "zoom-out"
2351
2350
  };
2352
2351
  const Button = React.forwardRef(
2353
- ({ appearance, size, href, className, children, loading, disabled, iconBefore, iconAfter, ...props }, ref) => {
2352
+ ({
2353
+ appearance,
2354
+ size,
2355
+ href,
2356
+ className,
2357
+ children,
2358
+ loading,
2359
+ disabled,
2360
+ iconBefore,
2361
+ iconAfter,
2362
+ ...props
2363
+ }, ref) => {
2354
2364
  const trulyDisabled = loading || disabled;
2355
2365
  const asComponent = href ? "a" : "button";
2356
- const classes = button({ appearance, size, iconBefore: Boolean(iconBefore), iconAfter: Boolean(iconAfter) });
2366
+ const classes = button({
2367
+ appearance,
2368
+ size,
2369
+ iconBefore: Boolean(iconBefore),
2370
+ iconAfter: Boolean(iconAfter)
2371
+ });
2357
2372
  return (
2358
2373
  // @ts-expect-error - Polymorphic type inference issue
2359
2374
  /* @__PURE__ */ jsx(
@@ -2373,7 +2388,18 @@ const Button = React.forwardRef(
2373
2388
  children,
2374
2389
  iconAfter && /* @__PURE__ */ jsx(Icon, { name: iconAfter, className: classes.icon })
2375
2390
  ] }),
2376
- loading && /* @__PURE__ */ jsx(Grid, { position: "absolute", top: "0", left: "0", right: "0", bottom: "0", placeItems: "center", children: /* @__PURE__ */ jsx(Spinner, {}) })
2391
+ loading && /* @__PURE__ */ jsx(
2392
+ Grid,
2393
+ {
2394
+ position: "absolute",
2395
+ top: "0",
2396
+ left: "0",
2397
+ right: "0",
2398
+ bottom: "0",
2399
+ placeItems: "center",
2400
+ children: /* @__PURE__ */ jsx(Spinner, {})
2401
+ }
2402
+ )
2377
2403
  ] })
2378
2404
  }
2379
2405
  )
@@ -2398,7 +2424,16 @@ const Badge = React.forwardRef(
2398
2424
  }
2399
2425
  );
2400
2426
  const IconButton = React.forwardRef(
2401
- ({ appearance, size, href, className, loading, disabled, iconName, ...props }, ref) => {
2427
+ ({
2428
+ appearance,
2429
+ size,
2430
+ href,
2431
+ className,
2432
+ loading,
2433
+ disabled,
2434
+ iconName,
2435
+ ...props
2436
+ }, ref) => {
2402
2437
  const trulyDisabled = loading || disabled;
2403
2438
  const asComponent = href ? "a" : "button";
2404
2439
  const classes = iconButton({ appearance, size });
@@ -2417,7 +2452,18 @@ const IconButton = React.forwardRef(
2417
2452
  ...props,
2418
2453
  children: /* @__PURE__ */ jsxs(Fragment, { children: [
2419
2454
  /* @__PURE__ */ jsx(HStack, { gap: "2", opacity: loading ? 0 : 1, children: /* @__PURE__ */ jsx(Icon, { name: iconName || "menu", className: classes.icon }) }),
2420
- loading && /* @__PURE__ */ jsx(Grid, { position: "absolute", top: "0", left: "0", right: "0", bottom: "0", placeItems: "center", children: /* @__PURE__ */ jsx(Spinner, {}) })
2455
+ loading && /* @__PURE__ */ jsx(
2456
+ Grid,
2457
+ {
2458
+ position: "absolute",
2459
+ top: "0",
2460
+ left: "0",
2461
+ right: "0",
2462
+ bottom: "0",
2463
+ placeItems: "center",
2464
+ children: /* @__PURE__ */ jsx(Spinner, {})
2465
+ }
2466
+ )
2421
2467
  ] })
2422
2468
  }
2423
2469
  )
@@ -2784,101 +2830,6 @@ const CheckboxInput = ({
2784
2830
  }
2785
2831
  );
2786
2832
  };
2787
- const THEME_STORAGE_KEY = "okshaun-theme-preference";
2788
- function getInitialTheme() {
2789
- const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
2790
- if (storedTheme) {
2791
- return storedTheme;
2792
- }
2793
- if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
2794
- return "dark";
2795
- }
2796
- return "light";
2797
- }
2798
- const ThemeContext = createContext(void 0);
2799
- function ThemeProvider({ children }) {
2800
- const [theme, setThemeState] = useState(() => getInitialTheme());
2801
- const setTheme = (newTheme) => {
2802
- setThemeState(newTheme);
2803
- localStorage.setItem(THEME_STORAGE_KEY, newTheme);
2804
- };
2805
- useEffect(() => {
2806
- document.documentElement.removeAttribute("data-color-mode");
2807
- document.documentElement.removeAttribute("data-theme");
2808
- document.documentElement.setAttribute("data-color-mode", theme);
2809
- }, [theme]);
2810
- useEffect(() => {
2811
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
2812
- const handleChange = (e) => {
2813
- const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
2814
- if (!storedTheme) {
2815
- setThemeState(e.matches ? "dark" : "light");
2816
- }
2817
- };
2818
- mediaQuery.addEventListener("change", handleChange);
2819
- return () => mediaQuery.removeEventListener("change", handleChange);
2820
- }, []);
2821
- return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { theme, setTheme }, children });
2822
- }
2823
- function useTheme() {
2824
- const context2 = useContext(ThemeContext);
2825
- if (context2 === void 0) {
2826
- throw new Error("useTheme must be used within a ThemeProvider");
2827
- }
2828
- return context2;
2829
- }
2830
- const themeSwitchStyles = css({
2831
- position: "relative",
2832
- borderWidth: "2",
2833
- borderStyle: "solid",
2834
- borderColor: "border",
2835
- color: "transparent",
2836
- margin: "8",
2837
- borderRadius: "100",
2838
- cursor: "pointer",
2839
- display: "grid",
2840
- lineHeight: "none",
2841
- width: "14",
2842
- height: "14",
2843
- transition: "all",
2844
- "&:before": {
2845
- content: '""',
2846
- position: "absolute",
2847
- inset: "0",
2848
- opacity: 0,
2849
- display: "block",
2850
- borderRadius: "100",
2851
- bg: "bg.neutral.bold",
2852
- transition: "all",
2853
- transitionTimingFunction: "default",
2854
- transitionDuration: "normal"
2855
- },
2856
- _hover: {
2857
- cursor: "pointer",
2858
- bg: { base: "darkNeutral.0", _dark: "neutral.0" },
2859
- borderColor: "bg.neutral.bold",
2860
- "&:before": {
2861
- inset: "-8",
2862
- bg: { base: "darkNeutral.0", _dark: "neutral.0" },
2863
- opacity: 0.25
2864
- }
2865
- }
2866
- });
2867
- function ThemeSwitcher() {
2868
- const { theme, setTheme } = useTheme();
2869
- const toggleTheme = () => {
2870
- setTheme(theme === "light" ? "dark" : "light");
2871
- };
2872
- return /* @__PURE__ */ jsx(
2873
- "button",
2874
- {
2875
- className: themeSwitchStyles,
2876
- onClick: toggleTheme,
2877
- "aria-label": `Switch to ${theme === "light" ? "dark" : "light"} theme`,
2878
- children: /* @__PURE__ */ jsx("span", {})
2879
- }
2880
- );
2881
- }
2882
2833
  const Tooltip = ({
2883
2834
  trigger = "onHover",
2884
2835
  caret = true,
@@ -3230,14 +3181,240 @@ const Menu = ({ menuSection, iconPlacement, variant, multiSelectType, onChange }
3230
3181
  }) })
3231
3182
  ] });
3232
3183
  };
3184
+ const THEME_STORAGE_KEY = "okshaun-theme-preference";
3185
+ function getInitialTheme() {
3186
+ const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
3187
+ if (storedTheme) {
3188
+ return storedTheme;
3189
+ }
3190
+ if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
3191
+ return "dark";
3192
+ }
3193
+ return "light";
3194
+ }
3195
+ const ThemeContext = createContext(void 0);
3196
+ function ThemeProvider({ children }) {
3197
+ const [theme, setThemeState] = useState(() => getInitialTheme());
3198
+ const setTheme = (newTheme) => {
3199
+ setThemeState(newTheme);
3200
+ localStorage.setItem(THEME_STORAGE_KEY, newTheme);
3201
+ };
3202
+ useEffect(() => {
3203
+ document.documentElement.removeAttribute("data-color-mode");
3204
+ document.documentElement.removeAttribute("data-theme");
3205
+ document.documentElement.setAttribute("data-color-mode", theme);
3206
+ }, [theme]);
3207
+ useEffect(() => {
3208
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
3209
+ const handleChange = (e) => {
3210
+ const storedTheme = localStorage.getItem(THEME_STORAGE_KEY);
3211
+ if (!storedTheme) {
3212
+ setThemeState(e.matches ? "dark" : "light");
3213
+ }
3214
+ };
3215
+ mediaQuery.addEventListener("change", handleChange);
3216
+ return () => mediaQuery.removeEventListener("change", handleChange);
3217
+ }, []);
3218
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { theme, setTheme }, children });
3219
+ }
3220
+ function useTheme() {
3221
+ const context2 = useContext(ThemeContext);
3222
+ if (context2 === void 0) {
3223
+ throw new Error("useTheme must be used within a ThemeProvider");
3224
+ }
3225
+ return context2;
3226
+ }
3227
+ const themeSwitchStyles = css({
3228
+ position: "relative",
3229
+ borderWidth: "2",
3230
+ borderStyle: "solid",
3231
+ borderColor: "border",
3232
+ color: "transparent",
3233
+ margin: "8",
3234
+ borderRadius: "100",
3235
+ cursor: "pointer",
3236
+ display: "grid",
3237
+ lineHeight: "none",
3238
+ width: "14",
3239
+ height: "14",
3240
+ transition: "all",
3241
+ "&:before": {
3242
+ content: '""',
3243
+ position: "absolute",
3244
+ inset: "0",
3245
+ opacity: 0,
3246
+ display: "block",
3247
+ borderRadius: "100",
3248
+ bg: "bg.neutral.bold",
3249
+ transition: "all",
3250
+ transitionTimingFunction: "default",
3251
+ transitionDuration: "normal"
3252
+ },
3253
+ _hover: {
3254
+ cursor: "pointer",
3255
+ bg: { base: "darkNeutral.0", _dark: "neutral.0" },
3256
+ borderColor: "bg.neutral.bold",
3257
+ "&:before": {
3258
+ inset: "-8",
3259
+ bg: { base: "darkNeutral.0", _dark: "neutral.0" },
3260
+ opacity: 0.25
3261
+ }
3262
+ }
3263
+ });
3264
+ function ThemeSwitcher() {
3265
+ const { theme, setTheme } = useTheme();
3266
+ const toggleTheme = () => {
3267
+ setTheme(theme === "light" ? "dark" : "light");
3268
+ };
3269
+ return /* @__PURE__ */ jsx(
3270
+ "button",
3271
+ {
3272
+ className: themeSwitchStyles,
3273
+ onClick: toggleTheme,
3274
+ "aria-label": `Switch to ${theme === "light" ? "dark" : "light"} theme`,
3275
+ children: /* @__PURE__ */ jsx("span", {})
3276
+ }
3277
+ );
3278
+ }
3279
+ function useMediaQuery(breakpoint, direction = "min") {
3280
+ const query = useMemo(() => {
3281
+ const breakpointValue = breakpoints[breakpoint];
3282
+ const breakpointNum = parseInt(breakpointValue, 10);
3283
+ return direction === "min" ? `(min-width: ${breakpointValue})` : `(max-width: ${breakpointNum - 1}px)`;
3284
+ }, [breakpoint, direction]);
3285
+ const mediaQuery = useMemo(() => {
3286
+ if (typeof window === "undefined") {
3287
+ return {
3288
+ matches: false,
3289
+ addEventListener: () => {
3290
+ },
3291
+ removeEventListener: () => {
3292
+ }
3293
+ };
3294
+ }
3295
+ return window.matchMedia(query);
3296
+ }, [query]);
3297
+ return useSyncExternalStore(
3298
+ (callback) => {
3299
+ mediaQuery.addEventListener("change", callback);
3300
+ return () => {
3301
+ mediaQuery.removeEventListener("change", callback);
3302
+ };
3303
+ },
3304
+ () => mediaQuery.matches,
3305
+ // SSR fallback - return false on server
3306
+ () => false
3307
+ );
3308
+ }
3309
+ function useContainerQuery(containerRef, size, direction = "min") {
3310
+ const query = useMemo(() => {
3311
+ const sizeValue = containerSizes[size].value;
3312
+ const sizeNum = parseFloat(sizeValue);
3313
+ return direction === "min" ? `(min-width: ${sizeValue})` : `(max-width: ${sizeNum - 0.0625}rem)`;
3314
+ }, [size, direction]);
3315
+ return useSyncExternalStore(
3316
+ (callback) => {
3317
+ if (typeof window === "undefined" || !containerRef.current) {
3318
+ return () => {
3319
+ };
3320
+ }
3321
+ const element = containerRef.current;
3322
+ const sizeValue = containerSizes[size].value;
3323
+ const sizeNum = parseFloat(sizeValue);
3324
+ const threshold = direction === "min" ? sizeNum : sizeNum - 0.0625;
3325
+ const checkSize = () => {
3326
+ if (!element) return false;
3327
+ const width = element.offsetWidth;
3328
+ const widthInRem = width / parseFloat(getComputedStyle(document.documentElement).fontSize);
3329
+ return direction === "min" ? widthInRem >= threshold : widthInRem < threshold;
3330
+ };
3331
+ if ("queryContainer" in element) {
3332
+ try {
3333
+ const containerQuery = element.queryContainer(query);
3334
+ containerQuery.addEventListener("change", callback);
3335
+ return () => {
3336
+ containerQuery.removeEventListener("change", callback);
3337
+ };
3338
+ } catch {
3339
+ }
3340
+ }
3341
+ let currentMatches = checkSize();
3342
+ const callbacks = /* @__PURE__ */ new Set();
3343
+ let observer = null;
3344
+ if (typeof ResizeObserver !== "undefined") {
3345
+ observer = new ResizeObserver(() => {
3346
+ const newMatches = checkSize();
3347
+ if (newMatches !== currentMatches) {
3348
+ currentMatches = newMatches;
3349
+ callbacks.forEach((cb) => cb());
3350
+ }
3351
+ });
3352
+ observer.observe(element);
3353
+ }
3354
+ callbacks.add(callback);
3355
+ return () => {
3356
+ callbacks.delete(callback);
3357
+ if (callbacks.size === 0 && observer) {
3358
+ observer.disconnect();
3359
+ }
3360
+ };
3361
+ },
3362
+ () => {
3363
+ if (typeof window === "undefined" || !containerRef.current) {
3364
+ return false;
3365
+ }
3366
+ const element = containerRef.current;
3367
+ const sizeValue = containerSizes[size].value;
3368
+ const sizeNum = parseFloat(sizeValue);
3369
+ const threshold = direction === "min" ? sizeNum : sizeNum - 0.0625;
3370
+ if ("queryContainer" in element) {
3371
+ try {
3372
+ const containerQuery = element.queryContainer(query);
3373
+ return containerQuery.matches;
3374
+ } catch {
3375
+ }
3376
+ }
3377
+ const width = element.offsetWidth;
3378
+ const widthInRem = width / parseFloat(getComputedStyle(document.documentElement).fontSize);
3379
+ return direction === "min" ? widthInRem >= threshold : widthInRem < threshold;
3380
+ },
3381
+ // SSR fallback - return false on server
3382
+ () => false
3383
+ );
3384
+ }
3385
+ function BreakpointIndicator() {
3386
+ const isXs = useMediaQuery("xs");
3387
+ const isSm = useMediaQuery("sm");
3388
+ const isMd = useMediaQuery("md");
3389
+ const isLg = useMediaQuery("lg");
3390
+ const isXl = useMediaQuery("xl");
3391
+ const is2Xl = useMediaQuery("2xl");
3392
+ let breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "red", appearance: "bold", children: "@media/base" });
3393
+ if (is2Xl) {
3394
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "blue", appearance: "bold", children: "@media/2xl" });
3395
+ } else if (isXl) {
3396
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "teal", appearance: "bold", children: "@media/xl" });
3397
+ } else if (isLg) {
3398
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "green", appearance: "bold", children: "@media/lg" });
3399
+ } else if (isMd) {
3400
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "lime", appearance: "bold", children: "@media/md" });
3401
+ } else if (isSm) {
3402
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "yellow", appearance: "bold", children: "@media/sm" });
3403
+ } else if (isXs) {
3404
+ breakpoint = /* @__PURE__ */ jsx(Tag, { hue: "orange", appearance: "bold", children: "@media/xs" });
3405
+ }
3406
+ return breakpoint;
3407
+ }
3233
3408
  export {
3234
3409
  Badge,
3235
3410
  Box,
3236
3411
  Breadcrumbs,
3412
+ BreakpointIndicator,
3237
3413
  Button,
3238
3414
  Card,
3239
3415
  Checkbox,
3240
3416
  CheckboxInput,
3417
+ Code,
3241
3418
  Divider,
3242
3419
  Heading,
3243
3420
  Icon,
@@ -3260,6 +3437,8 @@ export {
3260
3437
  ToggleInput,
3261
3438
  Tooltip,
3262
3439
  splitProps,
3440
+ useContainerQuery,
3441
+ useMediaQuery,
3263
3442
  useTheme
3264
3443
  };
3265
3444
  //# sourceMappingURL=index.js.map