nitro-web 0.0.72 → 0.0.74
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/client/app.tsx +6 -12
- package/components/partials/element/button.tsx +12 -9
- package/components/partials/element/calendar.tsx +3 -1
- package/components/partials/element/dropdown.tsx +56 -9
- package/components/partials/element/filters.tsx +3 -3
- package/components/partials/element/github-link.tsx +1 -1
- package/components/partials/element/sidebar.tsx +2 -2
- package/components/partials/form/checkbox.tsx +129 -102
- package/components/partials/form/drop.tsx +2 -1
- package/components/partials/form/field-currency.tsx +1 -1
- package/components/partials/form/field-date.tsx +3 -2
- package/components/partials/form/field.tsx +25 -21
- package/components/partials/form/select.tsx +8 -7
- package/components/partials/styleguide.tsx +11 -8
- package/package.json +1 -1
- package/types/util.d.ts +1 -6
- package/types/util.d.ts.map +1 -1
- package/util.js +67 -23
package/client/app.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createBrowserRouter, createHashRouter, redirect,
|
|
1
|
+
import { createBrowserRouter, createHashRouter, redirect, RouterProvider } from 'react-router-dom'
|
|
2
2
|
import { Fragment, ReactNode } from 'react'
|
|
3
3
|
import ReactDOM from 'react-dom/client'
|
|
4
4
|
import { axios, camelCase, pick, toArray, setTimeoutPromise } from 'nitro-web/util'
|
|
@@ -25,7 +25,7 @@ type Settings = {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
type Route = {
|
|
28
|
-
component: React.FC<{ route?: Route;
|
|
28
|
+
component: React.FC<{ route?: Route; config?: Config }>
|
|
29
29
|
middleware: string[]
|
|
30
30
|
name: string
|
|
31
31
|
path: string
|
|
@@ -70,9 +70,7 @@ export function updateJwt(token?: string | null) {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
function App({ settings, config, storeContainer }: { settings: Settings, config: Config, storeContainer: StoreContainer }): ReactNode {
|
|
73
|
-
|
|
74
|
-
const router = getRouter({ settings, config })
|
|
75
|
-
// const theme = pick(themeNormalised, []) // e.g. 'topPanelHeight'
|
|
73
|
+
const router = useMemo(() => getRouter({ settings, config }), [])
|
|
76
74
|
|
|
77
75
|
useEffect(() => {
|
|
78
76
|
/**
|
|
@@ -97,10 +95,8 @@ function App({ settings, config, storeContainer }: { settings: Settings, config:
|
|
|
97
95
|
|
|
98
96
|
return (
|
|
99
97
|
<storeContainer.Provider>
|
|
100
|
-
{
|
|
101
|
-
{ router && <RouterProvider router={router} /> }
|
|
98
|
+
{ router && <RouterProvider router={router}/> }
|
|
102
99
|
<AfterApp settings={settings} />
|
|
103
|
-
{/* </ThemeProvider> */}
|
|
104
100
|
</storeContainer.Provider>
|
|
105
101
|
)
|
|
106
102
|
}
|
|
@@ -206,7 +202,7 @@ function getRouter({ settings, config }: { settings: Settings, config: Config })
|
|
|
206
202
|
),
|
|
207
203
|
path: route.path,
|
|
208
204
|
loader: async () => { // request
|
|
209
|
-
// wait for container/exposedStoreData to be setup
|
|
205
|
+
// wait for container/exposedStoreData to be setup (note that this causes ReactRouter to re-render, but not the page)
|
|
210
206
|
if (!nonce) {
|
|
211
207
|
nonce = true
|
|
212
208
|
await setTimeoutPromise(() => {}, 0)
|
|
@@ -255,11 +251,9 @@ function RestoreScroll() {
|
|
|
255
251
|
|
|
256
252
|
function RouteComponent({ route, config }: { route: Route, config: Config }) {
|
|
257
253
|
const Component = route.component
|
|
258
|
-
const params = useParams()
|
|
259
|
-
const location = useLocation()
|
|
260
254
|
document.title = route.meta?.title || ''
|
|
261
255
|
return (
|
|
262
|
-
<Component route={route}
|
|
256
|
+
<Component route={route} config={config} />
|
|
263
257
|
)
|
|
264
258
|
}
|
|
265
259
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { twMerge } from 'nitro-web'
|
|
2
2
|
import { ChevronDown, ChevronUp } from 'lucide-react'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
interface Button extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
5
5
|
color?: 'primary'|'secondary'|'black'|'dark'|'white'|'clear'|'custom'
|
|
6
|
-
size?: 'xs'|'sm'|'md'|'lg'
|
|
6
|
+
size?: 'xs'|'sm'|'md'|'lg'|'custom'
|
|
7
7
|
customColor?: string
|
|
8
|
+
customSize?: string
|
|
8
9
|
className?: string
|
|
9
10
|
isLoading?: boolean
|
|
10
11
|
IconLeft?: React.ReactNode|'v'
|
|
@@ -19,6 +20,7 @@ export function Button({
|
|
|
19
20
|
size='md',
|
|
20
21
|
color='primary',
|
|
21
22
|
customColor,
|
|
23
|
+
customSize,
|
|
22
24
|
className,
|
|
23
25
|
isLoading,
|
|
24
26
|
IconLeft,
|
|
@@ -49,26 +51,27 @@ export function Button({
|
|
|
49
51
|
|
|
50
52
|
// Button sizes (px is better for height consistency)
|
|
51
53
|
const sizes = {
|
|
52
|
-
xs: 'px-[6px] h-[25px]
|
|
53
|
-
sm: 'px-[10px] h-[32px]
|
|
54
|
-
md: 'px-[12px] h-[38px]
|
|
55
|
-
lg: 'px-[18px] h-[42px]
|
|
54
|
+
'xs': 'px-[6px] h-[25px] text-xs !text-button-xs rounded',
|
|
55
|
+
'sm': 'px-[10px] h-[32px] text-md text-button-base rounded-md',
|
|
56
|
+
'md': 'px-[12px] h-[38px] text-md text-button-base rounded-md', // default
|
|
57
|
+
'lg': 'px-[18px] h-[42px] text-md text-button-base rounded-md',
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
const appliedColor = color === 'custom' ? customColor : colors[color]
|
|
61
|
+
const appliedSize = size === 'custom' ? customSize : sizes[size]
|
|
59
62
|
const contentLayout = `gap-x-1.5 ${iconPosition == 'none' ? '' : ''}`
|
|
60
63
|
const loading = isLoading ? '[&>*]:opacity-0 text-opacity-0' : ''
|
|
61
64
|
|
|
62
65
|
function getIcon(Icon: React.ReactNode | 'v') {
|
|
63
|
-
if (Icon == 'v' || Icon == 'down') return <ChevronDown size={16.5} className="mt-[-1.4rem] mb-[-1.5rem]
|
|
64
|
-
if (Icon == '^' || Icon == 'up') return <ChevronUp size={16.5} className="mt-[-1.4rem] mb-[-1.5rem]
|
|
66
|
+
if (Icon == 'v' || Icon == 'down') return <ChevronDown size={16.5} className="mt-[-1.4rem] mb-[-1.5rem]" />
|
|
67
|
+
if (Icon == '^' || Icon == 'up') return <ChevronUp size={16.5} className="mt-[-1.4rem] mb-[-1.5rem]" />
|
|
65
68
|
else return Icon
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
return (
|
|
69
72
|
<button
|
|
70
73
|
type={type}
|
|
71
|
-
class={twMerge(`${base} ${
|
|
74
|
+
class={twMerge(`${base} ${appliedSize} ${appliedColor} ${contentLayout} ${loading} nitro-button ${className||''}`)}
|
|
72
75
|
{...props}
|
|
73
76
|
>
|
|
74
77
|
{
|
|
@@ -3,6 +3,8 @@ import { isValid } from 'date-fns'
|
|
|
3
3
|
import 'react-day-picker/style.css'
|
|
4
4
|
import { IsFirstRender } from 'nitro-web'
|
|
5
5
|
|
|
6
|
+
export const dayButtonClassName = 'size-[33px] text-sm'
|
|
7
|
+
|
|
6
8
|
type Mode = 'single'|'multiple'|'range'
|
|
7
9
|
type ModeSelection<T extends Mode> = (
|
|
8
10
|
T extends 'single' ? Date | undefined
|
|
@@ -94,7 +96,7 @@ export function Calendar({ mode='single', onChange, value, numberOfMonths, month
|
|
|
94
96
|
// Days
|
|
95
97
|
weekday: `${d.weekday} text-[11px] font-bold uppercase`,
|
|
96
98
|
day: `${d.day} size-[33px]`,
|
|
97
|
-
day_button: `${d.day_button}
|
|
99
|
+
day_button: `${d.day_button} ${dayButtonClassName}`,
|
|
98
100
|
|
|
99
101
|
// States
|
|
100
102
|
focused: `${d.focused} [&>button]:bg-gray-200 [&>button]:border-gray-200`,
|
|
@@ -14,14 +14,14 @@ type DropdownProps = {
|
|
|
14
14
|
options?: { label: string|React.ReactNode, onClick?: Function, isSelected?: boolean, icon?: React.ReactNode, className?: string }[]
|
|
15
15
|
/** Whether the dropdown is hoverable **/
|
|
16
16
|
isHoverable?: boolean
|
|
17
|
-
/** The minimum width of the menu **/
|
|
18
|
-
minWidth?: number | string
|
|
19
17
|
/** The content to render inside the top of the dropdown **/
|
|
20
18
|
menuContent?: React.ReactNode
|
|
21
19
|
menuClassName?: string
|
|
22
20
|
menuOptionClassName?: string
|
|
23
21
|
menuIsOpen?: boolean
|
|
24
22
|
menuToggles?: boolean
|
|
23
|
+
/** The minimum width of the menu **/
|
|
24
|
+
minWidth?: number | string
|
|
25
25
|
toggleCallback?: (isActive: boolean) => void
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -30,15 +30,15 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
30
30
|
animate=true,
|
|
31
31
|
children,
|
|
32
32
|
className,
|
|
33
|
-
dir,
|
|
33
|
+
dir='bottom-left',
|
|
34
34
|
options,
|
|
35
35
|
isHoverable,
|
|
36
|
-
minWidth, // remove in favour of menuClassName
|
|
37
36
|
menuClassName,
|
|
38
37
|
menuOptionClassName,
|
|
39
38
|
menuContent,
|
|
40
39
|
menuIsOpen,
|
|
41
40
|
menuToggles=true,
|
|
41
|
+
minWidth,
|
|
42
42
|
toggleCallback,
|
|
43
43
|
}: DropdownProps, ref) {
|
|
44
44
|
// https://letsbuildui.dev/articles/building-a-dropdown-menu-component-with-react-hooks
|
|
@@ -46,6 +46,8 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
46
46
|
const dropdownRef = useRef<HTMLDivElement|null>(null)
|
|
47
47
|
const [isActive, setIsActive] = useState(!!menuIsOpen)
|
|
48
48
|
const menuStyle = getSelectStyle({ name: 'menu' })
|
|
49
|
+
const [direction, setDirection] = useState<null | 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'>(null)
|
|
50
|
+
const [ready, setReady] = useState(false)
|
|
49
51
|
|
|
50
52
|
// Expose the setIsActive function to the parent component
|
|
51
53
|
useImperativeHandle(ref, () => ({ setIsActive }))
|
|
@@ -76,7 +78,50 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
76
78
|
useEffect(() => {
|
|
77
79
|
if (toggleCallback) toggleCallback(isActive)
|
|
78
80
|
}, [isActive])
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
setReady(false)
|
|
84
|
+
if (!isActive || !dropdownRef.current) return
|
|
85
|
+
|
|
86
|
+
const ul = dropdownRef.current.querySelector('ul') as HTMLElement
|
|
87
|
+
if (!ul) return
|
|
88
|
+
|
|
89
|
+
// Temporarily show the ul for measurement
|
|
90
|
+
const originalMaxHeight = ul.style.maxHeight
|
|
91
|
+
const originalVisibility = ul.style.visibility
|
|
92
|
+
const originalOpacity = ul.style.opacity
|
|
93
|
+
const originalPointerEvents = ul.style.pointerEvents
|
|
94
|
+
|
|
95
|
+
ul.style.maxHeight = 'none'
|
|
96
|
+
ul.style.visibility = 'hidden'
|
|
97
|
+
ul.style.opacity = '0'
|
|
98
|
+
ul.style.pointerEvents = 'none'
|
|
79
99
|
|
|
100
|
+
const dropdownHeight = ul.getBoundingClientRect().height
|
|
101
|
+
|
|
102
|
+
// Revert styles
|
|
103
|
+
ul.style.maxHeight = originalMaxHeight
|
|
104
|
+
ul.style.visibility = originalVisibility
|
|
105
|
+
ul.style.opacity = originalOpacity
|
|
106
|
+
ul.style.pointerEvents = originalPointerEvents
|
|
107
|
+
|
|
108
|
+
const rect = dropdownRef.current.getBoundingClientRect()
|
|
109
|
+
const spaceBelow = window.innerHeight - rect.bottom
|
|
110
|
+
const spaceAbove = rect.top
|
|
111
|
+
|
|
112
|
+
const side = dir.endsWith('right') ? 'right' : 'left'
|
|
113
|
+
|
|
114
|
+
const newDirection = dir.startsWith('bottom')
|
|
115
|
+
? `${spaceBelow < dropdownHeight && spaceAbove > dropdownHeight ? 'top' : 'bottom'}-${side}`
|
|
116
|
+
: `${spaceAbove < dropdownHeight && spaceBelow > dropdownHeight ? 'bottom' : 'top'}-${side}`
|
|
117
|
+
|
|
118
|
+
setDirection(newDirection as 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right')
|
|
119
|
+
|
|
120
|
+
requestAnimationFrame(() => {
|
|
121
|
+
setReady(true)
|
|
122
|
+
})
|
|
123
|
+
}, [isActive, dir])
|
|
124
|
+
|
|
80
125
|
function onMouseDown(e: { key: string, preventDefault: Function }) {
|
|
81
126
|
if (e.key && e.key != 'Enter') return
|
|
82
127
|
if (e.key) e.preventDefault() // for button, stops buttons firing twice
|
|
@@ -87,12 +132,13 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
87
132
|
if (option.onClick) option.onClick(e)
|
|
88
133
|
if (!menuIsOpen) setIsActive(!isActive)
|
|
89
134
|
}
|
|
135
|
+
var ready2
|
|
90
136
|
|
|
91
137
|
return (
|
|
92
138
|
<div
|
|
93
139
|
class={
|
|
94
|
-
|
|
95
|
-
(
|
|
140
|
+
`relative is-${direction || dir}` + // until hovered, show the original direction to prevent scrollbars
|
|
141
|
+
(ready2 ? ' is-ready' : '') +
|
|
96
142
|
(isHoverable ? ' is-hoverable' : '') +
|
|
97
143
|
(isActive ? ' is-active' : '') +
|
|
98
144
|
(!animate ? ' no-animation' : '') +
|
|
@@ -113,7 +159,8 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
113
159
|
}
|
|
114
160
|
<ul
|
|
115
161
|
style={{ minWidth }}
|
|
116
|
-
class={
|
|
162
|
+
class={
|
|
163
|
+
twMerge(`${menuStyle} ${ready ? 'is-ready' : ''} absolute invisible opacity-0 select-none min-w-full z-[1] ${menuClassName||''}`)}
|
|
117
164
|
>
|
|
118
165
|
{menuContent}
|
|
119
166
|
{
|
|
@@ -127,7 +174,7 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
127
174
|
>
|
|
128
175
|
<span class="flex-auto">{option.label}</span>
|
|
129
176
|
{ !!option.icon && option.icon }
|
|
130
|
-
{ option.isSelected && <CheckCircleIcon className="size-[22px] text-primary -my-1 -mx-
|
|
177
|
+
{ option.isSelected && <CheckCircleIcon className="size-[22px] text-primary -my-1 -mx-0.5" /> }
|
|
131
178
|
</li>
|
|
132
179
|
)
|
|
133
180
|
})
|
|
@@ -172,7 +219,7 @@ const style = css`
|
|
|
172
219
|
&>ul>li:hover,
|
|
173
220
|
&>ul>li:focus,
|
|
174
221
|
&>ul>li.is-active {
|
|
175
|
-
&>ul {
|
|
222
|
+
&>ul.is-ready {
|
|
176
223
|
opacity: 1;
|
|
177
224
|
visibility: visible;
|
|
178
225
|
transition: transform 0.15s ease, opacity 0.15s ease;
|
|
@@ -123,7 +123,7 @@ export const Filters = forwardRef<FiltersHandleType, FiltersProps>(({
|
|
|
123
123
|
allowOverflow={true}
|
|
124
124
|
// menuIsOpen={true}
|
|
125
125
|
{...dropdownProps}
|
|
126
|
-
menuClassName={twMerge(
|
|
126
|
+
menuClassName={twMerge(`min-w-[330px] ${dropdownProps?.menuClassName || ''}`)}
|
|
127
127
|
menuContent={
|
|
128
128
|
<div>
|
|
129
129
|
<div class="flex justify-between items-center border-b p-4 py-3.5">
|
|
@@ -146,7 +146,7 @@ export const Filters = forwardRef<FiltersHandleType, FiltersProps>(({
|
|
|
146
146
|
filter.type === 'select' &&
|
|
147
147
|
<Elements.Select
|
|
148
148
|
{...filter}
|
|
149
|
-
class="mb-0"
|
|
149
|
+
class="!mb-0"
|
|
150
150
|
state={state}
|
|
151
151
|
onChange={onInputChange}
|
|
152
152
|
type={undefined}
|
|
@@ -156,7 +156,7 @@ export const Filters = forwardRef<FiltersHandleType, FiltersProps>(({
|
|
|
156
156
|
filter.type !== 'select' &&
|
|
157
157
|
<Elements.Field
|
|
158
158
|
{...filter}
|
|
159
|
-
class="mb-0"
|
|
159
|
+
class="!mb-0"
|
|
160
160
|
state={state}
|
|
161
161
|
onChange={onInputChange}
|
|
162
162
|
/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import GithubIcon from 'nitro-web/client/imgs/github.svg'
|
|
2
2
|
|
|
3
3
|
export function GithubLink({ filename }: { filename: string }) {
|
|
4
|
-
const base = 'https://github.com/boycce/nitro-web/blob/master/'
|
|
4
|
+
const base = 'https://github.com/boycce/nitro-web/blob/master/packages/'
|
|
5
5
|
// Filenames are relative to the webpack start directory
|
|
6
6
|
// 1. Remove ../ from filename (i.e. for _example build)
|
|
7
7
|
// 2. Remove node_modules/nitro-web/ from filename (i.e. for packages using nitro-web)
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
Bars3Icon,
|
|
7
7
|
HomeIcon,
|
|
8
8
|
UsersIcon,
|
|
9
|
-
XMarkIcon,
|
|
10
9
|
ArrowLeftCircleIcon,
|
|
11
10
|
PaintBrushIcon,
|
|
12
11
|
} from '@heroicons/react/24/outline'
|
|
12
|
+
import { XIcon } from 'lucide-react'
|
|
13
13
|
|
|
14
14
|
const sidebarWidth = 'w-80'
|
|
15
15
|
|
|
@@ -42,7 +42,7 @@ export function Sidebar({ Logo, menu, links }: SidebarProps) {
|
|
|
42
42
|
(sidebarOpen ? 'opacity-100' : 'opacity-0')
|
|
43
43
|
}>
|
|
44
44
|
<button type="button" onClick={() => setSidebarOpen(false)} className="-m-2.5 p-2.5">
|
|
45
|
-
<
|
|
45
|
+
<XIcon aria-hidden="true" strokeWidth={1.5} size={24} className="text-white" />
|
|
46
46
|
</button>
|
|
47
47
|
</div>
|
|
48
48
|
<SidebarContents Logo={Logo} menu={menu} links={links} />
|
|
@@ -1,119 +1,146 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { twMerge, deepFind, getErrorFromState } from 'nitro-web/util'
|
|
3
|
+
import { Errors, type Error } from 'nitro-web/types'
|
|
4
|
+
|
|
5
|
+
type CheckboxProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
6
|
+
/** field name or path on state (used to match errors), e.g. 'date', 'company.email' */
|
|
2
7
|
name: string
|
|
3
|
-
/** name is applied if not provided. Used for radios */
|
|
8
|
+
/** name is applied if id is not provided. Used for radios */
|
|
4
9
|
id?: string
|
|
5
|
-
|
|
10
|
+
/** state object to get the value, and check errors against */
|
|
11
|
+
state?: { errors?: Errors, [key: string]: any }
|
|
12
|
+
size?: number
|
|
6
13
|
subtext?: string|React.ReactNode
|
|
7
14
|
text?: string|React.ReactNode
|
|
8
15
|
type?: 'checkbox' | 'radio' | 'toggle'
|
|
9
|
-
|
|
16
|
+
checkboxClassName?: string
|
|
17
|
+
svgClassName?: string
|
|
18
|
+
labelClassName?: string
|
|
10
19
|
}
|
|
11
20
|
|
|
12
|
-
export function Checkbox({
|
|
21
|
+
export function Checkbox({
|
|
22
|
+
state, size, subtext, text, type='checkbox', className, checkboxClassName, svgClassName, labelClassName, ...props
|
|
23
|
+
}: CheckboxProps) {
|
|
13
24
|
// Checkbox/radio/toggle component
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
id = id || name
|
|
25
|
+
let value!: boolean
|
|
26
|
+
const error = getErrorFromState(state, props.name)
|
|
27
|
+
const id = props.id || props.name
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
md: {
|
|
26
|
-
checkbox: 'size-[16px]',
|
|
27
|
-
toggleWidth: 'w-[40px]', // 4px border + (toggleAfterSize * 2)
|
|
28
|
-
toggleHeight: 'h-[22px]',
|
|
29
|
-
toggleAfterSize: 'after:size-[18px]', // account for 2px border
|
|
30
|
-
},
|
|
29
|
+
if (!props.name) throw new Error('Checkbox requires a `name` prop')
|
|
30
|
+
|
|
31
|
+
// Value: Input is always controlled if state is passed in
|
|
32
|
+
if (typeof props.checked !== 'undefined') value = props.checked
|
|
33
|
+
else if (typeof state == 'object') {
|
|
34
|
+
const v = deepFind(state, props.name) as boolean | undefined
|
|
35
|
+
value = v ?? false
|
|
31
36
|
}
|
|
32
|
-
|
|
37
|
+
|
|
38
|
+
const BORDER = 2
|
|
39
|
+
const checkboxSize = size ?? 14
|
|
40
|
+
const toggleHeight = size ?? 18
|
|
41
|
+
const toggleWidth = toggleHeight * 2 - BORDER * 2
|
|
42
|
+
const toggleAfterSize = toggleHeight - BORDER * 2
|
|
33
43
|
|
|
34
44
|
return (
|
|
35
|
-
<div
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
45
|
+
<div
|
|
46
|
+
className={'mt-2.5 mb-6 ' + twMerge(`mt-input-before mb-input-after text-sm nitro-checkbox ${className}`)}
|
|
47
|
+
>
|
|
48
|
+
<div className="flex gap-3 items-baseline">
|
|
49
|
+
<div className="shrink-0 flex items-center">
|
|
50
|
+
<div className="w-0"> </div>
|
|
51
|
+
<div className="group relative">
|
|
52
|
+
{
|
|
53
|
+
type !== 'toggle'
|
|
54
|
+
? <>
|
|
55
|
+
<input
|
|
56
|
+
{...props}
|
|
57
|
+
type={type}
|
|
58
|
+
style={{ width: checkboxSize, height: checkboxSize }}
|
|
59
|
+
checked={value}
|
|
60
|
+
className={
|
|
61
|
+
twMerge(
|
|
62
|
+
`${type === 'radio' ? 'rounded-full' : 'rounded'} appearance-none border border-gray-300 bg-white forced-colors:appearance-auto disabled:border-gray-300 disabled:bg-gray-100 disabled:checked:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 ` +
|
|
63
|
+
// Variable-selected theme colors (was .*-blue-600)
|
|
64
|
+
'checked:border-variable-selected checked:bg-variable-selected indeterminate:border-variable-selected indeterminate:bg-variable-selected focus-visible:outline-variable-selected ' +
|
|
65
|
+
// Dark mode not used yet... dark:focus-visible:outline-blue-800
|
|
66
|
+
checkboxClassName
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
/>
|
|
70
|
+
<svg
|
|
71
|
+
fill="none"
|
|
72
|
+
viewBox="0 0 14 14"
|
|
73
|
+
style={{ width: checkboxSize, height: checkboxSize }}
|
|
74
|
+
className={twMerge('absolute top-0 left-0 pointer-events-none justify-self-center stroke-white group-has-[:disabled]:stroke-gray-950/25', svgClassName)}
|
|
75
|
+
>
|
|
76
|
+
{
|
|
77
|
+
type === 'radio'
|
|
78
|
+
? <circle
|
|
79
|
+
// cx={(_size.checkbox.match(/\d+/)?.[0] as unknown as number) / 2}
|
|
80
|
+
// cy={(_size.checkbox.match(/\d+/)?.[0] as unknown as number) / 2}
|
|
81
|
+
// r={(_size.checkbox.match(/\d+/)?.[0] as unknown as number) / 6}
|
|
82
|
+
cx={7}
|
|
83
|
+
cy={7}
|
|
84
|
+
r={2.5}
|
|
85
|
+
className="fill-white opacity-0 group-has-[:checked]:opacity-100"
|
|
86
|
+
/>
|
|
87
|
+
: <>
|
|
88
|
+
<path
|
|
89
|
+
d="M4 8L6 10L10 4.5"
|
|
90
|
+
strokeWidth={2}
|
|
91
|
+
strokeLinecap="round"
|
|
92
|
+
strokeLinejoin="round"
|
|
93
|
+
className="opacity-0 group-has-[:checked]:opacity-100"
|
|
94
|
+
/>
|
|
95
|
+
<path
|
|
96
|
+
d="M4 7H10"
|
|
97
|
+
strokeWidth={2}
|
|
98
|
+
strokeLinecap="round"
|
|
99
|
+
strokeLinejoin="round"
|
|
100
|
+
className="opacity-0 group-has-[:indeterminate]:opacity-100"
|
|
101
|
+
/>
|
|
102
|
+
</>
|
|
103
|
+
}
|
|
104
|
+
</svg>
|
|
105
|
+
</>
|
|
106
|
+
: <>
|
|
107
|
+
<input
|
|
108
|
+
{...props}
|
|
109
|
+
type="checkbox"
|
|
110
|
+
className="sr-only peer"
|
|
111
|
+
checked={value}
|
|
112
|
+
/>
|
|
113
|
+
<label
|
|
114
|
+
for={id}
|
|
115
|
+
style={{ width: toggleWidth, height: toggleHeight }}
|
|
116
|
+
className={
|
|
117
|
+
twMerge(
|
|
118
|
+
'block bg-gray-200 rounded-full transition-colors peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 ' +
|
|
119
|
+
// Variable-selected theme colors (was .*-blue-600)
|
|
120
|
+
'peer-checked:bg-variable-selected peer-focus-visible:outline-variable-selected ' +
|
|
121
|
+
labelClassName
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
>
|
|
125
|
+
<span
|
|
126
|
+
style={{ width: toggleAfterSize, height: toggleAfterSize }}
|
|
127
|
+
className={
|
|
128
|
+
'absolute top-[2px] start-[2px] bg-white border-gray-300 border rounded-full transition-all group-has-[:checked]:border-white group-has-[:checked]:translate-x-full '
|
|
129
|
+
}
|
|
130
|
+
/>
|
|
131
|
+
</label>
|
|
132
|
+
</>
|
|
133
|
+
}
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
{text &&
|
|
137
|
+
<label for={id} className="text-[length:inherit] leading-[inherit] select-none">
|
|
138
|
+
<span className="text-gray-900">{text}</span>
|
|
139
|
+
<span className="ml-2 text-gray-500">{subtext}</span>
|
|
140
|
+
</label>
|
|
109
141
|
}
|
|
110
142
|
</div>
|
|
111
|
-
{
|
|
112
|
-
<label for={id} className="self-center text-sm select-none">
|
|
113
|
-
<span className="text-gray-900">{text}</span>
|
|
114
|
-
<span className="ml-2 text-gray-500">{subtext}</span>
|
|
115
|
-
</label>
|
|
116
|
-
}
|
|
143
|
+
{error && <div class="mt-1.5 text-xs text-danger-foreground nitro-error">{error.detail}</div>}
|
|
117
144
|
</div>
|
|
118
145
|
)
|
|
119
146
|
}
|
|
@@ -3,6 +3,7 @@ import { deepFind, s3Image, getErrorFromState } from 'nitro-web/util'
|
|
|
3
3
|
import { DropHandler } from 'nitro-web'
|
|
4
4
|
import noImage from 'nitro-web/client/imgs/no-image.svg'
|
|
5
5
|
import { Errors, MonasteryImage } from 'nitro-web/types'
|
|
6
|
+
import { twMerge } from 'nitro-web/util'
|
|
6
7
|
|
|
7
8
|
type DropProps = {
|
|
8
9
|
awsUrl?: string
|
|
@@ -93,7 +94,7 @@ export function Drop({ awsUrl, className, id, name, onChange, multiple, state, .
|
|
|
93
94
|
// }
|
|
94
95
|
|
|
95
96
|
return (
|
|
96
|
-
<div class={
|
|
97
|
+
<div class={'mt-2.5 mb-6 ' + twMerge(`mt-input-before mb-input-after nitro-field nitro-drop ${className || ''}`)}>
|
|
97
98
|
<input
|
|
98
99
|
{...props}
|
|
99
100
|
id={inputId}
|
|
@@ -149,7 +149,7 @@ export function FieldCurrency({ config, currency='nzd', onChange, value, default
|
|
|
149
149
|
defaultValue={defaultValue}
|
|
150
150
|
/>
|
|
151
151
|
<span
|
|
152
|
-
class={`absolute top-0 bottom-0 left-
|
|
152
|
+
class={`absolute top-0 bottom-0 left-[12px] left-input-x inline-flex items-center select-none text-gray-500 text-input-base ${dollars !== null && settings.prefix == '$' ? 'text-foreground' : ''}`}
|
|
153
153
|
>
|
|
154
154
|
{settings.prefix || settings.suffix}
|
|
155
155
|
</span>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { format, isValid, parse } from 'date-fns'
|
|
3
3
|
import { getPrefixWidth } from 'nitro-web/util'
|
|
4
4
|
import { Calendar, Dropdown } from 'nitro-web'
|
|
5
|
+
import { dayButtonClassName } from '../element/calendar'
|
|
5
6
|
|
|
6
7
|
type Mode = 'single' | 'multiple' | 'range'
|
|
7
8
|
type DropdownRef = {
|
|
@@ -160,7 +161,7 @@ export function FieldDate({
|
|
|
160
161
|
{
|
|
161
162
|
prefix &&
|
|
162
163
|
// Similar classNames to the input.tsx:IconWrapper()
|
|
163
|
-
<span className="z-[0] col-start-1 row-start-1 self-center select-none justify-self-start text-input-base ml-
|
|
164
|
+
<span className="z-[0] col-start-1 row-start-1 self-center select-none justify-self-start text-input-base ml-[12px] ml-input-x">
|
|
164
165
|
{prefix}
|
|
165
166
|
</span>
|
|
166
167
|
}
|
|
@@ -234,7 +235,7 @@ function TimePicker({ date, onChange }: TimePickerProps) {
|
|
|
234
235
|
<button
|
|
235
236
|
key={item}
|
|
236
237
|
className={
|
|
237
|
-
|
|
238
|
+
`${dayButtonClassName} rounded-full flex justify-center items-center group-hover:bg-gray-100 `
|
|
238
239
|
+ (item === currentValue ? '!bg-input-border-focus text-white' : '')
|
|
239
240
|
}
|
|
240
241
|
onClick={() => handleTimeChange(type, item)}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
//
|
|
2
|
+
// fill-current tw class for lucide icons (https://github.com/lucide-icons/lucide/discussions/458)
|
|
3
3
|
import { css } from 'twin.macro'
|
|
4
4
|
import { FieldCurrency, FieldCurrencyProps, FieldColor, FieldColorProps, FieldDate, FieldDateProps } from 'nitro-web'
|
|
5
5
|
import { twMerge, getErrorFromState, deepFind } from 'nitro-web/util'
|
|
6
6
|
import { Errors, type Error } from 'nitro-web/types'
|
|
7
|
-
import {
|
|
7
|
+
import { MailIcon, CalendarIcon, FunnelIcon, SearchIcon, EyeIcon, EyeOffIcon } from 'lucide-react'
|
|
8
8
|
import { memo } from 'react'
|
|
9
9
|
|
|
10
10
|
type FieldType = 'text' | 'password' | 'email' | 'filter' | 'search' | 'textarea' | 'currency' | 'date' | 'color'
|
|
@@ -27,7 +27,7 @@ type FieldExtraProps = {
|
|
|
27
27
|
placeholder?: string
|
|
28
28
|
}
|
|
29
29
|
type IconWrapperProps = {
|
|
30
|
-
iconPos:
|
|
30
|
+
iconPos: 'left' | 'right'
|
|
31
31
|
icon?: React.ReactNode
|
|
32
32
|
[key: string]: unknown
|
|
33
33
|
}
|
|
@@ -77,22 +77,22 @@ function FieldBase({ state, icon, iconPos: ip, ...props }: FieldProps) {
|
|
|
77
77
|
if (type == 'password') {
|
|
78
78
|
Icon = <IconWrapper
|
|
79
79
|
iconPos={iconPos}
|
|
80
|
-
icon={icon || inputType == 'password' ? <
|
|
80
|
+
icon={icon || inputType == 'password' ? <EyeOffIcon /> : <EyeIcon />}
|
|
81
81
|
onClick={() => setInputType(o => o == 'password' ? 'text' : 'password')}
|
|
82
|
-
className="pointer-events-auto"
|
|
82
|
+
className="size-[15px] size-input-icon pointer-events-auto"
|
|
83
83
|
/>
|
|
84
84
|
} else if (type == 'email') {
|
|
85
|
-
Icon = <IconWrapper iconPos={iconPos} icon={icon || <
|
|
85
|
+
Icon = <IconWrapper iconPos={iconPos} icon={icon || <MailIcon />} className="size-[14px] size-input-icon" />
|
|
86
86
|
} else if (type == 'filter') {
|
|
87
|
-
Icon = <IconWrapper iconPos={iconPos} icon={icon || <FunnelIcon />} className="size-
|
|
87
|
+
Icon = <IconWrapper iconPos={iconPos} icon={icon || <FunnelIcon />} className="size-[14px] size-input-icon" />
|
|
88
88
|
} else if (type == 'search') {
|
|
89
|
-
Icon = <IconWrapper iconPos={iconPos} icon={icon || <
|
|
89
|
+
Icon = <IconWrapper iconPos={iconPos} icon={icon || <SearchIcon />} className="size-[14px] size-input-icon" />
|
|
90
90
|
} else if (type == 'color') {
|
|
91
91
|
Icon = <IconWrapper iconPos={iconPos} icon={icon || <ColorSvg hex={value}/>} className="size-[17px]" />
|
|
92
92
|
} else if (type == 'date') {
|
|
93
|
-
Icon = <IconWrapper iconPos={iconPos} icon={icon || <CalendarIcon />} className="size-
|
|
94
|
-
} else {
|
|
95
|
-
Icon = <IconWrapper iconPos={iconPos} icon={icon} />
|
|
93
|
+
Icon = <IconWrapper iconPos={iconPos} icon={icon || <CalendarIcon />} className="size-[14px] size-input-icon" />
|
|
94
|
+
} else if (icon) {
|
|
95
|
+
Icon = <IconWrapper iconPos={iconPos} icon={icon} className="size-[14px] size-input-icon" />
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// Classname
|
|
@@ -135,7 +135,7 @@ function FieldBase({ state, icon, iconPos: ip, ...props }: FieldProps) {
|
|
|
135
135
|
|
|
136
136
|
function FieldContainer({ children, className, error }: { children: React.ReactNode, className?: string, error?: Error }) {
|
|
137
137
|
return (
|
|
138
|
-
<div css={style} className={
|
|
138
|
+
<div css={style} className={'mt-2.5 mb-6 ' + twMerge(`mt-input-before mb-input-after grid grid-cols-1 nitro-field ${className || ''}`)}>
|
|
139
139
|
{children}
|
|
140
140
|
{error && <div class="mt-1.5 text-xs text-danger-foreground nitro-error">{error.detail}</div>}
|
|
141
141
|
</div>
|
|
@@ -143,15 +143,15 @@ function FieldContainer({ children, className, error }: { children: React.ReactN
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
function getInputClasses({ error, Icon, iconPos, type }: { error?: Error, Icon?: React.ReactNode, iconPos: string, type?: string }) {
|
|
146
|
-
|
|
147
|
-
const
|
|
146
|
+
// not twMerge
|
|
147
|
+
const px = 'px-[12px]'
|
|
148
148
|
const py = 'py-[9px] py-input-y'
|
|
149
|
-
const plWithIcon = type == 'color' ? 'pl-9' : 'pl-8' // was sm:pl-8 pl-8, etc
|
|
150
|
-
const prWithIcon = type == 'color' ? 'pr-9' : 'pr-8'
|
|
151
149
|
return (
|
|
152
|
-
|
|
153
|
-
'placeholder:text-input-placeholder focus:outline focus:outline-2 focus:-outline-offset-2 ' +
|
|
154
|
-
(iconPos == 'right' && Icon ?
|
|
150
|
+
'block col-start-1 row-start-1 w-full rounded-md bg-white text-input-base outline outline-1 -outline-offset-1 ' +
|
|
151
|
+
'placeholder:text-input-placeholder focus:outline focus:outline-2 focus:-outline-offset-2 ' + `${py} ${px} ` +
|
|
152
|
+
(iconPos == 'right' && Icon ? 'pr-[32px] pr-input-x-icon pl-input-x ' : '') +
|
|
153
|
+
(iconPos == 'left' && Icon ? 'pl-[32px] pl-input-x-icon pr-input-x ' : 'px-input-x ') +
|
|
154
|
+
(iconPos == 'left' && Icon && type == 'color' ? 'indent-[5px] ' : '') +
|
|
155
155
|
(error
|
|
156
156
|
? 'text-danger-foreground outline-danger focus:outline-danger '
|
|
157
157
|
: 'text-input outline-input-border focus:outline-input-border-focus ') +
|
|
@@ -166,8 +166,8 @@ function IconWrapper({ icon, iconPos, ...props }: IconWrapperProps) {
|
|
|
166
166
|
<div
|
|
167
167
|
{...props}
|
|
168
168
|
className={
|
|
169
|
-
'z-[0]
|
|
170
|
-
(iconPos == 'right' ? 'justify-self-end mr-
|
|
169
|
+
'z-[0] col-start-1 row-start-1 self-center text-[#c6c8ce] text-input-icon select-none [&>svg]:size-full ' +
|
|
170
|
+
(iconPos == 'right' ? 'justify-self-end mr-[12px] mr-input-x ' : 'justify-self-start ml-[12px] ml-input-x ') +
|
|
171
171
|
props.className || ''
|
|
172
172
|
}
|
|
173
173
|
>{icon}</div>
|
|
@@ -220,4 +220,8 @@ const style = css`
|
|
|
220
220
|
-webkit-appearance: none;
|
|
221
221
|
margin: 0;
|
|
222
222
|
}
|
|
223
|
+
/* tw4 we can use calc to determine the padding-left with css variables...
|
|
224
|
+
.inputt {
|
|
225
|
+
padding-left: calc(var(--input-x) * 2);
|
|
226
|
+
} */
|
|
223
227
|
`
|
|
@@ -5,7 +5,8 @@ import ReactSelect, {
|
|
|
5
5
|
components, ControlProps, createFilter, OptionProps, SingleValueProps, ClearIndicatorProps,
|
|
6
6
|
DropdownIndicatorProps, MultiValueRemoveProps,
|
|
7
7
|
} from 'react-select'
|
|
8
|
-
import {
|
|
8
|
+
import { CheckCircleIcon } from '@heroicons/react/20/solid'
|
|
9
|
+
import { ChevronsUpDownIcon, XIcon } from 'lucide-react'
|
|
9
10
|
import { isFieldCached } from 'nitro-web'
|
|
10
11
|
import { getErrorFromState, deepFind, twMerge } from 'nitro-web/util'
|
|
11
12
|
import { Errors } from 'nitro-web/types'
|
|
@@ -67,7 +68,7 @@ function SelectBase({ id, containerId, minMenuWidth, name, prefix='', onChange,
|
|
|
67
68
|
if (typeof state == 'object' && typeof value == 'undefined') value = ''
|
|
68
69
|
|
|
69
70
|
return (
|
|
70
|
-
<div css={style} class={
|
|
71
|
+
<div css={style} class={'mt-2.5 mb-6 ' + twMerge(`mt-input-before mb-input-after nitro-select ${props.className||''}`)}>
|
|
71
72
|
<ReactSelect
|
|
72
73
|
/**
|
|
73
74
|
* react-select prop quick reference (https://react-select.com/props#api):
|
|
@@ -211,7 +212,7 @@ function Option(props: OptionProps) {
|
|
|
211
212
|
<components.Option className={data.className} {...props}>
|
|
212
213
|
{ _nitro?.mode == 'country' && <Flag flag={data.flag} /> }
|
|
213
214
|
<span class="flex-auto">{props.label}</span>
|
|
214
|
-
{props.isSelected && <CheckCircleIcon className="size-[22px] text-primary -my-1 -mx-
|
|
215
|
+
{props.isSelected && <CheckCircleIcon className="size-[22px] text-primary -my-1 -mx-0.5" />}
|
|
215
216
|
</components.Option>
|
|
216
217
|
)
|
|
217
218
|
}
|
|
@@ -219,7 +220,7 @@ function Option(props: OptionProps) {
|
|
|
219
220
|
const DropdownIndicator = (props: DropdownIndicatorProps) => {
|
|
220
221
|
return (
|
|
221
222
|
<components.DropdownIndicator {...props}>
|
|
222
|
-
<
|
|
223
|
+
<ChevronsUpDownIcon size={15} className="text-gray-400 -my-0.5 -mx-[1px]" />
|
|
223
224
|
</components.DropdownIndicator>
|
|
224
225
|
)
|
|
225
226
|
}
|
|
@@ -227,7 +228,7 @@ const DropdownIndicator = (props: DropdownIndicatorProps) => {
|
|
|
227
228
|
const ClearIndicator = (props: ClearIndicatorProps) => {
|
|
228
229
|
return (
|
|
229
230
|
<components.ClearIndicator {...props}>
|
|
230
|
-
<
|
|
231
|
+
<XIcon size={14} />
|
|
231
232
|
</components.ClearIndicator>
|
|
232
233
|
)
|
|
233
234
|
}
|
|
@@ -235,7 +236,7 @@ const ClearIndicator = (props: ClearIndicatorProps) => {
|
|
|
235
236
|
const MultiValueRemove = (props: MultiValueRemoveProps) => {
|
|
236
237
|
return (
|
|
237
238
|
<components.MultiValueRemove {...props}>
|
|
238
|
-
<
|
|
239
|
+
<XIcon className="size-[1em] p-[1px]" />
|
|
239
240
|
</components.MultiValueRemove>
|
|
240
241
|
)
|
|
241
242
|
}
|
|
@@ -258,7 +259,7 @@ const selectStyles = {
|
|
|
258
259
|
focus: 'outline-2 -outline-offset-2 outline-input-border-focus',
|
|
259
260
|
error: 'outline-danger',
|
|
260
261
|
},
|
|
261
|
-
valueContainer: 'py-[9px] px-[12px] py-input-y px-input-x gap-1',
|
|
262
|
+
valueContainer: 'py-[9px] px-[12px] py-input-y px-input-x gap-1', // dont twMerge (input-x is optional)
|
|
262
263
|
// Input container objects
|
|
263
264
|
input: {
|
|
264
265
|
base: 'text-input',
|
|
@@ -187,10 +187,10 @@ export function Styleguide({ className, elements, children }: StyleguideProps) {
|
|
|
187
187
|
<div><Button color="primary" size="sm">*-sm button</Button></div>
|
|
188
188
|
<div><Button color="primary">*-md (default)</Button></div>
|
|
189
189
|
<div><Button color="primary" size="lg">*-lg button</Button></div>
|
|
190
|
-
<div><Button IconLeft={<Check size={19} className="-my-5
|
|
191
|
-
<div><Button IconLeft={<Check size={19} className="-my-5
|
|
190
|
+
<div><Button IconLeft={<Check size={19} className="-my-5" />}>IconLeft</Button></div>
|
|
191
|
+
<div><Button IconLeft={<Check size={19} className="-my-5" />}
|
|
192
192
|
className="w-[160px]">IconLeft 160px</Button></div>
|
|
193
|
-
<div><Button IconLeftEnd={<Check size={19} className="-my-5
|
|
193
|
+
<div><Button IconLeftEnd={<Check size={19} className="-my-5" />}
|
|
194
194
|
className="w-[190px]">IconLeftEnd 190px</Button></div>
|
|
195
195
|
<div><Button IconRight="v">IconRight</Button></div>
|
|
196
196
|
<div><Button IconRightEnd="v" className="w-[190px]">IconRightEnd 190px</Button></div>
|
|
@@ -204,18 +204,21 @@ export function Styleguide({ className, elements, children }: StyleguideProps) {
|
|
|
204
204
|
<div class="grid grid-cols-3 gap-x-6 mb-4">
|
|
205
205
|
<div>
|
|
206
206
|
<label for="input2">Label</label>
|
|
207
|
-
<Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0"
|
|
208
|
-
|
|
207
|
+
<Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0"
|
|
208
|
+
state={state} onChange={(e) => onChange(setState, e)} />
|
|
209
|
+
<Checkbox name="input3" type="toggle" text="Toggle 22px" subtext="some additional text here." size={22} />
|
|
209
210
|
</div>
|
|
210
211
|
<div>
|
|
211
212
|
<label for="input1">Label</label>
|
|
212
|
-
<Checkbox name="input1" type="radio" text="Radio
|
|
213
|
+
<Checkbox name="input1" type="radio" text="Radio" subtext="some additional text here 1." id="input1-1" class="!mb-0"
|
|
213
214
|
defaultChecked />
|
|
214
|
-
<Checkbox name="input1" type="radio" text="Radio
|
|
215
|
+
<Checkbox name="input1" type="radio" text="Radio 16px" subtext="some additional text here 2." id="input1-2" size={16} />
|
|
215
216
|
</div>
|
|
216
217
|
<div>
|
|
217
218
|
<label for="input0">Label</label>
|
|
218
|
-
<Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." defaultChecked />
|
|
219
|
+
<Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." class="!mb-0" defaultChecked />
|
|
220
|
+
<Checkbox name="input0.1" type="checkbox" text="Checkbox 16px" size={16}
|
|
221
|
+
subtext="some additional text here which is a bit longer that will be line-wrap to the next line." />
|
|
219
222
|
</div>
|
|
220
223
|
</div>
|
|
221
224
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.74",
|
|
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 🚀",
|
package/types/util.d.ts
CHANGED
|
@@ -721,18 +721,13 @@ export function toArray<T>(variable: T | undefined): (T extends any[] ? T : T[])
|
|
|
721
721
|
* @returns {string}
|
|
722
722
|
*/
|
|
723
723
|
export function trim(string: string): string;
|
|
724
|
-
/**
|
|
725
|
-
* Merge tailwind classes, but ignore classes that shouldn't be merged, and intended as an override
|
|
726
|
-
* @param {...string} args
|
|
727
|
-
* @returns {string}
|
|
728
|
-
*/
|
|
729
|
-
export function twMerge(...args: string[]): string;
|
|
730
724
|
/**
|
|
731
725
|
* Capitalize the first letter of a string
|
|
732
726
|
* @param {string} string
|
|
733
727
|
* @returns {string}
|
|
734
728
|
*/
|
|
735
729
|
export function ucFirst(string: string): string;
|
|
730
|
+
export const twMerge: (...classLists: import("tailwind-merge").ClassNameValue[]) => string;
|
|
736
731
|
/**
|
|
737
732
|
* Returns a list of response errors
|
|
738
733
|
*/
|
package/types/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"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"}
|
package/util.js
CHANGED
|
@@ -1675,31 +1675,75 @@ export function trim (string) {
|
|
|
1675
1675
|
return string.trim().replace(/\n\s+\n/g, '\n\n')
|
|
1676
1676
|
}
|
|
1677
1677
|
|
|
1678
|
-
|
|
1679
|
-
* Merge tailwind classes, but ignore classes that shouldn't be merged, and intended as an override
|
|
1680
|
-
* @param {...string} args
|
|
1681
|
-
* @returns {string}
|
|
1682
|
-
*/
|
|
1683
|
-
export function twMerge(...args) {
|
|
1684
|
-
const ignoredClasses = /** @type {string[]} */([])
|
|
1685
|
-
const ignoreClasses = [
|
|
1686
|
-
'text-button-xs',
|
|
1687
|
-
'text-button-sm',
|
|
1688
|
-
'text-button-md',
|
|
1689
|
-
'text-button-lg',
|
|
1690
|
-
'text-input-base',
|
|
1691
|
-
]
|
|
1692
|
-
const classes = args.filter(Boolean).join(' ').split(' ')
|
|
1678
|
+
import { createTailwindMerge, getDefaultConfig } from 'tailwind-merge'
|
|
1693
1679
|
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1680
|
+
// Create a custom twMerge instance
|
|
1681
|
+
export const twMerge = createTailwindMerge(() => {
|
|
1682
|
+
const config = getDefaultConfig()
|
|
1683
|
+
|
|
1684
|
+
/**
|
|
1685
|
+
* @param {string[]} baseNames - base names for x-axis (e.g. 'input-x')
|
|
1686
|
+
* @returns {object} extended classGroups with new spacing classes
|
|
1687
|
+
*/
|
|
1688
|
+
function newSpacingSizes(baseNames) {
|
|
1689
|
+
const obj = {
|
|
1690
|
+
pl: [...(/** @type {any} */(config.classGroups.pl) ?? [])],
|
|
1691
|
+
pr: [...(/** @type {any} */(config.classGroups.pr) ?? [])],
|
|
1692
|
+
pt: [...(/** @type {any} */(config.classGroups.pt) ?? [])],
|
|
1693
|
+
pb: [...(/** @type {any} */(config.classGroups.pb) ?? [])],
|
|
1694
|
+
px: [...(/** @type {any} */(config.classGroups.px) ?? [])],
|
|
1695
|
+
py: [...(/** @type {any} */(config.classGroups.py) ?? [])],
|
|
1696
|
+
p: [...(/** @type {any} */(config.classGroups.p) ?? [])],
|
|
1697
|
+
ml: [...(/** @type {any} */(config.classGroups.ml) ?? [])],
|
|
1698
|
+
mr: [...(/** @type {any} */(config.classGroups.mr) ?? [])],
|
|
1699
|
+
mt: [...(/** @type {any} */(config.classGroups.mt) ?? [])],
|
|
1700
|
+
mb: [...(/** @type {any} */(config.classGroups.mb) ?? [])],
|
|
1701
|
+
mx: [...(/** @type {any} */(config.classGroups.mx) ?? [])],
|
|
1702
|
+
my: [...(/** @type {any} */(config.classGroups.my) ?? [])],
|
|
1703
|
+
m: [...(/** @type {any} */(config.classGroups.m) ?? [])],
|
|
1704
|
+
gap: [...(/** @type {any} */(config.classGroups.gap) ?? [])],
|
|
1698
1705
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
}
|
|
1706
|
+
|
|
1707
|
+
// Add both axes classes
|
|
1708
|
+
for (const baseName of baseNames) {
|
|
1709
|
+
obj.pl.push(`pl-${baseName}`)
|
|
1710
|
+
obj.pr.push(`pr-${baseName}`)
|
|
1711
|
+
obj.pt.push(`pt-${baseName}`)
|
|
1712
|
+
obj.pb.push(`pb-${baseName}`)
|
|
1713
|
+
obj.px.push(`px-${baseName}`)
|
|
1714
|
+
obj.py.push(`py-${baseName}`)
|
|
1715
|
+
obj.p.push(`p-${baseName}`)
|
|
1716
|
+
obj.ml.push(`ml-${baseName}`)
|
|
1717
|
+
obj.mr.push(`mr-${baseName}`)
|
|
1718
|
+
obj.mt.push(`mt-${baseName}`)
|
|
1719
|
+
obj.mb.push(`mb-${baseName}`)
|
|
1720
|
+
obj.mx.push(`mx-${baseName}`)
|
|
1721
|
+
obj.my.push(`my-${baseName}`)
|
|
1722
|
+
obj.m.push(`m-${baseName}`)
|
|
1723
|
+
obj.gap.push(`gap-${baseName}`)
|
|
1724
|
+
}
|
|
1725
|
+
return obj
|
|
1726
|
+
}
|
|
1727
|
+
return {
|
|
1728
|
+
...config,
|
|
1729
|
+
classGroups: {
|
|
1730
|
+
...config.classGroups,
|
|
1731
|
+
...newSpacingSizes(['input-x', 'input-x-icon', 'input-y', 'input-before', 'input-after', 'input-icon']),
|
|
1732
|
+
'shadow': [...(config.classGroups.shadow || []), 'shadow-dropdown-ul'],
|
|
1733
|
+
'font-size': [...(config.classGroups['font-size'] || []), 'text-button-base', 'text-input-base'],
|
|
1734
|
+
},
|
|
1735
|
+
}
|
|
1736
|
+
// console.dir(
|
|
1737
|
+
// newSpacingSizes(['input-x', 'input-y', 'input-before', 'input-after']),
|
|
1738
|
+
// { depth: null }
|
|
1739
|
+
// )
|
|
1740
|
+
// console.log(customTwMerge('mb-1 mb-2 mb-input-x')) // mb-input-x
|
|
1741
|
+
// console.log(customTwMerge('mb-1 mb-2 my-input-y')) // my-input-y
|
|
1742
|
+
// console.log(customTwMerge('mb-1 my-input-y mb-2')) // my-input-y mb-2
|
|
1743
|
+
// console.log(customTwMerge('mb-1 my-input-y mb-2 my-input-x')) // my-input-x
|
|
1744
|
+
// console.log(customTwMerge('mx-1 my-input-y mb-2 my-input-x')) // mx-1 my-input-x
|
|
1745
|
+
// console.log(customTwMerge('text-xs text-base text-input text-button-base'))
|
|
1746
|
+
})
|
|
1703
1747
|
|
|
1704
1748
|
/**
|
|
1705
1749
|
* Capitalize the first letter of a string
|