nitro-web 0.0.35 → 0.0.37
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,5 @@
|
|
|
1
1
|
import { twMerge } from 'tailwind-merge'
|
|
2
|
-
import {
|
|
2
|
+
import { ChevronDown, ChevronUp } from 'lucide-react'
|
|
3
3
|
|
|
4
4
|
type Button = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
5
5
|
color?: 'primary'|'secondary'|'black'|'white'
|
|
@@ -51,8 +51,8 @@ export function Button({
|
|
|
51
51
|
const loading = isLoading ? '[&>*]:opacity-0 text-opacity-0' : ''
|
|
52
52
|
|
|
53
53
|
function getIcon(Icon: React.ReactNode | 'v') {
|
|
54
|
-
if (Icon == 'v' || Icon == 'down') return <
|
|
55
|
-
if (Icon == '^' || Icon == 'up') return <
|
|
54
|
+
if (Icon == 'v' || Icon == 'down') return <ChevronDown size={16.5} className="mt-[-1.4rem] mb-[-1.5rem] -mx-0.5" />
|
|
55
|
+
if (Icon == '^' || Icon == 'up') return <ChevronUp size={16.5} className="mt-[-1.4rem] mb-[-1.5rem] -mx-0.5" />
|
|
56
56
|
else return Icon
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
// Todo: show correct message type, e.g. error, warning, info, success `${store.message.type || 'success'}`
|
|
2
2
|
import { isObject, isString, queryObject } from 'nitro-web/util'
|
|
3
|
-
import {
|
|
4
|
-
import { CheckCircleIcon } from '@heroicons/react/24/outline'
|
|
5
|
-
import { XMarkIcon } from '@heroicons/react/20/solid'
|
|
3
|
+
import { X, CircleCheck } from 'lucide-react'
|
|
6
4
|
import { MessageObject } from 'nitro-web/types'
|
|
7
5
|
|
|
8
6
|
/**
|
|
@@ -64,7 +62,7 @@ export function Message() {
|
|
|
64
62
|
// Show message and hide it again after some time. Send back cleanup if store.message changes
|
|
65
63
|
} else if (messageObject && now - 500 < messageObject.date) {
|
|
66
64
|
const timeout1 = setTimeout(() => setVisible(true), 50)
|
|
67
|
-
if (messageObject.timeout !== 0 && !devDontHide) var timeout2 = setTimeout(hide, messageObject.timeout ||
|
|
65
|
+
if (messageObject.timeout !== 0 && !devDontHide) var timeout2 = setTimeout(hide, messageObject.timeout || 500000)
|
|
68
66
|
return () => {
|
|
69
67
|
clearTimeout(timeout1)
|
|
70
68
|
clearTimeout(timeout2)
|
|
@@ -85,16 +83,15 @@ export function Message() {
|
|
|
85
83
|
className="pointer-events-none fixed inset-0 flex items-end px-4 py-6 sm:items-start sm:p-6 z-20 nitro-message"
|
|
86
84
|
>
|
|
87
85
|
<div className="flex w-full flex-col items-center space-y-4 sm:items-end">
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
<div className="p-4">
|
|
86
|
+
{isObject(store.message) && (
|
|
87
|
+
<div className={
|
|
88
|
+
'overflow-hidden pointer-events-auto max-w-[350px] rounded-md bg-white shadow-lg ring-1 ring-black/5 transition ' +
|
|
89
|
+
(visible ? 'translate-x-0 opacity-100' : 'translate-x-1 opacity-0')
|
|
90
|
+
}>
|
|
91
|
+
<div className="p-3">
|
|
95
92
|
<div className="flex items-start">
|
|
96
93
|
<div className="shrink-0">
|
|
97
|
-
<
|
|
94
|
+
<CircleCheck aria-hidden="true" size={21} className="text-green-400 mt-0.5" />
|
|
98
95
|
</div>
|
|
99
96
|
<div className="ml-3 flex-1 pt-0.5">
|
|
100
97
|
<p className="text-sm font-medium text-gray-900">{typeof store.message === 'object' && store.message?.text}
|
|
@@ -105,17 +102,17 @@ export function Message() {
|
|
|
105
102
|
<button
|
|
106
103
|
type="button"
|
|
107
104
|
onClick={hide}
|
|
108
|
-
className="inline-flex
|
|
105
|
+
className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2
|
|
109
106
|
focus:ring-indigo-500 focus:ring-offset-2"
|
|
110
107
|
>
|
|
111
108
|
<span className="sr-only">Close</span>
|
|
112
|
-
<
|
|
109
|
+
<X aria-hidden="true" size={19} className="mt-0.5" />
|
|
113
110
|
</button>
|
|
114
111
|
</div>
|
|
115
112
|
</div>
|
|
116
113
|
</div>
|
|
117
114
|
</div>
|
|
118
|
-
|
|
115
|
+
)}
|
|
119
116
|
</div>
|
|
120
117
|
</div>
|
|
121
118
|
</>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Component: https://tailwindui.com/components/application-ui/application-shells/sidebar#component-a69d85b6237ea2ad506c00ef1cd39a38
|
|
2
|
-
import {
|
|
2
|
+
import { css } from 'twin.macro'
|
|
3
3
|
import avatarImg from 'nitro-web/client/imgs/avatar.jpg'
|
|
4
4
|
import { injectedConfig } from 'nitro-web'
|
|
5
5
|
import {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
PaintBrushIcon,
|
|
12
12
|
} from '@heroicons/react/24/outline'
|
|
13
13
|
|
|
14
|
-
const sidebarWidth = '
|
|
14
|
+
const sidebarWidth = 'w-80'
|
|
15
15
|
|
|
16
16
|
export type SidebarProps = {
|
|
17
17
|
Logo?: React.FC<{ width?: string, height?: string }>;
|
|
@@ -27,36 +27,41 @@ export function Sidebar({ Logo, menu, links }: SidebarProps) {
|
|
|
27
27
|
const [sidebarOpen, setSidebarOpen] = useState(false)
|
|
28
28
|
return (
|
|
29
29
|
<>
|
|
30
|
-
{/*
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</div>
|
|
48
|
-
</TransitionChild>
|
|
49
|
-
<SidebarContents Logo={Logo} menu={menu} links={links} />
|
|
50
|
-
</DialogPanel>
|
|
30
|
+
{/* desktop sidebar */}
|
|
31
|
+
<div css={style} className={
|
|
32
|
+
'fixed inset-y-0 z-50 flex flex-col ease-in-out lg:left-0 lg:translate-x-0 lg:!delay-0 lg:!duration-0 ' +
|
|
33
|
+
(
|
|
34
|
+
sidebarOpen
|
|
35
|
+
? 'left-0 translate-x-[0px] sidebar-transition '
|
|
36
|
+
: 'left-[-100%] translate-x-[-100%] sidebar-transition-delay '
|
|
37
|
+
) +
|
|
38
|
+
sidebarWidth
|
|
39
|
+
}>
|
|
40
|
+
<div className={
|
|
41
|
+
'absolute left-full top-0 flex w-16 justify-center pt-5 lg:hidden duration-300 ease ' +
|
|
42
|
+
(sidebarOpen ? 'opacity-100' : 'opacity-0')
|
|
43
|
+
}>
|
|
44
|
+
<button type="button" onClick={() => setSidebarOpen(false)} className="-m-2.5 p-2.5">
|
|
45
|
+
<XMarkIcon aria-hidden="true" className="size-6 text-white" />
|
|
46
|
+
</button>
|
|
51
47
|
</div>
|
|
52
|
-
</Dialog>
|
|
53
|
-
|
|
54
|
-
{/* Static sidebar for desktop */}
|
|
55
|
-
<div className={`hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:flex-col ${sidebarWidth}`}>
|
|
56
48
|
<SidebarContents Logo={Logo} menu={menu} links={links} />
|
|
57
49
|
</div>
|
|
50
|
+
|
|
51
|
+
{/* mobile backdrop */}
|
|
52
|
+
<div
|
|
53
|
+
css={style}
|
|
54
|
+
onClick={() => setSidebarOpen(false)}
|
|
55
|
+
className={'fixed w-full z-[49] inset-0 bg-gray-900/70 ease-linear lg:hidden ' +
|
|
56
|
+
(
|
|
57
|
+
sidebarOpen
|
|
58
|
+
? 'left-0 opacity-100 sidebar-transition '
|
|
59
|
+
: 'left-[-100%] opacity-0 sidebar-transition-delay '
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
/>
|
|
58
63
|
|
|
59
|
-
{/* mobile sidebar
|
|
64
|
+
{/* mobile sidebar topbar */}
|
|
60
65
|
<div className="sticky top-0 z-40 flex items-center gap-x-6 bg-white px-4 py-4 shadow-sm sm:px-6 lg:hidden">
|
|
61
66
|
<button type="button" onClick={() => setSidebarOpen(true)} className="-m-2.5 p-2.5 text-gray-700 lg:hidden">
|
|
62
67
|
<Bars3Icon aria-hidden="true" className="size-6" />
|
|
@@ -178,4 +183,13 @@ function SidebarContents ({ Logo, menu, links }: SidebarProps) {
|
|
|
178
183
|
</nav>
|
|
179
184
|
</div>
|
|
180
185
|
)
|
|
181
|
-
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const style = css`
|
|
189
|
+
&.sidebar-transition-delay {
|
|
190
|
+
transition: transform 300ms, opacity 300ms, left 0ms 300ms;
|
|
191
|
+
}
|
|
192
|
+
&.sidebar-transition {
|
|
193
|
+
transition: transform 300ms, opacity 300ms, left 0ms 0ms;
|
|
194
|
+
}
|
|
195
|
+
`
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EyeIcon,
|
|
11
11
|
EyeSlashIcon,
|
|
12
12
|
} from '@heroicons/react/20/solid'
|
|
13
|
+
// Maybe use fill-current tw class for lucide icons (https://github.com/lucide-icons/lucide/discussions/458)
|
|
13
14
|
|
|
14
15
|
type InputProps = React.InputHTMLAttributes<HTMLInputElement>
|
|
15
16
|
type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Drop, Dropdown, Field, Select, Button, Checkbox, GithubLink, Modal, Calendar, injectedConfig } from 'nitro-web'
|
|
2
2
|
import { getCountryOptions, getCurrencyOptions, ucFirst } from 'nitro-web/util'
|
|
3
|
-
import {
|
|
3
|
+
import { Check } from 'lucide-react'
|
|
4
4
|
|
|
5
5
|
export function Styleguide() {
|
|
6
6
|
const [customerSearch, setCustomerSearch] = useState('')
|
|
@@ -106,9 +106,11 @@ export function Styleguide() {
|
|
|
106
106
|
<div><Button color="primary" size="sm">*-sm button</Button></div>
|
|
107
107
|
<div><Button color="primary">*-md (default)</Button></div>
|
|
108
108
|
<div><Button color="primary" size="lg">*-lg button</Button></div>
|
|
109
|
-
<div><Button IconLeft={<
|
|
110
|
-
<div><Button IconLeft={<
|
|
111
|
-
|
|
109
|
+
<div><Button IconLeft={<Check size={19} className="-my-5 -mx-0.5" />}>IconLeft</Button></div>
|
|
110
|
+
<div><Button IconLeft={<Check size={19} className="-my-5 -mx-0.5" />}
|
|
111
|
+
className="w-[160px]">IconLeft 160px</Button></div>
|
|
112
|
+
<div><Button IconLeftEnd={<Check size={19} className="-my-5 -mx-0.5" />}
|
|
113
|
+
className="w-[190px]">IconLeftEnd 190px</Button></div>
|
|
112
114
|
<div><Button IconRight="v">IconRight</Button></div>
|
|
113
115
|
<div><Button IconRightEnd="v" className="w-[190px]">IconRightEnd 190px</Button></div>
|
|
114
116
|
<div><Button color="primary" IconRight="v" isLoading>primary isLoading</Button></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"repository": "github:boycce/nitro-web",
|
|
5
5
|
"homepage": "https://boycce.github.io/nitro-web/",
|
|
6
6
|
"description": "Nitro is a battle-tested, modular base project to turbocharge your projects, styled using Tailwind 🚀",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"bumpFiles": [
|
|
68
68
|
"package.json",
|
|
69
|
+
"package-lock.json",
|
|
69
70
|
"../webpack/package.json",
|
|
70
71
|
{
|
|
71
72
|
"filename": "../readme.md",
|