@neoptocom/neopto-ui 0.6.2 → 0.7.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/README.md CHANGED
@@ -98,6 +98,19 @@ This library uses **Tailwind CSS v4** utility classes directly in components (e.
98
98
 
99
99
  ## 🧩 Components
100
100
 
101
+ ### AppBackground
102
+
103
+ ```tsx
104
+ import { AppBackground } from "@neoptocom/neopto-ui";
105
+
106
+ <AppBackground
107
+ lightImage="/path/to/light-bg.jpg"
108
+ darkImage="/path/to/dark-bg.jpg"
109
+ >
110
+ <YourApp />
111
+ </AppBackground>;
112
+ ```
113
+
101
114
  ### Button
102
115
 
103
116
  ```tsx
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var React2 = require('react');
4
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var React2 = require('react');
5
5
  var reactDom = require('react-dom');
6
6
 
7
7
  function _interopNamespace(e) {
@@ -24,7 +24,51 @@ function _interopNamespace(e) {
24
24
 
25
25
  var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
26
26
 
27
- // src/components/Input.tsx
27
+ // src/components/AppBackground.tsx
28
+ function AppBackground({
29
+ children,
30
+ lightImage,
31
+ darkImage,
32
+ className = ""
33
+ }) {
34
+ const hasImages = lightImage || darkImage;
35
+ const baseClasses = "min-h-screen transition-colors";
36
+ const gradientClasses = !hasImages ? "bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800" : "";
37
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
38
+ lightImage && /* @__PURE__ */ jsxRuntime.jsx(
39
+ "div",
40
+ {
41
+ className: "fixed inset-0 -z-10 dark:hidden",
42
+ style: {
43
+ backgroundImage: `url(${lightImage})`,
44
+ backgroundSize: "cover",
45
+ backgroundPosition: "center",
46
+ backgroundRepeat: "no-repeat"
47
+ }
48
+ }
49
+ ),
50
+ darkImage && /* @__PURE__ */ jsxRuntime.jsx(
51
+ "div",
52
+ {
53
+ className: "fixed inset-0 -z-10 hidden dark:block",
54
+ style: {
55
+ backgroundImage: `url(${darkImage})`,
56
+ backgroundSize: "cover",
57
+ backgroundPosition: "center",
58
+ backgroundRepeat: "no-repeat"
59
+ }
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsxRuntime.jsx(
63
+ "div",
64
+ {
65
+ className: [baseClasses, gradientClasses, className].filter(Boolean).join(" "),
66
+ style: hasImages ? {} : void 0,
67
+ children
68
+ }
69
+ )
70
+ ] });
71
+ }
28
72
  var Input = React2__namespace.forwardRef(
29
73
  ({ className, disabled, ...props }, ref) => {
30
74
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1057,6 +1101,7 @@ var ChatButton_default = ChatButton;
1057
1101
 
1058
1102
  exports.AnimatedBgCircle = AnimatedBgCircle_default;
1059
1103
  exports.AnimatedBgRectangle = AnimatedBgRectangle_default;
1104
+ exports.AppBackground = AppBackground;
1060
1105
  exports.Autocomplete = Autocomplete;
1061
1106
  exports.Avatar = Avatar;
1062
1107
  exports.AvatarGroup = AvatarGroup;
package/dist/index.d.cts CHANGED
@@ -1,5 +1,17 @@
1
- import * as React from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type AppBackgroundProps = {
5
+ /** Content to render inside the background */
6
+ children: React.ReactNode;
7
+ /** Background image URL for light mode */
8
+ lightImage?: string;
9
+ /** Background image URL for dark mode */
10
+ darkImage?: string;
11
+ /** Additional CSS classes */
12
+ className?: string;
13
+ };
14
+ declare function AppBackground({ children, lightImage, darkImage, className, }: AppBackgroundProps): react_jsx_runtime.JSX.Element;
3
15
 
4
16
  type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>;
5
17
  declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
@@ -230,4 +242,4 @@ interface AnimatedBgRectangleProps {
230
242
  }
231
243
  declare const AnimatedBgRectangle: ({ colors, delay }: AnimatedBgRectangleProps) => react_jsx_runtime.JSX.Element;
232
244
 
233
- export { AnimatedBgCircle, AnimatedBgRectangle, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight };
245
+ export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,17 @@
1
- import * as React from 'react';
2
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ type AppBackgroundProps = {
5
+ /** Content to render inside the background */
6
+ children: React.ReactNode;
7
+ /** Background image URL for light mode */
8
+ lightImage?: string;
9
+ /** Background image URL for dark mode */
10
+ darkImage?: string;
11
+ /** Additional CSS classes */
12
+ className?: string;
13
+ };
14
+ declare function AppBackground({ children, lightImage, darkImage, className, }: AppBackgroundProps): react_jsx_runtime.JSX.Element;
3
15
 
4
16
  type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>;
5
17
  declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
@@ -230,4 +242,4 @@ interface AnimatedBgRectangleProps {
230
242
  }
231
243
  declare const AnimatedBgRectangle: ({ colors, delay }: AnimatedBgRectangleProps) => react_jsx_runtime.JSX.Element;
232
244
 
233
- export { AnimatedBgCircle, AnimatedBgRectangle, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight };
245
+ export { AnimatedBgCircle, AnimatedBgRectangle, AppBackground, type AppBackgroundProps, Autocomplete, type AutocompleteOption, type AutocompleteProps, Avatar, AvatarGroup, type AvatarGroupProps, type AvatarProps, Button, type ButtonProps, ChatButton, type ChatButtonProps, Chip, type ChipProps, Counter, type CounterProps, Icon, IconButton, type IconButtonProps, type IconProps, Input, type InputProps, Modal, type ModalProps, Search, type SearchOption, type SearchProps, Skeleton, type SkeletonProps, Typo, type TypoProps, type TypoVariant, type TypoWeight };
package/dist/index.js CHANGED
@@ -1,9 +1,53 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
1
2
  import * as React2 from 'react';
2
3
  import { useState, useMemo, useId, useRef, useCallback, useEffect } from 'react';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
4
  import { createPortal } from 'react-dom';
5
5
 
6
- // src/components/Input.tsx
6
+ // src/components/AppBackground.tsx
7
+ function AppBackground({
8
+ children,
9
+ lightImage,
10
+ darkImage,
11
+ className = ""
12
+ }) {
13
+ const hasImages = lightImage || darkImage;
14
+ const baseClasses = "min-h-screen transition-colors";
15
+ const gradientClasses = !hasImages ? "bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800" : "";
16
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
17
+ lightImage && /* @__PURE__ */ jsx(
18
+ "div",
19
+ {
20
+ className: "fixed inset-0 -z-10 dark:hidden",
21
+ style: {
22
+ backgroundImage: `url(${lightImage})`,
23
+ backgroundSize: "cover",
24
+ backgroundPosition: "center",
25
+ backgroundRepeat: "no-repeat"
26
+ }
27
+ }
28
+ ),
29
+ darkImage && /* @__PURE__ */ jsx(
30
+ "div",
31
+ {
32
+ className: "fixed inset-0 -z-10 hidden dark:block",
33
+ style: {
34
+ backgroundImage: `url(${darkImage})`,
35
+ backgroundSize: "cover",
36
+ backgroundPosition: "center",
37
+ backgroundRepeat: "no-repeat"
38
+ }
39
+ }
40
+ ),
41
+ /* @__PURE__ */ jsx(
42
+ "div",
43
+ {
44
+ className: [baseClasses, gradientClasses, className].filter(Boolean).join(" "),
45
+ style: hasImages ? {} : void 0,
46
+ children
47
+ }
48
+ )
49
+ ] });
50
+ }
7
51
  var Input = React2.forwardRef(
8
52
  ({ className, disabled, ...props }, ref) => {
9
53
  return /* @__PURE__ */ jsx(
@@ -1034,4 +1078,4 @@ var ChatButton = ({
1034
1078
  };
1035
1079
  var ChatButton_default = ChatButton;
1036
1080
 
1037
- export { AnimatedBgCircle_default as AnimatedBgCircle, AnimatedBgRectangle_default as AnimatedBgRectangle, Autocomplete, Avatar, AvatarGroup, Button, ChatButton_default as ChatButton, Chip, Counter, Icon, IconButton, Input, Modal, Search, Skeleton, Typo };
1081
+ export { AnimatedBgCircle_default as AnimatedBgCircle, AnimatedBgRectangle_default as AnimatedBgRectangle, AppBackground, Autocomplete, Avatar, AvatarGroup, Button, ChatButton_default as ChatButton, Chip, Counter, Icon, IconButton, Input, Modal, Search, Skeleton, Typo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neoptocom/neopto-ui",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "description": "A modern React component library built with Tailwind CSS v4 and TypeScript. Features dark mode, design tokens, and comprehensive Storybook documentation. Requires Tailwind v4+.",
6
6
  "keywords": [
@@ -0,0 +1,81 @@
1
+ import * as React from "react";
2
+
3
+ export type AppBackgroundProps = {
4
+ /** Content to render inside the background */
5
+ children: React.ReactNode;
6
+ /** Background image URL for light mode */
7
+ lightImage?: string;
8
+ /** Background image URL for dark mode */
9
+ darkImage?: string;
10
+ /** Additional CSS classes */
11
+ className?: string;
12
+ };
13
+
14
+ export function AppBackground({
15
+ children,
16
+ lightImage,
17
+ darkImage,
18
+ className = "",
19
+ }: AppBackgroundProps) {
20
+ const hasImages = lightImage || darkImage;
21
+
22
+ // Base classes
23
+ const baseClasses = "min-h-screen transition-colors";
24
+
25
+ // Gradient fallback when no images provided
26
+ const gradientClasses = !hasImages
27
+ ? "bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800"
28
+ : "";
29
+
30
+ // Background image styles
31
+ const getBackgroundStyle = (): React.CSSProperties => {
32
+ if (!hasImages) return {};
33
+
34
+ return {
35
+ backgroundSize: "cover",
36
+ backgroundPosition: "center",
37
+ backgroundRepeat: "no-repeat",
38
+ };
39
+ };
40
+
41
+ return (
42
+ <>
43
+ {/* Light mode background image */}
44
+ {lightImage && (
45
+ <div
46
+ className="fixed inset-0 -z-10 dark:hidden"
47
+ style={{
48
+ backgroundImage: `url(${lightImage})`,
49
+ backgroundSize: "cover",
50
+ backgroundPosition: "center",
51
+ backgroundRepeat: "no-repeat",
52
+ }}
53
+ />
54
+ )}
55
+
56
+ {/* Dark mode background image */}
57
+ {darkImage && (
58
+ <div
59
+ className="fixed inset-0 -z-10 hidden dark:block"
60
+ style={{
61
+ backgroundImage: `url(${darkImage})`,
62
+ backgroundSize: "cover",
63
+ backgroundPosition: "center",
64
+ backgroundRepeat: "no-repeat",
65
+ }}
66
+ />
67
+ )}
68
+
69
+ {/* Content container */}
70
+ <div
71
+ className={[baseClasses, gradientClasses, className]
72
+ .filter(Boolean)
73
+ .join(" ")}
74
+ style={hasImages ? {} : undefined}
75
+ >
76
+ {children}
77
+ </div>
78
+ </>
79
+ );
80
+ }
81
+
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  // Components
2
+ export { AppBackground } from "./components/AppBackground";
2
3
  export * from "./components/Input";
3
4
  export * from "./components/Modal";
4
5
  export { default as Typo } from "./components/Typo";
@@ -15,6 +16,7 @@ export { default as Counter } from "./components/Counter";
15
16
  export * from "./components/Chat";
16
17
 
17
18
  // Types
19
+ export type { AppBackgroundProps } from "./components/AppBackground";
18
20
  export type { InputProps } from "./components/Input";
19
21
  export type { ModalProps } from "./components/Modal";
20
22
  export type { TypoProps, TypoVariant, TypoWeight } from "./components/Typo";
@@ -0,0 +1,106 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { AppBackground } from "../components/AppBackground";
3
+ import Typo from "../components/Typo";
4
+ import { Button } from "../components/Button";
5
+
6
+ const meta = {
7
+ title: "Components/AppBackground",
8
+ component: AppBackground,
9
+ parameters: {
10
+ layout: "fullscreen",
11
+ },
12
+ tags: ["autodocs"],
13
+ } satisfies Meta<typeof AppBackground>;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ export const Default: Story = {
19
+ args: {
20
+ children: (
21
+ <div className="p-8">
22
+ <Typo variant="headline-lg" bold="bold" className="mb-4">
23
+ Default Gradient Background
24
+ </Typo>
25
+ <Typo variant="body-md" className="mb-4">
26
+ This background automatically switches between light and dark gradients based on the theme.
27
+ </Typo>
28
+ <Button variant="primary">Click Me</Button>
29
+ </div>
30
+ ),
31
+ },
32
+ };
33
+
34
+ export const WithLightImage: Story = {
35
+ args: {
36
+ lightImage: "https://images.unsplash.com/photo-1557683316-973673baf926?w=1920&q=80",
37
+ children: (
38
+ <div className="p-8">
39
+ <Typo variant="headline-lg" bold="bold" className="mb-4 text-white">
40
+ With Light Mode Image
41
+ </Typo>
42
+ <Typo variant="body-md" className="mb-4 text-white">
43
+ Custom background image for light mode. Switch to dark mode to see the gradient fallback.
44
+ </Typo>
45
+ <Button variant="primary">Click Me</Button>
46
+ </div>
47
+ ),
48
+ },
49
+ };
50
+
51
+ export const WithDarkImage: Story = {
52
+ args: {
53
+ darkImage: "https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920&q=80",
54
+ children: (
55
+ <div className="p-8">
56
+ <Typo variant="headline-lg" bold="bold" className="mb-4">
57
+ With Dark Mode Image
58
+ </Typo>
59
+ <Typo variant="body-md" className="mb-4">
60
+ Custom background image for dark mode. Switch to light mode to see the gradient fallback.
61
+ </Typo>
62
+ <Button variant="primary">Click Me</Button>
63
+ </div>
64
+ ),
65
+ },
66
+ };
67
+
68
+ export const WithBothImages: Story = {
69
+ args: {
70
+ lightImage: "https://images.unsplash.com/photo-1557683316-973673baf926?w=1920&q=80",
71
+ darkImage: "https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920&q=80",
72
+ children: (
73
+ <div className="p-8">
74
+ <Typo variant="headline-lg" bold="bold" className="mb-4">
75
+ Different Images per Theme
76
+ </Typo>
77
+ <Typo variant="body-md" className="mb-4">
78
+ This example has different background images for light and dark modes. Toggle the theme to see the difference!
79
+ </Typo>
80
+ <Button variant="primary">Click Me</Button>
81
+ </div>
82
+ ),
83
+ },
84
+ };
85
+
86
+ export const FullPageExample: Story = {
87
+ args: {
88
+ children: (
89
+ <div className="flex min-h-screen items-center justify-center">
90
+ <div className="max-w-2xl rounded-lg bg-white/80 dark:bg-slate-900/80 p-8 backdrop-blur-sm shadow-xl">
91
+ <Typo variant="headline-lg" bold="bold" className="mb-4">
92
+ Welcome to NeoPTO
93
+ </Typo>
94
+ <Typo variant="body-md" className="mb-6 text-text-secondary">
95
+ This is an example of a full-page layout with AppBackground. The background automatically adjusts to your theme preference.
96
+ </Typo>
97
+ <div className="flex gap-4">
98
+ <Button variant="primary">Get Started</Button>
99
+ <Button variant="secondary">Learn More</Button>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ ),
104
+ },
105
+ };
106
+