@sqlrooms/ui 0.4.0 → 0.4.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.
@@ -1,5 +1,39 @@
1
1
  import { FC } from 'react';
2
+ /**
3
+ * A theme toggle switch component that allows users to switch between light and dark themes.
4
+ *
5
+ * This component provides a visually appealing switch with sun/moon icons that animate smoothly
6
+ * during theme transitions. It integrates with the theme context to manage theme state.
7
+ *
8
+ * Features:
9
+ * - Smooth icon animations
10
+ * - Accessible keyboard navigation
11
+ * - Focus and hover states
12
+ * - Customizable via className prop
13
+ *
14
+ * @component
15
+ * @example
16
+ * ```tsx
17
+ * // Basic usage
18
+ * <ThemeSwitch />
19
+ *
20
+ * // With custom styling
21
+ * <ThemeSwitch className="my-custom-class" />
22
+ *
23
+ * // Within a theme provider
24
+ * import { ThemeProvider } from '../theme/theme-provider';
25
+ *
26
+ * function App() {
27
+ * return (
28
+ * <ThemeProvider>
29
+ * <ThemeSwitch />
30
+ * </ThemeProvider>
31
+ * );
32
+ * }
33
+ * ```
34
+ */
2
35
  export declare const ThemeSwitch: FC<{
36
+ /** Optional CSS class name for styling the switch container */
3
37
  className?: string;
4
38
  }>;
5
39
  //# sourceMappingURL=theme-switch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-switch.d.ts","sourceRoot":"","sources":["../../src/components/theme-switch.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAEzB,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAC,CAwBhD,CAAC"}
