nitro-web 0.0.113 → 0.0.115
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/components/partials/element/dropdown.tsx +5 -2
- package/components/partials/element/table.tsx +4 -3
- package/components/partials/form/field-currency.tsx +0 -1
- package/components/partials/form/field.tsx +5 -5
- package/components/partials/styleguide.tsx +4 -0
- package/package.json +1 -1
- package/types/util.d.ts +15 -1
- package/types/util.d.ts.map +1 -1
- package/util.js +33 -27
|
@@ -17,6 +17,8 @@ type DropdownProps = {
|
|
|
17
17
|
isSelected?: boolean,
|
|
18
18
|
icon?: React.ReactNode,
|
|
19
19
|
iconLeft?: React.ReactNode,
|
|
20
|
+
/** Prevent the dropdown from closing when the option is clicked */
|
|
21
|
+
preventCloseOnClick?: boolean,
|
|
20
22
|
className?: string
|
|
21
23
|
}[]
|
|
22
24
|
/** Whether the dropdown is hoverable **/
|
|
@@ -25,6 +27,7 @@ type DropdownProps = {
|
|
|
25
27
|
menuContent?: React.ReactNode
|
|
26
28
|
menuClassName?: string
|
|
27
29
|
menuOptionClassName?: string
|
|
30
|
+
/** force open the menu */
|
|
28
31
|
menuIsOpen?: boolean
|
|
29
32
|
menuToggles?: boolean
|
|
30
33
|
/** The minimum width of the menu **/
|
|
@@ -137,9 +140,9 @@ export const Dropdown = forwardRef(function Dropdown({
|
|
|
137
140
|
if (!isHoverable && !menuIsOpen && ((menuToggles || e.key) || !isActive)) setIsActive(!isActive)
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
function onClick(option: { onClick?: Function }, e: React.MouseEvent) {
|
|
143
|
+
function onClick(option: { onClick?: Function, preventCloseOnClick?: boolean }, e: React.MouseEvent) {
|
|
141
144
|
if (option.onClick) option.onClick(e)
|
|
142
|
-
if (!menuIsOpen) setIsActive(!isActive)
|
|
145
|
+
if (!menuIsOpen && !option?.preventCloseOnClick) setIsActive(!isActive)
|
|
143
146
|
}
|
|
144
147
|
|
|
145
148
|
return (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { JSX, useState, useCallback } from 'react'
|
|
1
|
+
import { JSX, useState, useCallback, Fragment } from 'react'
|
|
2
2
|
import { ChevronDownIcon, ChevronUpIcon } from 'lucide-react'
|
|
3
3
|
import { Checkbox, queryObject, queryString, twMerge } from 'nitro-web'
|
|
4
4
|
|
|
@@ -142,7 +142,7 @@ export function Table<T extends TableRow>({
|
|
|
142
142
|
const pl = sideColorPadding + (j == 0 ? columnPaddingX : columnGap)
|
|
143
143
|
const pr = j == columns.length - 1 ? columnPaddingX : columnGap
|
|
144
144
|
|
|
145
|
-
if(col.isHidden) return
|
|
145
|
+
if (col.isHidden) return <Fragment key={j} />
|
|
146
146
|
return (
|
|
147
147
|
<div
|
|
148
148
|
key={j}
|
|
@@ -213,6 +213,7 @@ export function Table<T extends TableRow>({
|
|
|
213
213
|
return (
|
|
214
214
|
<div
|
|
215
215
|
key={`${row._id}-${i}`}
|
|
216
|
+
id={`row-${row._id}-${i}`}
|
|
216
217
|
onClick={rowOnClick ? () => rowOnClick(row) : undefined}
|
|
217
218
|
className={twMerge(
|
|
218
219
|
`table-row relative ${rowOnClick ? 'cursor-pointer' : ''} ${isSelected ? 'is-selected' : ''}`, rowClassName
|
|
@@ -224,7 +225,7 @@ export function Table<T extends TableRow>({
|
|
|
224
225
|
const pl = j == 0 ? columnPaddingX : columnGap
|
|
225
226
|
const pr = j == columns.length - 1 ? columnPaddingX : columnGap
|
|
226
227
|
|
|
227
|
-
if(col.isHidden) return
|
|
228
|
+
if (col.isHidden) return <Fragment key={j} />
|
|
228
229
|
return (
|
|
229
230
|
<div
|
|
230
231
|
key={j}
|
|
@@ -7,7 +7,7 @@ import { Errors, type Error } from 'nitro-web/types'
|
|
|
7
7
|
import { MailIcon, CalendarIcon, FunnelIcon, SearchIcon, EyeIcon, EyeOffIcon } from 'lucide-react'
|
|
8
8
|
import { memo } from 'react'
|
|
9
9
|
|
|
10
|
-
type FieldType = 'text' | 'password' | 'email' | 'filter' | 'search' | 'textarea' | 'currency' | 'date' | 'color'
|
|
10
|
+
type FieldType = 'text' | 'number' | 'password' | 'email' | 'filter' | 'search' | 'textarea' | 'currency' | 'date' | 'color'
|
|
11
11
|
type InputProps = React.InputHTMLAttributes<HTMLInputElement>
|
|
12
12
|
type TextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement>
|
|
13
13
|
type FieldExtraProps = {
|
|
@@ -35,7 +35,7 @@ type IconWrapperProps = {
|
|
|
35
35
|
}
|
|
36
36
|
// Discriminated union (https://stackoverflow.com/a/77351290/1900648)
|
|
37
37
|
export type FieldProps = (
|
|
38
|
-
| ({ type?: 'text' | 'password' | 'email' | 'filter' | 'search' } & InputProps & FieldExtraProps)
|
|
38
|
+
| ({ type?: 'text' | 'number' | 'password' | 'email' | 'filter' | 'search' } & InputProps & FieldExtraProps)
|
|
39
39
|
| ({ type: 'textarea' } & TextareaProps & FieldExtraProps)
|
|
40
40
|
| ({ type: 'currency' } & FieldCurrencyProps & FieldExtraProps)
|
|
41
41
|
| ({ type: 'color' } & FieldColorProps & FieldExtraProps)
|
|
@@ -67,7 +67,7 @@ function FieldBase({ state, icon, iconPos: ip, errorTitle, ...props }: FieldProp
|
|
|
67
67
|
|
|
68
68
|
// Input type
|
|
69
69
|
const [inputType, setInputType] = useState(() => { // eslint-disable-line
|
|
70
|
-
return type == 'password' ? 'password' : (type == 'textarea' ? 'textarea' : 'text')
|
|
70
|
+
return type == 'password' ? 'password' : (type == 'textarea' ? 'textarea' : (type == 'number' ? 'number' : 'text'))
|
|
71
71
|
})
|
|
72
72
|
|
|
73
73
|
// Value: Input is always controlled if state is passed in
|
|
@@ -76,7 +76,7 @@ function FieldBase({ state, icon, iconPos: ip, errorTitle, ...props }: FieldProp
|
|
|
76
76
|
const v = deepFind(state, props.name) as string | undefined
|
|
77
77
|
value = v ?? ''
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
// Icon
|
|
81
81
|
if (type == 'password') {
|
|
82
82
|
Icon = <IconWrapper
|
|
@@ -104,7 +104,7 @@ function FieldBase({ state, icon, iconPos: ip, errorTitle, ...props }: FieldProp
|
|
|
104
104
|
const commonProps = { id: id, value: value, className: inputClassName }
|
|
105
105
|
|
|
106
106
|
// Type has to be referenced as props.type for TS to be happy
|
|
107
|
-
if (!type || type == 'text' || type == 'password' || type == 'email' || type == 'filter' || type == 'search') {
|
|
107
|
+
if (!type || type == 'text' || type == 'number' || type == 'password' || type == 'email' || type == 'filter' || type == 'search') {
|
|
108
108
|
return (
|
|
109
109
|
<FieldContainer error={error} className={props.className}>
|
|
110
110
|
{Icon}<input {...props} {...commonProps} type={inputType} />
|
|
@@ -412,6 +412,10 @@ export function Styleguide({ className, elements, children, currencies }: Styleg
|
|
|
412
412
|
</div>
|
|
413
413
|
<Field name="password" type="password"/>
|
|
414
414
|
</div>
|
|
415
|
+
<div>
|
|
416
|
+
<label for="search3number">Number</label>
|
|
417
|
+
<Field name="number" id="search3number" type="number" placeholder="Number..." />
|
|
418
|
+
</div>
|
|
415
419
|
<div>
|
|
416
420
|
<label for="search3">Search</label>
|
|
417
421
|
<Field name="search" id="search3" type="search" placeholder="Search..." />
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nitro-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.115",
|
|
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
|
@@ -171,7 +171,20 @@ export function deepFind(obj: object | any[], path: string): unknown;
|
|
|
171
171
|
* @param {unknown|function} value - The value to set, or a function to compute it from the current value.
|
|
172
172
|
* @returns {T}
|
|
173
173
|
*/
|
|
174
|
-
export function
|
|
174
|
+
export function deepSet<T>(obj: T, path: string, value: unknown | Function): T;
|
|
175
|
+
/**
|
|
176
|
+
* Sets a deeply nested value without mutating the original object.
|
|
177
|
+
* @template T
|
|
178
|
+
* @param {T} _obj - The target object or array.
|
|
179
|
+
* @param {string} path - Dot-separated path to the nested property.
|
|
180
|
+
* @param {unknown|function} value - The value to set, or a function to compute it from the current value.
|
|
181
|
+
* @returns {{ obj: T, parent: T, fieldName: string }}
|
|
182
|
+
*/
|
|
183
|
+
export function deepSetWithInfo<T>(_obj: T, path: string, value: unknown | Function): {
|
|
184
|
+
obj: T;
|
|
185
|
+
parent: T;
|
|
186
|
+
fieldName: string;
|
|
187
|
+
};
|
|
175
188
|
/**
|
|
176
189
|
* Iterates over an object or array
|
|
177
190
|
* @param {{[key: string]: any}|[]|null} obj
|
|
@@ -488,6 +501,7 @@ export function omit(obj: {
|
|
|
488
501
|
* @template T
|
|
489
502
|
* @param {React.Dispatch<React.SetStateAction<T>>} setState
|
|
490
503
|
* @param {{target: {name: string, value: unknown}}|[string, function|unknown]} eventOrPathValue
|
|
504
|
+
* - The input/select change event or path/value pair to update the state with
|
|
491
505
|
* @param {Function} [beforeSetState] - optional function to run before setting the state
|
|
492
506
|
* @returns {Promise<T>}
|
|
493
507
|
*
|
package/types/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"AAoCA;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BC;AAED;;;;;;;;;GASG;AACH,yBARa,sBAAsB,CAoBlC;AAED;;;;;GAKG;AACH,8BAJW,MAAM,cACN;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,GACrB,MAAM,CAKlB;AAED;;;;;;GAMG;AACH,+BALW,MAAM,oBACN,OAAO,gBACP,OAAO,GACL,MAAM,CAelB;AAED;;;;;GAKG;AACH,sCAJW,MAAM,wBACN,OAAO,GACL,MAAM,CAMlB;AAED;;;;GAIG;AACH,sCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;GAIG;AACH,iCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;GAMG;AACH,gCALW,MAAM,aACN,MAAM,oBACN,MAAM,GACJ,MAAM,CAUlB;AAED;;;;GAIG;AACH,0CAHW,MAAM,GACJ,MAAM,CAMlB;AAED;;;;;;;;;;;GAWG;AACH,4BAVW,MAAM,GAAC,IAAI,WACX,MAAM,aACN,MAAM,GACJ,MAAM,CAsBlB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,yBAlBuC,CAAC,SAA3B,CAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAI,QAI3B,CAAC,SACD,MAAM,YACN;IACN,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GACS,CAAC,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG;IACpD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,KAAK,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,CAAA;CAC7B,CAuKH;AAED;;;;;GAKG;AACH,yBAJa,CAAC,OACH,CAAC,GACC,CAAC,CAgBb;AAED;;;;;GAKG;AACH,8BAJW,MAAM,GAAC,GAAG,EAAE,QACZ,MAAM,GACJ,OAAO,CAgBnB;AAED;;;;;;;GAOG;AACH,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"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"}
|
package/util.js
CHANGED
|
@@ -450,36 +450,52 @@ export function deepFind(obj, path) {
|
|
|
450
450
|
* @param {unknown|function} value - The value to set, or a function to compute it from the current value.
|
|
451
451
|
* @returns {T}
|
|
452
452
|
*/
|
|
453
|
-
export function
|
|
453
|
+
export function deepSet(obj, path, value) {
|
|
454
454
|
if (obj === null || obj === undefined) return obj
|
|
455
|
+
return deepSetWithInfo(obj, path, value).obj
|
|
456
|
+
}
|
|
455
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Sets a deeply nested value without mutating the original object.
|
|
460
|
+
* @template T
|
|
461
|
+
* @param {T} _obj - The target object or array.
|
|
462
|
+
* @param {string} path - Dot-separated path to the nested property.
|
|
463
|
+
* @param {unknown|function} value - The value to set, or a function to compute it from the current value.
|
|
464
|
+
* @returns {{ obj: T, parent: T, fieldName: string }}
|
|
465
|
+
*/
|
|
466
|
+
export function deepSetWithInfo(_obj, path, value) {
|
|
456
467
|
/** @type {any} */
|
|
457
|
-
let
|
|
458
|
-
let
|
|
459
|
-
|
|
468
|
+
let obj = Array.isArray(_obj) ? [..._obj] : { ..._obj }
|
|
469
|
+
let parent = obj
|
|
470
|
+
const chunks = (path || '').split('.')
|
|
460
471
|
|
|
461
472
|
for (let i = 0, l = chunks.length; i < l; i++) {
|
|
462
473
|
const key = chunks[i]
|
|
463
474
|
const isLast = i === l - 1
|
|
464
475
|
|
|
465
476
|
if (isLast) {
|
|
466
|
-
|
|
477
|
+
// was obj for onChange()
|
|
478
|
+
parent[key] = typeof value === 'function' ? value(parent[key]) : value
|
|
467
479
|
} else {
|
|
468
480
|
const nextIsArray = /^\d+$/.test(chunks[i + 1])
|
|
469
|
-
const current =
|
|
481
|
+
const current = parent[key]
|
|
470
482
|
|
|
471
483
|
// If the next level doesn't exist, create an empty array/object
|
|
472
484
|
const parentCopy = nextIsArray
|
|
473
485
|
? Array.isArray(current) ? [...current] : []
|
|
474
486
|
: isObject(current) ? { ...current } : {}
|
|
475
487
|
|
|
476
|
-
|
|
488
|
+
parent = parent[key] = parentCopy
|
|
477
489
|
}
|
|
478
490
|
}
|
|
479
|
-
|
|
480
|
-
|
|
491
|
+
return {
|
|
492
|
+
obj: obj,
|
|
493
|
+
parent: parent,
|
|
494
|
+
fieldName: chunks.pop() ?? '',
|
|
495
|
+
}
|
|
481
496
|
}
|
|
482
497
|
|
|
498
|
+
|
|
483
499
|
/**
|
|
484
500
|
* Iterates over an object or array
|
|
485
501
|
* @param {{[key: string]: any}|[]|null} obj
|
|
@@ -1142,7 +1158,8 @@ export function omit (obj, fields) {
|
|
|
1142
1158
|
*
|
|
1143
1159
|
* @template T
|
|
1144
1160
|
* @param {React.Dispatch<React.SetStateAction<T>>} setState
|
|
1145
|
-
* @param {{target: {name: string, value: unknown}}|[string, function|unknown]} eventOrPathValue
|
|
1161
|
+
* @param {{target: {name: string, value: unknown}}|[string, function|unknown]} eventOrPathValue
|
|
1162
|
+
* - The input/select change event or path/value pair to update the state with
|
|
1146
1163
|
* @param {Function} [beforeSetState] - optional function to run before setting the state
|
|
1147
1164
|
* @returns {Promise<T>}
|
|
1148
1165
|
*
|
|
@@ -1153,14 +1170,14 @@ export function omit (obj, fields) {
|
|
|
1153
1170
|
export function onChange (setState, eventOrPathValue, beforeSetState) {
|
|
1154
1171
|
/** @type {unknown|function} */
|
|
1155
1172
|
let value
|
|
1156
|
-
/** @type {string
|
|
1157
|
-
let
|
|
1173
|
+
/** @type {string} */
|
|
1174
|
+
let path = ''
|
|
1158
1175
|
/** @type {boolean} */
|
|
1159
1176
|
let hasFiles
|
|
1160
1177
|
|
|
1161
1178
|
if (typeof eventOrPathValue === 'object' && 'target' in eventOrPathValue) {
|
|
1162
1179
|
const element = /** @type {HTMLInputElement & {_value?: unknown}} */(eventOrPathValue.target) // we need to assume this is an input
|
|
1163
|
-
|
|
1180
|
+
path = (element.name || element.id)
|
|
1164
1181
|
hasFiles = !!element.files
|
|
1165
1182
|
value = element.files
|
|
1166
1183
|
? element.files[0]
|
|
@@ -1171,7 +1188,7 @@ export function onChange (setState, eventOrPathValue, beforeSetState) {
|
|
|
1171
1188
|
: element.value
|
|
1172
1189
|
|
|
1173
1190
|
} else if (Array.isArray(eventOrPathValue)) {
|
|
1174
|
-
|
|
1191
|
+
path = eventOrPathValue[0]
|
|
1175
1192
|
value = eventOrPathValue[1]
|
|
1176
1193
|
}
|
|
1177
1194
|
|
|
@@ -1184,20 +1201,9 @@ export function onChange (setState, eventOrPathValue, beforeSetState) {
|
|
|
1184
1201
|
return new Promise((resolve) => {
|
|
1185
1202
|
setState((state) => {
|
|
1186
1203
|
/** @type {{[key: string]: any}} */
|
|
1187
|
-
const newState = { ...state, ...(hasFiles ? { hasFiles } : {}) }
|
|
1188
|
-
let target = newState
|
|
1189
|
-
for (var i = 0, l = chunks.length; i < l; i++) {
|
|
1190
|
-
if (l === i + 1) { // Last
|
|
1191
|
-
target[chunks[i]] = typeof value === 'function' ? value(state) : value
|
|
1192
|
-
// console.log(target)
|
|
1193
|
-
} else {
|
|
1194
|
-
let isArray = chunks[i + 1].match(/^[0-9]+$/)
|
|
1195
|
-
let parentCopy = isArray ? [...(target[chunks[i]] || [])] : { ...(target[chunks[i]] || {}) }
|
|
1196
|
-
target = target[chunks[i]] = parentCopy
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1204
|
+
const { obj: newState, parent, fieldName } = deepSetWithInfo({ ...state, ...(hasFiles ? { hasFiles } : {}) }, path, value)
|
|
1199
1205
|
if (beforeSetState) {
|
|
1200
|
-
beforeSetState({ newState
|
|
1206
|
+
beforeSetState({ newState, fieldName, parent })
|
|
1201
1207
|
}
|
|
1202
1208
|
resolve(/** @type {T} */(newState))
|
|
1203
1209
|
return /** @type {T} */(newState)
|