naria-ui 0.1.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 ADDED
@@ -0,0 +1,36 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
Binary file
@@ -0,0 +1,42 @@
1
+ :root {
2
+ --background: #ffffff;
3
+ --foreground: #171717;
4
+ }
5
+
6
+ @media (prefers-color-scheme: dark) {
7
+ :root {
8
+ --background: #0a0a0a;
9
+ --foreground: #ededed;
10
+ }
11
+ }
12
+
13
+ html,
14
+ body {
15
+ max-width: 100vw;
16
+ overflow-x: hidden;
17
+ }
18
+
19
+ body {
20
+ color: var(--foreground);
21
+ background: var(--background);
22
+ font-family: Arial, Helvetica, sans-serif;
23
+ -webkit-font-smoothing: antialiased;
24
+ -moz-osx-font-smoothing: grayscale;
25
+ }
26
+
27
+ * {
28
+ box-sizing: border-box;
29
+ padding: 0;
30
+ margin: 0;
31
+ }
32
+
33
+ a {
34
+ color: inherit;
35
+ text-decoration: none;
36
+ }
37
+
38
+ @media (prefers-color-scheme: dark) {
39
+ html {
40
+ color-scheme: dark;
41
+ }
42
+ }
package/app/layout.tsx ADDED
@@ -0,0 +1,32 @@
1
+ import type { Metadata } from "next";
2
+ import { Geist, Geist_Mono } from "next/font/google";
3
+ import "./globals.css";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "Create Next App",
17
+ description: "Generated by create next app",
18
+ };
19
+
20
+ export default function RootLayout({
21
+ children,
22
+ }: Readonly<{
23
+ children: React.ReactNode;
24
+ }>) {
25
+ return (
26
+ <html lang="en">
27
+ <body className={`${geistSans.variable} ${geistMono.variable}`}>
28
+ {children}
29
+ </body>
30
+ </html>
31
+ );
32
+ }
@@ -0,0 +1,167 @@
1
+ .page {
2
+ --gray-rgb: 0, 0, 0;
3
+ --gray-alpha-200: rgba(var(--gray-rgb), 0.08);
4
+ --gray-alpha-100: rgba(var(--gray-rgb), 0.05);
5
+
6
+ --button-primary-hover: #383838;
7
+ --button-secondary-hover: #f2f2f2;
8
+
9
+ display: grid;
10
+ grid-template-rows: 20px 1fr 20px;
11
+ align-items: center;
12
+ justify-items: center;
13
+ min-height: 100svh;
14
+ padding: 80px;
15
+ gap: 64px;
16
+ font-family: var(--font-geist-sans);
17
+ }
18
+
19
+ @media (prefers-color-scheme: dark) {
20
+ .page {
21
+ --gray-rgb: 255, 255, 255;
22
+ --gray-alpha-200: rgba(var(--gray-rgb), 0.145);
23
+ --gray-alpha-100: rgba(var(--gray-rgb), 0.06);
24
+
25
+ --button-primary-hover: #ccc;
26
+ --button-secondary-hover: #1a1a1a;
27
+ }
28
+ }
29
+
30
+ .main {
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 32px;
34
+ grid-row-start: 2;
35
+ }
36
+
37
+ .main ol {
38
+ font-family: var(--font-geist-mono);
39
+ padding-left: 0;
40
+ margin: 0;
41
+ font-size: 14px;
42
+ line-height: 24px;
43
+ letter-spacing: -0.01em;
44
+ list-style-position: inside;
45
+ }
46
+
47
+ .main li:not(:last-of-type) {
48
+ margin-bottom: 8px;
49
+ }
50
+
51
+ .main code {
52
+ font-family: inherit;
53
+ background: var(--gray-alpha-100);
54
+ padding: 2px 4px;
55
+ border-radius: 4px;
56
+ font-weight: 600;
57
+ }
58
+
59
+ .ctas {
60
+ display: flex;
61
+ gap: 16px;
62
+ }
63
+
64
+ .ctas a {
65
+ appearance: none;
66
+ border-radius: 128px;
67
+ height: 48px;
68
+ padding: 0 20px;
69
+ border: 1px solid transparent;
70
+ transition:
71
+ background 0.2s,
72
+ color 0.2s,
73
+ border-color 0.2s;
74
+ cursor: pointer;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ font-size: 16px;
79
+ line-height: 20px;
80
+ font-weight: 500;
81
+ }
82
+
83
+ a.primary {
84
+ background: var(--foreground);
85
+ color: var(--background);
86
+ gap: 8px;
87
+ }
88
+
89
+ a.secondary {
90
+ border-color: var(--gray-alpha-200);
91
+ min-width: 158px;
92
+ }
93
+
94
+ .footer {
95
+ grid-row-start: 3;
96
+ display: flex;
97
+ gap: 24px;
98
+ }
99
+
100
+ .footer a {
101
+ display: flex;
102
+ align-items: center;
103
+ gap: 8px;
104
+ }
105
+
106
+ .footer img {
107
+ flex-shrink: 0;
108
+ }
109
+
110
+ /* Enable hover only on non-touch devices */
111
+ @media (hover: hover) and (pointer: fine) {
112
+ a.primary:hover {
113
+ background: var(--button-primary-hover);
114
+ border-color: transparent;
115
+ }
116
+
117
+ a.secondary:hover {
118
+ background: var(--button-secondary-hover);
119
+ border-color: transparent;
120
+ }
121
+
122
+ .footer a:hover {
123
+ text-decoration: underline;
124
+ text-underline-offset: 4px;
125
+ }
126
+ }
127
+
128
+ @media (max-width: 600px) {
129
+ .page {
130
+ padding: 32px;
131
+ padding-bottom: 80px;
132
+ }
133
+
134
+ .main {
135
+ align-items: center;
136
+ }
137
+
138
+ .main ol {
139
+ text-align: center;
140
+ }
141
+
142
+ .ctas {
143
+ flex-direction: column;
144
+ }
145
+
146
+ .ctas a {
147
+ font-size: 14px;
148
+ height: 40px;
149
+ padding: 0 16px;
150
+ }
151
+
152
+ a.secondary {
153
+ min-width: auto;
154
+ }
155
+
156
+ .footer {
157
+ flex-wrap: wrap;
158
+ align-items: center;
159
+ justify-content: center;
160
+ }
161
+ }
162
+
163
+ @media (prefers-color-scheme: dark) {
164
+ .logo {
165
+ filter: invert();
166
+ }
167
+ }
package/app/page.tsx ADDED
@@ -0,0 +1,95 @@
1
+ import Image from "next/image";
2
+ import styles from "./page.module.css";
3
+
4
+ export default function Home() {
5
+ return (
6
+ <div className={styles.page}>
7
+ <main className={styles.main}>
8
+ <Image
9
+ className={styles.logo}
10
+ src="/next.svg"
11
+ alt="Next.js logo"
12
+ width={180}
13
+ height={38}
14
+ priority
15
+ />
16
+ <ol>
17
+ <li>
18
+ Get started by editing <code>app/page.tsx</code>.
19
+ </li>
20
+ <li>Save and see your changes instantly.</li>
21
+ </ol>
22
+
23
+ <div className={styles.ctas}>
24
+ <a
25
+ className={styles.primary}
26
+ href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
27
+ target="_blank"
28
+ rel="noopener noreferrer"
29
+ >
30
+ <Image
31
+ className={styles.logo}
32
+ src="/vercel.svg"
33
+ alt="Vercel logomark"
34
+ width={20}
35
+ height={20}
36
+ />
37
+ Deploy now
38
+ </a>
39
+ <a
40
+ href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
41
+ target="_blank"
42
+ rel="noopener noreferrer"
43
+ className={styles.secondary}
44
+ >
45
+ Read our docs
46
+ </a>
47
+ </div>
48
+ </main>
49
+ <footer className={styles.footer}>
50
+ <a
51
+ href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
52
+ target="_blank"
53
+ rel="noopener noreferrer"
54
+ >
55
+ <Image
56
+ aria-hidden
57
+ src="/file.svg"
58
+ alt="File icon"
59
+ width={16}
60
+ height={16}
61
+ />
62
+ Learn
63
+ </a>
64
+ <a
65
+ href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
66
+ target="_blank"
67
+ rel="noopener noreferrer"
68
+ >
69
+ <Image
70
+ aria-hidden
71
+ src="/window.svg"
72
+ alt="Window icon"
73
+ width={16}
74
+ height={16}
75
+ />
76
+ Examples
77
+ </a>
78
+ <a
79
+ href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
80
+ target="_blank"
81
+ rel="noopener noreferrer"
82
+ >
83
+ <Image
84
+ aria-hidden
85
+ src="/globe.svg"
86
+ alt="Globe icon"
87
+ width={16}
88
+ height={16}
89
+ />
90
+ Go to nextjs.org →
91
+ </a>
92
+ </footer>
93
+ </div>
94
+ );
95
+ }
@@ -0,0 +1,30 @@
1
+ "use client"
2
+ import React, {FC} from "react";
3
+ import Loading from "@/components/shared/loading/Loading";
4
+
5
+ export interface props extends React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement> {
6
+ type?: "button" | "submit";
7
+ classNames?: string;
8
+ value: string;
9
+ theme?: "btn-primary" | "btn-secondary" | "btn-success" | "btn-warning" | "btn-info-light" | "btn-danger-light" | "btn-info-link" | "btn-outline-secondary" | "btn-outline-primary" | "btn-secondary-light";
10
+ size?: "btn-md" | "btn-sm";
11
+ isLoading?: boolean;
12
+ isDisabled?: boolean;
13
+ icon?: HTMLElement | undefined;
14
+ }
15
+
16
+ const Button: FC<props> = ({
17
+ type = "button", classNames = "",
18
+ value, theme = "btn-primary", size = "btn-md",
19
+ icon = undefined,
20
+ isLoading = false, isDisabled = false, ...otherProps
21
+ }) => {
22
+ return (
23
+ <button type={type} disabled={isDisabled} {...otherProps}
24
+ className={`flex items-center gap-1.5 justify-center rounded-lg w-full ${theme} ${size} ${classNames}`}
25
+ >{isLoading ? <Loading size={size === "btn-md" ? "w-5" : "w-4"} bgColor="text-transparent"
26
+ color={isDisabled ? "text-grey-300" : ""}/> : undefined}{icon}{value}</button>
27
+ );
28
+ };
29
+
30
+ export default Button;
@@ -0,0 +1,98 @@
1
+ "use client"
2
+ import {FC, forwardRef, useEffect, useImperativeHandle, useState} from "react";
3
+ import {useWidth} from '@/hooks/use-width';
4
+ import {useRouter} from 'next/navigation';
5
+
6
+ export interface LibDrawerProps {
7
+ children?: React.ReactNode;
8
+ size?: string;
9
+ position?: "TOP" | "RIGHT" | "LEFT" | "BOTTOM";
10
+ }
11
+
12
+ export interface LibDrawerRef {
13
+ onToggle: () => void;
14
+ }
15
+
16
+ const Drawer = forwardRef<LibDrawerRef, LibDrawerProps>(({size, children, position = "TOP"}, ref) => {
17
+ useImperativeHandle(ref, () => ({
18
+ onToggle: () => onToggle(),
19
+ }));
20
+ const getDeviceWidth = useWidth();
21
+ const router = useRouter();
22
+ const [isShow, setIsShow] = useState(false);
23
+ const onToggle = () => {
24
+ setIsShow(!isShow);
25
+ }
26
+ const onToggleEvent = (e) => {
27
+ if (e?.target?.className.toString()?.includes('backdrop')) {
28
+ onToggle()
29
+ }
30
+ }
31
+ const getPosition = () => {
32
+ if (position === "TOP") {
33
+ return `top-0 ${getDeviceWidth < 1024 ? '' : 'rounded-b-xl'}`
34
+ }
35
+ if (position === "BOTTOM") {
36
+ return `bottom-0 ${getDeviceWidth < 1024 ? '' : 'rounded-t-xl'}`
37
+ }
38
+ if (position === "LEFT") {
39
+ return `left-0 ${getDeviceWidth < 1024 ? '' : 'rounded-r-xl'}`
40
+ }
41
+ if (position === "RIGHT") {
42
+ return `right-0 ${getDeviceWidth < 1024 ? '' : 'rounded-l-xl'}`
43
+ }
44
+ }
45
+
46
+ useEffect(() => {
47
+ const handlePopState = () => {
48
+ setIsShow(false);
49
+ };
50
+ window.addEventListener('popstate', handlePopState);
51
+ return () => {
52
+ window.removeEventListener('popstate', handlePopState);
53
+ };
54
+ }, []);
55
+
56
+ useEffect(() => {
57
+ if (getDeviceWidth < 1024) {
58
+ if (isShow) {
59
+ router.push('#drawer');
60
+ } else {
61
+ if (window.location.hash && !document.referrer.includes('#')) {
62
+ router.back();
63
+ }
64
+ }
65
+ }
66
+ if (isShow) {
67
+ document.body.style.overflow = 'hidden';
68
+ } else {
69
+ document.body.style.overflow = 'auto';
70
+ }
71
+ }, [isShow]);
72
+
73
+ return (
74
+ <>
75
+ {isShow ?
76
+ (
77
+ <div
78
+ className={`backdrop bg-dark-100/20 backdrop-blur-sm fixed lg:place-items-center lg:grid right-0 top-0 left-0 bottom-0 w-full h-full z-40 duration-200 transition-opacity ${isShow ? "opacity-1" : "opacity-0 hidden pointer-events-none"}`}
79
+ onClick={onToggleEvent}>
80
+ <div
81
+ className={`absolute z-50 transform p-3 md:p-5 bg-grey-100 shadow-xl transition-opacity
82
+ ${getPosition()}
83
+ duration-200 h-full w-full lg:h-auto ${size ? size : "max-w-lg"}
84
+ ${isShow ? "opacity-1" : "opacity-0 pointer-events-none"}`}>
85
+ <div
86
+ className="overflow-y-auto max-h-[calc(100vh-60px)] md:max-h-[calc(100vh-90px)] h-full">
87
+ {children}
88
+ </div>
89
+ </div>
90
+ </div>
91
+ ) : undefined
92
+ }
93
+
94
+ </>
95
+ );
96
+ });
97
+
98
+ export default Drawer;
@@ -0,0 +1,89 @@
1
+ "use client"
2
+ import {FC} from "react";
3
+
4
+ export interface props {
5
+ type?: string;
6
+ classNames?: string;
7
+ placeholder: string;
8
+ label: string;
9
+ theme?: "secondary";
10
+ size?: "md" | "sm";
11
+ hasError?: string | null;
12
+ register?: any;
13
+ name?: string;
14
+ isDisabled?: boolean;
15
+ autocomplete?: boolean;
16
+ }
17
+
18
+ const themes = {
19
+ secondary: {
20
+ input: `border
21
+ bg-transparent
22
+ placeholder:text-secondary-400
23
+ outline-1
24
+ outline-primary-100
25
+ border-secondary-300
26
+ rounded-md
27
+ hover:not:border-primary-100
28
+ focus:outline
29
+ focus:border-primary-100
30
+
31
+ disabled:text-secondary-100
32
+ disabled:border-secondary-500`,
33
+
34
+ label: `text-dark-100
35
+ peer-focus:text-primary-100
36
+ peer-focus:scale-90
37
+
38
+ peer-disabled:text-secondary-400`
39
+ }
40
+ }
41
+
42
+ const sizes = {
43
+ sm: {
44
+ input: "text-xs px-2 py-1",
45
+ label: `px-1 text-xs `,
46
+ },
47
+ md: {
48
+ input: "text-sm px-3 py-2",
49
+ label: `px-1 text-xs`,
50
+ },
51
+ }
52
+ const Input: FC<props> = ({
53
+ type = "text", placeholder, classNames = "",
54
+ label, theme = "secondary", size = "md", hasError,
55
+ register, name, isDisabled = false, autocomplete = false,
56
+ ...otherProps
57
+ }) => {
58
+ return (
59
+ <div>
60
+ <label
61
+ htmlFor={name}
62
+ className={`cursor-text transition-all duration-200
63
+ transform ${themes[theme].label} ${sizes[size].label}
64
+ ${hasError && "!text-danger-100"}`}>
65
+ {label}
66
+ <input
67
+ disabled={isDisabled}
68
+ autoComplete = {autocomplete ? "on" : "off"}
69
+ id={name}
70
+ {...register}
71
+ {...otherProps}
72
+ type={type}
73
+ name={name}
74
+ className={`mt-1 w-full bg-white transition duration-200 ease ${themes[theme].input} ${sizes[size].input}
75
+ ${hasError && "!border-danger-100 focus:border-danger-100 outline-danger-100"} ${classNames}`}
76
+ placeholder={placeholder}
77
+ />
78
+ </label>
79
+ {
80
+ hasError &&
81
+ <p className="text-xs mt-1 text-danger-100">{hasError}</p>
82
+ }
83
+ </div>
84
+
85
+
86
+ );
87
+ };
88
+
89
+ export default Input;