1
+ {"version":3,"file":"theme-switch.d.ts","sourceRoot":"","sources":["../../src/components/theme-switch.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC;IAC3B,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAwBA,CAAC"}
@@ -3,6 +3,39 @@ import { useTheme } from '../theme/theme-provider';
3
3
  import * as SwitchPrimitives from '@radix-ui/react-switch';
4
4
  import { SunIcon, MoonIcon } from 'lucide-react';
5
5
  import { cn } from '../lib/utils';
6
+ /**
7
+ * A theme toggle switch component that allows users to switch between light and dark themes.
8
+ *
9
+ * This component provides a visually appealing switch with sun/moon icons that animate smoothly
10
+ * during theme transitions. It integrates with the theme context to manage theme state.
11
+ *
12
+ * Features:
13
+ * - Smooth icon animations
14
+ * - Accessible keyboard navigation
15
+ * - Focus and hover states
16
+ * - Customizable via className prop
17
+ *
18
+ * @component
19
+ * @example
20
+ * ```tsx
21
+ * // Basic usage
22
+ * <ThemeSwitch />
23
+ *
24
+ * // With custom styling
25
+ * <ThemeSwitch className="my-custom-class" />
26
+ *
27
+ * // Within a theme provider
28
+ * import { ThemeProvider } from '../theme/theme-provider';
29
+ *
30
+ * function App() {
31
+ * return (
32
+ * <ThemeProvider>
33
+ * <ThemeSwitch />
34
+ * </ThemeProvider>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
6
39
  export const ThemeSwitch = ({ className }) => {
7
40
  const { theme, setTheme } = useTheme();
8
41
  return (_jsx(SwitchPrimitives.Root, { className: cn('peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary/20 data-[state=unchecked]:bg-input', className), checked: theme === 'dark', onCheckedChange: (checked) => {
@@ -1 +1 @@
1
- {"version":3,"file":"theme-switch.js","sourceRoot":"","sources":["../../src/components/theme-switch.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AACjD,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAGhC,MAAM,CAAC,MAAM,WAAW,GAA6B,CAAC,EAAC,SAAS,EAAC,EAAE,EAAE;IACnE,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAC,GAAG,QAAQ,EAAE,CAAC;IAErC,OAAO,CACL,KAAC,gBAAgB,CAAC,IAAI,IACpB,SAAS,EAAE,EAAE,CACX,gYAAgY,EAChY,SAAS,CACV,EACD,OAAO,EAAE,KAAK,KAAK,MAAM,EACzB,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;YAC3B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,YAED,MAAC,gBAAgB,CAAC,KAAK,IACrB,SAAS,EAAE,EAAE,CACX,wNAAwN,CACzN,aAED,KAAC,OAAO,IAAC,SAAS,EAAC,8FAA8F,GAAG,EACpH,KAAC,QAAQ,IAAC,SAAS,EAAC,sGAAsG,GAAG,IACtG,GACH,CACzB,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"theme-switch.js","sourceRoot":"","sources":["../../src/components/theme-switch.tsx"],"names":[],"mappings":";AACA,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAC;AACjD,OAAO,KAAK,gBAAgB,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAGhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,WAAW,GAGnB,CAAC,EAAC,SAAS,EAAC,EAAE,EAAE;IACnB,MAAM,EAAC,KAAK,EAAE,QAAQ,EAAC,GAAG,QAAQ,EAAE,CAAC;IAErC,OAAO,CACL,KAAC,gBAAgB,CAAC,IAAI,IACpB,SAAS,EAAE,EAAE,CACX,gYAAgY,EAChY,SAAS,CACV,EACD,OAAO,EAAE,KAAK,KAAK,MAAM,EACzB,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;YAC3B,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,YAED,MAAC,gBAAgB,CAAC,KAAK,IACrB,SAAS,EAAE,EAAE,CACX,wNAAwN,CACzN,aAED,KAAC,OAAO,IAAC,SAAS,EAAC,8FAA8F,GAAG,EACpH,KAAC,QAAQ,IAAC,SAAS,EAAC,sGAAsG,GAAG,IACtG,GACH,CACzB,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Represents the dimensions of an element
3
+ * @interface Dimensions
4
+ * @property {number} width - The width in pixels
5
+ * @property {number} height - The height in pixels
6
+ */
7
+ export interface Dimensions {
8
+ width: number;
9
+ height: number;
10
+ }
11
+ /**
12
+ * Props for the useAspectRatioDimensions hook
13
+ * @interface UseAspectRatioDimensionsProps
14
+ * @property {number | 'auto'} width - The explicitly provided width, or 'auto' for container-based width
15
+ * @property {number | 'auto'} height - The explicitly provided height, or 'auto' for aspect ratio-based height
16
+ * @property {number} aspectRatio - The desired width-to-height ratio when dimensions are auto-calculated
17
+ * @property {React.RefObject<HTMLElement>} containerRef - Reference to the container element
18
+ */
19
+ export interface UseAspectRatioDimensionsProps {
20
+ width: number | 'auto';
21
+ height: number | 'auto';
22
+ aspectRatio: number;
23
+ containerRef: React.RefObject<HTMLElement>;
24
+ }
25
+ /**
26
+ * A hook that calculates element dimensions based on provided values and container size
27
+ *
28
+ * This hook handles various combinations of width/height specifications:
29
+ * - If both width and height are provided, uses those exact dimensions
30
+ * - If only width is provided, calculates height using the aspect ratio
31
+ * - If only height is provided, calculates width using the aspect ratio
32
+ * - If both are 'auto', uses container width and calculates height using the aspect ratio
33
+ *
34
+ * @param {UseAspectRatioDimensionsProps} props - The input parameters for dimension calculation
35
+ * @returns {Dimensions} The calculated width and height
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * const containerRef = useRef<HTMLDivElement>(null);
40
+ * const {width, height} = useAspectRatioDimensions({
41
+ * width: 'auto',
42
+ * height: 'auto',
43
+ * aspectRatio: 16/9,
44
+ * containerRef
45
+ * });
46
+ * // Returns dimensions based on container size
47
+ * ```
48
+ */
49
+ export declare function useAspectRatioDimensions({ width, height, aspectRatio, containerRef, }: UseAspectRatioDimensionsProps): Dimensions;
50
+ //# sourceMappingURL=useAspectRatioDimensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAspectRatioDimensions.d.ts","sourceRoot":"","sources":["../../src/hooks/useAspectRatioDimensions.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,KAAK,EACL,MAAM,EACN,WAAW,EACX,YAAY,GACb,EAAE,6BAA6B,GAAG,UAAU,CAoB5C"}
@@ -0,0 +1,47 @@
1
+ import { useMemo } from 'react';
2
+ import { useResizeObserver } from 'usehooks-ts';
3
+ /**
4
+ * A hook that calculates element dimensions based on provided values and container size
5
+ *
6
+ * This hook handles various combinations of width/height specifications:
7
+ * - If both width and height are provided, uses those exact dimensions
8
+ * - If only width is provided, calculates height using the aspect ratio
9
+ * - If only height is provided, calculates width using the aspect ratio
10
+ * - If both are 'auto', uses container width and calculates height using the aspect ratio
11
+ *
12
+ * @param {UseAspectRatioDimensionsProps} props - The input parameters for dimension calculation
13
+ * @returns {Dimensions} The calculated width and height
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * const containerRef = useRef<HTMLDivElement>(null);
18
+ * const {width, height} = useAspectRatioDimensions({
19
+ * width: 'auto',
20
+ * height: 'auto',
21
+ * aspectRatio: 16/9,
22
+ * containerRef
23
+ * });
24
+ * // Returns dimensions based on container size
25
+ * ```
26
+ */
27
+ export function useAspectRatioDimensions({ width, height, aspectRatio, containerRef, }) {
28
+ const { width: containerWidth = 0 } = useResizeObserver({
29
+ ref: containerRef,
30
+ box: 'border-box',
31
+ });
32
+ return useMemo(() => {
33
+ if (width !== 'auto' && height !== 'auto') {
34
+ return { width, height };
35
+ }
36
+ if (width !== 'auto') {
37
+ return { width, height: width / aspectRatio };
38
+ }
39
+ if (height !== 'auto') {
40
+ return { width: height * aspectRatio, height };
41
+ }
42
+ const finalWidth = containerWidth;
43
+ const finalHeight = finalWidth / aspectRatio;
44
+ return { width: finalWidth, height: finalHeight };
45
+ }, [containerWidth, aspectRatio, width, height]);
46
+ }
47
+ //# sourceMappingURL=useAspectRatioDimensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAspectRatioDimensions.js","sourceRoot":"","sources":["../../src/hooks/useAspectRatioDimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAC,iBAAiB,EAAC,MAAM,aAAa,CAAC;AA4B9C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,wBAAwB,CAAC,EACvC,KAAK,EACL,MAAM,EACN,WAAW,EACX,YAAY,GACkB;IAC9B,MAAM,EAAC,KAAK,EAAE,cAAc,GAAG,CAAC,EAAC,GAAG,iBAAiB,CAAC;QACpD,GAAG,EAAE,YAAY;QACjB,GAAG,EAAE,YAAY;KAClB,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,KAAK,KAAK,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1C,OAAO,EAAC,KAAK,EAAE,MAAM,EAAC,CAAC;QACzB,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,OAAO,EAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,WAAW,EAAC,CAAC;QAC9C,CAAC;QACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,EAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,MAAM,EAAC,CAAC;QAC/C,CAAC;QACD,MAAM,UAAU,GAAG,cAAc,CAAC;QAClC,MAAM,WAAW,GAAG,UAAU,GAAG,WAAW,CAAC;QAC7C,OAAO,EAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAC,CAAC;IAClD,CAAC,EAAE,CAAC,cAAc,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AACnD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -32,6 +32,7 @@ export * from './components/toaster';
32
32
  export * from './components/tooltip';
33
33
  export * from './hooks/use-toast';
34
34
  export * from './hooks/useDisclosure';
35
+ export * from './hooks/useAspectRatioDimensions';
35
36
  export * from './lib/utils';
36
37
  export * from './tailwind-preset';
37
38
  export * from './theme/theme-provider';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -32,6 +32,7 @@ export * from './components/toaster';
32
32
  export * from './components/tooltip';
33
33
  export * from './hooks/use-toast';
34
34
  export * from './hooks/useDisclosure';
35
+ export * from './hooks/useAspectRatioDimensions';
35
36
  export * from './lib/utils';
36
37
  export * from './tailwind-preset';
37
38
  export * from './theme/theme-provider';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
@@ -1,14 +1,100 @@
1
+ /**
2
+ * Available theme options
3
+ * @typedef {'dark' | 'light' | 'system'} Theme
4
+ */
1
5
  type Theme = 'dark' | 'light' | 'system';
6
+ /**
7
+ * Props for the ThemeProvider component
8
+ * @interface ThemeProviderProps
9
+ * @property {React.ReactNode} children - Child components that will have access to the theme context
10
+ * @property {Theme} [defaultTheme='system'] - Initial theme to use if none is stored
11
+ * @property {string} [storageKey='sqlrooms-ui-theme'] - Local storage key to persist theme preference
12
+ */
2
13
  type ThemeProviderProps = {
3
14
  children: React.ReactNode;
4
15
  defaultTheme?: Theme;
5
16
  storageKey?: string;
6
17
  };
18
+ /**
19
+ * Theme context state
20
+ * @interface ThemeProviderState
21
+ * @property {Theme} theme - Current active theme
22
+ * @property {(theme: Theme) => void} setTheme - Function to update the current theme
23
+ */
7
24
  type ThemeProviderState = {
8
25
  theme: Theme;
9
26
  setTheme: (theme: Theme) => void;
10
27
  };
28
+ /**
29
+ * ThemeProvider component that manages and provides theme context to its children.
30
+ * Handles system theme detection and persistence of theme preference.
31
+ *
32
+ * @example
33
+ * ```tsx
34
+ * // Basic usage with default settings
35
+ * function App() {
36
+ * return (
37
+ * <ThemeProvider>
38
+ * <YourApp />
39
+ * </ThemeProvider>
40
+ * );
41
+ * }
42
+ *
43
+ * // Custom default theme and storage key
44
+ * function App() {
45
+ * return (
46
+ * <ThemeProvider defaultTheme="dark" storageKey="my-app-theme">
47
+ * <YourApp />
48
+ * </ThemeProvider>
49
+ * );
50
+ * }
51
+ * ```
52
+ */
11
53
  export declare function ThemeProvider({ children, defaultTheme, storageKey, ...props }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
54
+ /**
55
+ * Hook to access the current theme and theme setter function.
56
+ * Must be used within a ThemeProvider component.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * import { Button } from '@sqlrooms/ui';
61
+ *
62
+ * function ThemeToggle() {
63
+ * const { theme, setTheme } = useTheme();
64
+ * const isDark = theme === 'dark';
65
+ *
66
+ * return (
67
+ * <Button
68
+ * variant="outline"
69
+ * size="sm"
70
+ * onClick={() => setTheme(isDark ? 'light' : 'dark')}
71
+ * >
72
+ * {isDark ? '☀️ Light' : '🌙 Dark'}
73
+ * </Button>
74
+ * );
75
+ * }
76
+ * ```
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * import { ThemeSwitch } from '@sqlrooms/ui';
81
+ *
82
+ * function AppHeader() {
83
+ * return (
84
+ * <nav className="border-b">
85
+ * <div className="flex h-16 items-center px-4">
86
+ * <div className="ml-auto">
87
+ * <ThemeSwitch />
88
+ * </div>
89
+ * </div>
90
+ * </nav>
91
+ * );
92
+ * }
93
+ * ```
94
+ *
95
+ * @returns {ThemeProviderState} Object containing current theme and setTheme function
96
+ * @throws {Error} If used outside of a ThemeProvider
97
+ */
12
98
  export declare const useTheme: () => ThemeProviderState;
13
99
  export {};
14
100
  //# sourceMappingURL=theme-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/theme/theme-provider.tsx"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzC,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,CAAC;AASF,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAuB,EACvB,UAAgC,EAChC,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAoCpB;AAED,eAAO,MAAM,QAAQ,0BAOpB,CAAC"}
1
+ {"version":3,"file":"theme-provider.d.ts","sourceRoot":"","sources":["../../src/theme/theme-provider.tsx"],"names":[],"mappings":"AAEA;;;GAGG;AACH,KAAK,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEzC;;;;;;GAMG;AACH,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC,CAAC;AASF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAuB,EACvB,UAAgC,EAChC,GAAG,KAAK,EACT,EAAE,kBAAkB,2CAoCpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,eAAO,MAAM,QAAQ,0BAOpB,CAAC"}
@@ -5,6 +5,31 @@ const initialState = {
5
5
  setTheme: () => null,
6
6
  };
7
7
  const ThemeProviderContext = createContext(initialState);
8
+ /**
9
+ * ThemeProvider component that manages and provides theme context to its children.
10
+ * Handles system theme detection and persistence of theme preference.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * // Basic usage with default settings
15
+ * function App() {
16
+ * return (
17
+ * <ThemeProvider>
18
+ * <YourApp />
19
+ * </ThemeProvider>
20
+ * );
21
+ * }
22
+ *
23
+ * // Custom default theme and storage key
24
+ * function App() {
25
+ * return (
26
+ * <ThemeProvider defaultTheme="dark" storageKey="my-app-theme">
27
+ * <YourApp />
28
+ * </ThemeProvider>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
8
33
  export function ThemeProvider({ children, defaultTheme = 'system', storageKey = 'sqlrooms-ui-theme', ...props }) {
9
34
  const [theme, setTheme] = useState(() => localStorage.getItem(storageKey) || defaultTheme);
10
35
  useEffect(() => {
@@ -29,6 +54,50 @@ export function ThemeProvider({ children, defaultTheme = 'system', storageKey =
29
54
  };
30
55
  return (_jsx(ThemeProviderContext.Provider, { ...props, value: value, children: children }));
31
56
  }
57
+ /**
58
+ * Hook to access the current theme and theme setter function.
59
+ * Must be used within a ThemeProvider component.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * import { Button } from '@sqlrooms/ui';
64
+ *
65
+ * function ThemeToggle() {
66
+ * const { theme, setTheme } = useTheme();
67
+ * const isDark = theme === 'dark';
68
+ *
69
+ * return (
70
+ * <Button
71
+ * variant="outline"
72
+ * size="sm"
73
+ * onClick={() => setTheme(isDark ? 'light' : 'dark')}
74
+ * >
75
+ * {isDark ? '☀️ Light' : '🌙 Dark'}
76
+ * </Button>
77
+ * );
78
+ * }
79
+ * ```
80
+ *
81
+ * @example
82
+ * ```tsx
83
+ * import { ThemeSwitch } from '@sqlrooms/ui';
84
+ *
85
+ * function AppHeader() {
86
+ * return (
87
+ * <nav className="border-b">
88
+ * <div className="flex h-16 items-center px-4">
89
+ * <div className="ml-auto">
90
+ * <ThemeSwitch />
91
+ * </div>
92
+ * </div>
93
+ * </nav>
94
+ * );
95
+ * }
96
+ * ```
97
+ *
98
+ * @returns {ThemeProviderState} Object containing current theme and setTheme function
99
+ * @throws {Error} If used outside of a ThemeProvider
100
+ */
32
101
  export const useTheme = () => {
33
102
  const context = useContext(ThemeProviderContext);
34
103
  if (context === undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"theme-provider.js","sourceRoot":"","sources":["../../src/theme/theme-provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAerE,MAAM,YAAY,GAAuB;IACvC,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;CACrB,CAAC;AAEF,MAAM,oBAAoB,GAAG,aAAa,CAAqB,YAAY,CAAC,CAAC;AAE7E,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAY,GAAG,QAAQ,EACvB,UAAU,GAAG,mBAAmB,EAChC,GAAG,KAAK,EACW;IACnB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAChC,GAAG,EAAE,CAAE,YAAY,CAAC,OAAO,CAAC,UAAU,CAAW,IAAI,YAAY,CAClE,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QAE7C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEvC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC;iBAClE,OAAO;gBACR,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,OAAO,CAAC;YAEZ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,QAAQ,EAAE,CAAC,KAAY,EAAE,EAAE;YACzB,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACxC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;IAEF,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,OAAK,KAAK,EAAE,KAAK,EAAE,KAAK,YACnD,QAAQ,GACqB,CACjC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAEjD,IAAI,OAAO,KAAK,SAAS;QACvB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAElE,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
1
+ {"version":3,"file":"theme-provider.js","sourceRoot":"","sources":["../../src/theme/theme-provider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAgCrE,MAAM,YAAY,GAAuB;IACvC,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI;CACrB,CAAC;AAEF,MAAM,oBAAoB,GAAG,aAAa,CAAqB,YAAY,CAAC,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,YAAY,GAAG,QAAQ,EACvB,UAAU,GAAG,mBAAmB,EAChC,GAAG,KAAK,EACW;IACnB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAChC,GAAG,EAAE,CAAE,YAAY,CAAC,OAAO,CAAC,UAAU,CAAW,IAAI,YAAY,CAClE,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QAE7C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEvC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,8BAA8B,CAAC;iBAClE,OAAO;gBACR,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,OAAO,CAAC;YAEZ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,MAAM,KAAK,GAAG;QACZ,KAAK;QACL,QAAQ,EAAE,CAAC,KAAY,EAAE,EAAE;YACzB,YAAY,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACxC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;IAEF,OAAO,CACL,KAAC,oBAAoB,CAAC,QAAQ,OAAK,KAAK,EAAE,KAAK,EAAE,KAAK,YACnD,QAAQ,GACqB,CACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IAEjD,IAAI,OAAO,KAAK,SAAS;QACvB,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAElE,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/ui",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "Ilya Boyandin <ilya@boyandin.me>",
@@ -54,11 +54,12 @@
54
54
  "react-resizable-panels": "^2.1.7",
55
55
  "tailwind-merge": "^2.6.0",
56
56
  "tailwindcss-animate": "^1.0.7",
57
+ "usehooks-ts": "^3.1.1",
57
58
  "zod": "^3.24.1"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "autoprefixer": "^10.4.20",
61
62
  "tailwindcss": "^3.4.17"
62
63
  },
63
- "gitHead": "fbc92d77cf3a70bdbef67bb0d7cf9342ed3e81a1"
64
+ "gitHead": "4260241d97423fd1839746ebb7980d01eaffde97"
64
65
  }