nitro-web 0.0.138 → 0.0.140

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.
@@ -157,7 +157,10 @@ function FieldBase({ state, icon, iconPos: ip, errorTitle, ...props }: FieldProp
157
157
 
158
158
  function FieldContainer({ children, className, error }: { children: React.ReactNode, className?: string, error?: Error }) {
159
159
  return (
160
- <div css={style} className={'mt-2.5 mb-6 ' + twMerge(`mt-input-before mb-input-after grid grid-cols-1 nitro-field ${className || ''}`)}>
160
+ <div
161
+ css={style}
162
+ className={twMerge('(mt-2.5 mb-6 mt-input-before mb-input-after) grid grid-cols-1 nitro-field', className || '')}
163
+ >
161
164
  {children}
162
165
  {error && <div class="mt-1.5 text-xs text-danger-foreground nitro-error">{error.detail}</div>}
163
166
  </div>
@@ -246,4 +249,4 @@ const style = css`
246
249
  .inputt {
247
250
  padding-left: calc(var(--input-x) * 2);
248
251
  } */
249
- `
252
+ `
@@ -20,14 +20,27 @@ type GetSelectStyle = {
20
20
  hasError?: boolean
21
21
  usePrefixes?: boolean
22
22
  }
23
- export type SelectOption = {
24
- value: unknown,
25
- label: string | React.ReactNode,
26
- fixed?: boolean,
27
- data?: { [key: string]: unknown }
23
+ export type SelectOption<TValue, TData = unknown> = {
24
+ value: TValue
25
+ label: string | React.ReactNode
26
+ fixed?: boolean
27
+ data?: TData
28
28
  }
29
+
30
+ // Example of what the generic types need to handle:
31
+ // title: 'Employee Name',
32
+ // name: 'employee',
33
+ // type: 'select',
34
+ // value: state.employee?._id,
35
+ // options: userOptions,
36
+ // onChange: (e) => handleSelectChange(e, setState, (value): TimesheetState['employee'] => {
37
+ // const employeeValue = value as Id | undefined
38
+ // const employee = userOptions?.find(o => o._id === employeeValue)
39
+ // return employee
40
+ // }),
41
+
29
42
  /** Select (all other props are passed to react-select) **/
30
- export type SelectProps = {
43
+ export type SelectProps<TValue = unknown, TOption extends SelectOption<TValue, TData> = SelectOption<TValue, TData>> = {
31
44
  /** field name or path on state (used to match errors), e.g. 'date', 'company.email' **/
32
45
  name: string
33
46
  /** inputId, the name is used if not provided **/
@@ -39,7 +52,13 @@ export type SelectProps = {
39
52
  /** The prefix to add to the input **/
40
53
  prefix?: string
41
54
  /** The onChange handler **/
42
- onChange?: (event: { target: { name: string, value: unknown } }) => void
55
+ ////////
56
+ onChange?: (
57
+ event: { target: { name: string; value: TValue | TValue[] } },
58
+ option: TOption | TOption[] | null
59
+ ) => void
60
+
61
+ onChange?: (event: { target: { name: string, value: unknown } }) => void // todo-ricky: add second parameter to return the selected option generic?
43
62
  /** The options to display in the dropdown, data is used to pass additional data to the option **/
44
63
  options: SelectOption[]
45
64
  /** The state object to get the value and check errors from **/
@@ -35,6 +35,21 @@ export function Styleguide({ className, elements, children, currencies }: Styleg
35
35
  const [, setStore] = useTracked()
36
36
  const [customerSearch, setCustomerSearch] = useState('')
37
37
  const [showModal1, setShowModal1] = useState(false)
38
+ // Tip: handy when developing or updating components, you can hide/show the groups you want to see
39
+ const groups = [
40
+ // 'Links',
41
+ // 'Dropdowns',
42
+ // 'Filters',
43
+ // 'Buttons',
44
+ // 'Varients',
45
+ // 'Selects',
46
+ 'Inputs',
47
+ // 'Date Inputs',
48
+ // 'File Inputs & Calendar',
49
+ 'Tables',
50
+ // 'Modals',
51
+ // 'Custom Components',
52
+ ]
38
53
  const [state, setState] = useState({
39
54
  address: '',
40
55
  amount: 100,
@@ -180,378 +195,425 @@ export function Styleguide({ className, elements, children, currencies }: Styleg
180
195
  // }, [])
181
196
 
182
197
  return (
183
- <div class={`text-left max-w-[1100px] ${className}`}>
184
- <Modal show={showModal1} setShow={setShowModal1}>
185
- <h3 class="h3">Edit Profile</h3>
186
- <p class="mb-5">An example modal containing a basic form for editing profiles.</p>
187
- <form class="mb-8 text-left">
188
- <div>
189
- <label for="firstName2">First Name</label>
190
- <Field name="firstName2" state={state} onChange={(e) => onChange(e, setState)} />
191
- </div>
192
- <div>
193
- <label for="email2">Email Address</label>
194
- <Field name="email2" type="email" placeholder="Your email address..."/>
195
- </div>
196
- </form>
197
- <div class="flex justify-end">
198
- <Button color="primary" onClick={() => setShowModal1(false)}>Save</Button>
199
- </div>
200
- </Modal>
201
-
202
- <GithubLink filename={__filename} />
203
- <div class="mb-7">
198
+ <div class={`text-left max-w-[1100px] flex flex-col gap-4 pb-2 ${className}`}>
199
+ <div>
204
200
  <h1 class="h1">{injectedConfig.isDemo ? 'Design System' : 'Style Guide'}</h1>
205
- <p>
201
+ <p class="mb-3">
206
202
  Components are styled using&nbsp;
207
203
  <a href="https://v3.tailwindcss.com/docs/configuration" class="underline" target="_blank" rel="noreferrer">TailwindCSS</a>.
208
204
  </p>
209
205
  </div>
210
206
 
211
- <h2 class="h3">Links</h2>
212
- <div class="mb-10">
213
- <a class="mr-2" href="#">Default</a>
214
- <a class="underline1 is-active mr-2" href="#">Underline1</a>
215
- <a class="underline2 is-active mr-2" href="#">Underline2</a>
216
- </div>
217
-
218
- <h2 class="h3">Modals</h2>
219
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
220
- <div><Button color="primary" onClick={() => setShowModal1(true)}>Modal (default)</Button></div>
221
- </div>
222
-
223
- <h2 class="h3">Dropdowns</h2>
224
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
207
+ {groups.includes('Links') && (
225
208
  <div>
226
- <Dropdown options={options} minWidth="250px">
227
- <Button IconRight="v" class="gap-x-3">Dropdown</Button>
228
- </Dropdown>
229
- </div>
230
- <div>
231
- <Dropdown
232
- // menuIsOpen={true}
233
- dir="bottom-right"
234
- minWidth="330px"
235
- options={[{ label: <><b>New Customer</b> / Add <b>Bruce Lee</b></>, className: 'border-bottom-with-space' }, ...options]}
236
- >
237
- <Button color="white" IconRight="v" class="gap-x-3">Dropdown bottom-right</Button>
238
- </Dropdown>
209
+ <h2 class="h3">Links</h2>
210
+ <div class="mb-6">
211
+ <a class="mr-2" href="#">Default</a>
212
+ <a class="underline1 is-active mr-2" href="#">Underline1</a>
213
+ <a class="underline2 is-active mr-2" href="#">Underline2</a>
214
+ </div>
239
215
  </div>
216
+ )}
217
+
218
+ {groups.includes('Dropdowns') && (
240
219
  <div>
241
- <Dropdown options={options} dir="top-left" minWidth="250px">
242
- <Button color="white" IconRight="v" class="gap-x-3">Dropdown top-left</Button>
243
- </Dropdown>
220
+ <h2 class="h3">Dropdowns</h2>
221
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-6">
222
+ <div>
223
+ <Dropdown options={options} minWidth="250px">
224
+ <Button IconRight="v" class="gap-x-3">Dropdown</Button>
225
+ </Dropdown>
226
+ </div>
227
+ <div>
228
+ <Dropdown
229
+ // menuIsOpen={true}
230
+ dir="bottom-right"
231
+ minWidth="330px"
232
+ options={[{ label: <><b>New Customer</b> / Add <b>Bruce Lee</b></>, className: 'border-bottom-with-space' }, ...options]}
233
+ >
234
+ <Button color="white" IconRight="v" class="gap-x-3">Dropdown bottom-right</Button>
235
+ </Dropdown>
236
+ </div>
237
+ <div>
238
+ <Dropdown options={options} dir="top-left" minWidth="250px">
239
+ <Button color="white" IconRight="v" class="gap-x-3">Dropdown top-left</Button>
240
+ </Dropdown>
241
+ </div>
242
+ </div>
244
243
  </div>
245
- </div>
246
-
247
- <h2 class="h3">Filters</h2>
248
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
249
- {/* Filter dropdown */}
250
- <Filters
251
- ref={filtersRef}
252
- filters={filters}
253
- state={filterState}
254
- setState={setFilterState}
255
- dropdownProps={{ dir: 'bottom-left' }}
256
- elements={{ Button: Button }}
257
- />
258
- {/* Search bar */}
259
- <Field
260
- class="!my-0 min-w-[242px]"
261
- type="search"
262
- name="search"
263
- id="search2"
264
- iconPos="left"
265
- state={filterState}
266
- onChange={(e) => {
267
- onChange(e, setFilterState)
268
- filtersRef.current?.submit()
269
- }}
270
- placeholder="Linked search bar..."
271
- />
272
- </div>
273
-
274
- <h2 class="h3">Buttons</h2>
275
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
276
- <div><Button color="primary">primary (default)</Button></div>
277
- <div><Button color="secondary">secondary button</Button></div>
278
- <div><Button color="black">black button</Button></div>
279
- <div><Button color="dark">dark button</Button></div>
280
- <div><Button color="white">white button</Button></div>
281
- <div><Button color="clear">clear button</Button></div>
282
- <div><Button color="primary" size="xs">*-xs button</Button></div>
283
- <div><Button color="primary" size="sm">*-sm button</Button></div>
284
- <div><Button color="primary">*-md (default)</Button></div>
285
- <div><Button color="primary" size="lg">*-lg button</Button></div>
286
- <div><Button IconLeft={<Check size={19} className="-my-5" />}>IconLeft</Button></div>
287
- <div><Button IconLeft={<Check size={19} className="-my-5" />}
288
- className="w-[160px]">IconLeft 160px</Button></div>
289
- <div><Button IconLeftEnd={<Check size={19} className="-my-5" />}
290
- className="w-[190px]">IconLeftEnd 190px</Button></div>
291
- <div><Button IconRight="v">IconRight</Button></div>
292
- <div><Button IconRightEnd="v" className="w-[190px]">IconRightEnd 190px</Button></div>
293
- <div><Button color="primary" IconRight="v" isLoading>primary isLoading</Button></div>
294
- <div><Button IconCenter={<FileEditIcon size={18}/>}></Button></div>
295
- <div><Button size="sm" IconCenter={<FileEditIcon size={16}/>}></Button></div>
296
- <div><Button size="xs" IconCenter={<FileEditIcon size={14}/>}></Button></div>
297
- </div>
244
+ )}
298
245
 
299
- <h2 class="h3">Varients</h2>
300
- <div class="grid grid-cols-3 gap-x-6 mb-4">
246
+ {groups.includes('Filters') && (
301
247
  <div>
302
- <label for="input2">Toggles</label>
303
- <Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0"
304
- state={state} onChange={(e) => onChange(e, setState)} />
305
- <Checkbox name="input3" type="toggle" text="Toggle 22px" subtext="some additional text here." size={22} />
306
- </div>
307
- <div>
308
- <label for="input1">Radios</label>
309
- <Checkbox name="input1" type="radio" text="Radio" subtext="some additional text here 1." id="input1-1" class="!mb-0"
310
- defaultChecked />
311
- <Checkbox name="input1" type="radio" text="Radio 16px" subtext="some additional text here 2." id="input1-2" size={16} />
312
- </div>
313
- <div>
314
- <label for="input0">Checkboxes</label>
315
- <Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." class="!mb-0" defaultChecked />
316
- <Checkbox name="input0.1" type="checkbox" text="Checkbox 16px" size={16}
317
- subtext="some additional text here which is a bit longer that will be line-wrap to the next line." />
248
+ <h2 class="h3">Filters</h2>
249
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-6">
250
+ {/* Filter dropdown */}
251
+ <Filters
252
+ ref={filtersRef}
253
+ filters={filters}
254
+ state={filterState}
255
+ setState={setFilterState}
256
+ dropdownProps={{ dir: 'bottom-left' }}
257
+ elements={{ Button: Button }}
258
+ />
259
+ {/* Search bar */}
260
+ <Field
261
+ class="!my-0 min-w-[242px]"
262
+ type="search"
263
+ name="search"
264
+ id="search2"
265
+ iconPos="left"
266
+ state={filterState}
267
+ onChange={(e) => {
268
+ onChange(e, setFilterState)
269
+ filtersRef.current?.submit()
270
+ }}
271
+ placeholder="Linked search bar..."
272
+ />
273
+ </div>
318
274
  </div>
319
- </div>
275
+ )}
320
276
 
321
- <h2 class="h3">Selects</h2>
322
- <div class="grid grid-cols-3 lg:grid-cols-3 gap-x-6 mb-4">
323
- <div>
324
- <label for="action">Default</label>
325
- <Select
326
- // menuIsOpen={true}
327
- name="action"
328
- isSearchable={false}
329
- options={useMemo(() => [
330
- { value: 'edit', label: 'Edit' },
331
- { value: 'delete', label: 'Delete' },
332
- ], [])}
333
- />
334
- </div>
335
- <div>
336
- <label for="colorsMulti">Mutli Select</label>
337
- <Select
338
- name="colorsMulti"
339
- isMulti={true}
340
- state={state}
341
- options={useMemo(() => [
342
- { value: 'blue', label: 'Blue' },
343
- { value: 'green', label: 'Green' },
344
- { value: 'yellow', label: 'Yellow' },
345
- { value: 'red', label: 'Red' },
346
- { value: 'orange', label: 'Orange' },
347
- { value: 'purple', label: 'Purple' },
348
- { value: 'pink', label: 'Pink' },
349
- { value: 'gray', label: 'Gray' },
350
- { value: 'black', label: 'Black' },
351
- { value: 'white', label: 'White' },
352
- ], [])}
353
- onChange={(e) => onChange(e, setState)}
354
- />
355
- </div>
277
+ {groups.includes('Buttons') && (
356
278
  <div>
357
- <label for="country">Countries</label>
358
- <Select
359
- // https://github.com/lipis/flag-icons
360
- name="country"
361
- mode="country"
362
- state={state}
363
- options={useMemo(() => [{ value: 'nz', label: 'New Zealand' }, { value: 'au', label: 'Australia' }], [])}
364
- onChange={(e) => onChange(e, setState)}
365
- />
366
- </div>
367
- <div>
368
- <label for="customer">List Item with Action</label>
369
- <Select
370
- // menuIsOpen={true}
371
- placeholder="Select or add customer..."
372
- name="customer"
373
- mode="customer"
374
- state={state}
375
- onChange={onCustomerInputChange}
376
- onInputChange={onCustomerSearch}
377
- options={useMemo(() => [
378
- {
379
- className: 'bb',
380
- fixed: true,
381
- value: '0',
382
- label: (
383
- <>
384
- <b>New Customer</b> (and clear select)
385
- {customerSearch ? <> / Add <b>{ucFirst(customerSearch)}</b></> : ''}
386
- </>
387
- ),
388
- },
389
- { value: '1', label: 'Iron Man Industries' },
390
- { value: '2', label: 'Captain America' },
391
- { value: '3', label: 'Thor Limited' },
392
- ], [customerSearch])}
393
- />
394
- </div>
395
- <div>
396
- <label for="currency">Currencies</label>
397
- <Select
398
- name="currency"
399
- state={state}
400
- options={useMemo(() => (currencies ? getCurrencyOptions(currencies) : [{ value: 'nzd', label: 'New Zealand Dollar' }, { value: 'aud', label: 'Australian Dollar' }]), [])}
401
- onChange={(e) => onChange(e, setState)}
402
- />
279
+ <h2 class="h3">Buttons</h2>
280
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-6">
281
+ <div><Button color="primary">primary (default)</Button></div>
282
+ <div><Button color="secondary">secondary button</Button></div>
283
+ <div><Button color="black">black button</Button></div>
284
+ <div><Button color="dark">dark button</Button></div>
285
+ <div><Button color="white">white button</Button></div>
286
+ <div><Button color="clear">clear button</Button></div>
287
+ <div><Button color="primary" size="xs">*-xs button</Button></div>
288
+ <div><Button color="primary" size="sm">*-sm button</Button></div>
289
+ <div><Button color="primary">*-md (default)</Button></div>
290
+ <div><Button color="primary" size="lg">*-lg button</Button></div>
291
+ <div><Button IconLeft={<Check size={19} className="-my-5" />}>IconLeft</Button></div>
292
+ <div><Button IconLeft={<Check size={19} className="-my-5" />}
293
+ className="w-[160px]">IconLeft 160px</Button></div>
294
+ <div><Button IconLeftEnd={<Check size={19} className="-my-5" />}
295
+ className="w-[190px]">IconLeftEnd 190px</Button></div>
296
+ <div><Button IconRight="v">IconRight</Button></div>
297
+ <div><Button IconRightEnd="v" className="w-[190px]">IconRightEnd 190px</Button></div>
298
+ <div><Button color="primary" IconRight="v" isLoading>primary isLoading</Button></div>
299
+ <div><Button IconCenter={<FileEditIcon size={18}/>}></Button></div>
300
+ <div><Button size="sm" IconCenter={<FileEditIcon size={16}/>}></Button></div>
301
+ <div><Button size="xs" IconCenter={<FileEditIcon size={14}/>}></Button></div>
302
+ </div>
403
303
  </div>
404
- </div>
304
+ )}
405
305
 
406
- <h2 class="h3">Inputs</h2>
407
- <div class="grid grid-cols-3 gap-x-6 mb-4">
408
- <div>
409
- <label for="firstName">First Name</label>
410
- <Field name="firstName" state={state} onChange={(e) => onChange(e, setState)} />
411
- </div>
412
- <div>
413
- <label for="email">Email Address</label>
414
- <Field name="email" type="email" placeholder="Your email address..."/>
415
- </div>
306
+ {groups.includes('Varients') && (
416
307
  <div>
417
- <div class="flex justify-between">
418
- <label for="password">Password</label>
419
- <a href="#" class="label">Forgot?</a>
308
+ <h2 class="h3">Varients</h2>
309
+ <div class="grid grid-cols-3 gap-x-6">
310
+ <div>
311
+ <label for="input2">Toggles</label>
312
+ <Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0"
313
+ state={state} onChange={(e) => onChange(e, setState)} />
314
+ <Checkbox name="input3" type="toggle" text="Toggle 22px" subtext="some additional text here." size={22} />
315
+ </div>
316
+ <div>
317
+ <label for="input1">Radios</label>
318
+ <Checkbox name="input1" type="radio" text="Radio" subtext="some additional text here 1." id="input1-1" class="!mb-0"
319
+ defaultChecked />
320
+ <Checkbox name="input1" type="radio" text="Radio 16px" subtext="some additional text here 2." id="input1-2" size={16} />
321
+ </div>
322
+ <div>
323
+ <label for="input0">Checkboxes</label>
324
+ <Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." class="!mb-0" defaultChecked />
325
+ <Checkbox name="input0.1" type="checkbox" text="Checkbox 16px" size={16}
326
+ subtext="some additional text here which is a bit longer that will be line-wrap to the next line." />
327
+ </div>
420
328
  </div>
421
- <Field name="password" type="password"/>
422
- </div>
423
- <div>
424
- <label for="search3number">Number</label>
425
- <Field name="number" id="search3number" type="number" placeholder="Number..." />
426
- </div>
427
- <div>
428
- <label for="search3">Search</label>
429
- <Field name="search" id="search3" type="search" placeholder="Search..." />
430
- </div>
431
- <div>
432
- <label for="filter">Filter by Code</label>
433
- <Field name="filter" type="filter" iconPos="left" />
434
- </div>
435
- <div>
436
- <label for="address">Input Error</label>
437
- <Field name="address" placeholder="Address..." state={state} onChange={(e) => onChange(e, setState)} />
438
329
  </div>
439
- <div>
440
- <label for="description">Description</label>
441
- <Field name="description" type="textarea" rows={2} />
442
- </div>
443
- <div>
444
- <label for="brandColor">Brand Color</label>
445
- <Field name="brandColor" type="color" iconPos="left" state={state} onChange={(e) => onChange(e, setState)} />
446
- </div>
447
- <div>
448
- <label for="amount">Amount ({state.amount})</label>
449
- <Field
450
- name="amount" type="currency" state={state} currency={state.currency || 'nzd'} onChange={(e) => onChange(e, setState)}
451
- // Example of using a custom format and currencies, e.g.
452
- format={'¤#,##0.00'}
453
- currencies={currencies}
454
- />
455
- </div>
456
- </div>
330
+ )}
457
331
 
458
- <h2 class="h3">Date Inputs</h2>
459
- <div class="grid grid-cols-1 gap-x-6 mb-4 sm:grid-cols-3">
332
+ {groups.includes('Selects') && (
460
333
  <div>
461
- <label for="date">Date with time</label>
462
- <Field name="date-time" type="date" mode="single" showTime={true} state={state} onChange={(e) => onChange(e, setState)} />
463
- </div>
464
- <div>
465
- <label for="date-range">Date range (with prefix & disabled days)</label>
466
- <Field
467
- name="date-range"
468
- type="date"
469
- mode="range"
470
- prefix="Date:"
471
- state={state}
472
- onChange={(e) => onChange(e, setState)}
473
- DayPickerProps={{
474
- disabled: { after: new Date(Date.now() + 1000 * 60 * 60 * 24 * 45) }
475
- }}
476
- />
334
+ <h2 class="h3">Selects</h2>
335
+ <div class="grid grid-cols-3 lg:grid-cols-3 gap-x-6">
336
+ <div>
337
+ <label for="action">Default</label>
338
+ <Select
339
+ // menuIsOpen={true}
340
+ name="action"
341
+ isSearchable={false}
342
+ options={useMemo(() => [
343
+ { value: 'edit', label: 'Edit' },
344
+ { value: 'delete', label: 'Delete' },
345
+ ], [])}
346
+ />
347
+ </div>
348
+ <div>
349
+ <label for="colorsMulti">Mutli Select</label>
350
+ <Select
351
+ name="colorsMulti"
352
+ isMulti={true}
353
+ state={state}
354
+ options={useMemo(() => [
355
+ { value: 'blue', label: 'Blue' },
356
+ { value: 'green', label: 'Green' },
357
+ { value: 'yellow', label: 'Yellow' },
358
+ { value: 'red', label: 'Red' },
359
+ { value: 'orange', label: 'Orange' },
360
+ { value: 'purple', label: 'Purple' },
361
+ { value: 'pink', label: 'Pink' },
362
+ { value: 'gray', label: 'Gray' },
363
+ { value: 'black', label: 'Black' },
364
+ { value: 'white', label: 'White' },
365
+ ], [])}
366
+ onChange={(e) => onChange(e, setState)}
367
+ />
368
+ </div>
369
+ <div>
370
+ <label for="country">Countries</label>
371
+ <Select
372
+ // https://github.com/lipis/flag-icons
373
+ name="country"
374
+ mode="country"
375
+ state={state}
376
+ options={useMemo(() => [{ value: 'nz', label: 'New Zealand' }, { value: 'au', label: 'Australia' }], [])}
377
+ onChange={(e) => onChange(e, setState)}
378
+ />
379
+ </div>
380
+ <div>
381
+ <label for="customer">List Item with Action</label>
382
+ <Select
383
+ // menuIsOpen={true}
384
+ placeholder="Select or add customer..."
385
+ name="customer"
386
+ mode="customer"
387
+ state={state}
388
+ onChange={onCustomerInputChange}
389
+ onInputChange={onCustomerSearch}
390
+ options={useMemo(() => [
391
+ {
392
+ className: 'bb',
393
+ fixed: true,
394
+ value: '0',
395
+ label: (
396
+ <>
397
+ <b>New Customer</b> (and clear select)
398
+ {customerSearch ? <> / Add <b>{ucFirst(customerSearch)}</b></> : ''}
399
+ </>
400
+ ),
401
+ },
402
+ { value: '1', label: 'Iron Man Industries' },
403
+ { value: '2', label: 'Captain America' },
404
+ { value: '3', label: 'Thor Limited' },
405
+ ], [customerSearch])}
406
+ />
407
+ </div>
408
+ <div>
409
+ <label for="currency">Currencies</label>
410
+ <Select
411
+ name="currency"
412
+ state={state}
413
+ options={useMemo(() => (currencies ? getCurrencyOptions(currencies) : [{ value: 'nzd', label: 'New Zealand Dollar' }, { value: 'aud', label: 'Australian Dollar' }]), [])}
414
+ onChange={(e) => onChange(e, setState)}
415
+ />
416
+ </div>
417
+ </div>
477
418
  </div>
419
+ )}
420
+
421
+ {groups.includes('Inputs') && (
478
422
  <div>
479
- <label for="date">Date multi-select (right aligned)</label>
480
- <Field name="date" type="date" mode="multiple" state={state} onChange={(e) => onChange(e, setState)} dir="bottom-right" />
423
+ <h2 class="h3">Inputs</h2>
424
+ <div class="grid grid-cols-3 gap-x-6">
425
+ <div>
426
+ <label for="firstName">First Name</label>
427
+ <Field name="firstName" state={state} onChange={(e) => onChange(e, setState)} />
428
+ </div>
429
+ <div>
430
+ <label for="email">Email Address</label>
431
+ <Field name="email" type="email" placeholder="Your email address..."/>
432
+ </div>
433
+ <div>
434
+ <div class="flex justify-between">
435
+ <label for="password">Password</label>
436
+ <a href="#" class="label">Forgot?</a>
437
+ </div>
438
+ <Field name="password" type="password"/>
439
+ </div>
440
+ <div>
441
+ <label for="search3number">Number</label>
442
+ <Field name="number" id="search3number" type="number" placeholder="Number..." />
443
+ </div>
444
+ <div>
445
+ <label for="search3">Search</label>
446
+ <Field name="search" id="search3" type="search" placeholder="Search..." />
447
+ </div>
448
+ <div>
449
+ <label for="filter">Filter by Code</label>
450
+ <Field name="filter" type="filter" iconPos="left" />
451
+ </div>
452
+ <div>
453
+ <label for="address">Input Error</label>
454
+ <Field name="address" placeholder="Address..." state={state} onChange={(e) => onChange(e, setState)} />
455
+ </div>
456
+ <div>
457
+ <label for="description">Description</label>
458
+ <Field name="description" type="textarea" rows={2} />
459
+ </div>
460
+ <div>
461
+ <label for="brandColor">Brand Color</label>
462
+ <Field name="brandColor" type="color" iconPos="left" state={state} onChange={(e) => onChange(e, setState)} />
463
+ </div>
464
+ <div>
465
+ <label for="amount">Amount ({state.amount})</label>
466
+ <Field
467
+ name="amount" type="currency" state={state} currency={state.currency || 'nzd'} onChange={(e) => onChange(e, setState)}
468
+ // Example of using a custom format and currencies, e.g.
469
+ format={'¤#,##0.00'}
470
+ currencies={currencies}
471
+ />
472
+ </div>
473
+ </div>
481
474
  </div>
475
+ )}
476
+
477
+ {groups.includes('Date Inputs') && (
482
478
  <div>
483
- <label for="time">Time</label>
484
- <Field name="time" type="time" state={state} onChange={(e) => onChange(e, setState)} />
479
+ <h2 class="h3">Date Inputs</h2>
480
+ <div class="grid grid-cols-1 gap-x-6 sm:grid-cols-3">
481
+ <div>
482
+ <label for="date">Date with time</label>
483
+ <Field name="date-time" type="date" mode="single" showTime={true} state={state} onChange={(e) => onChange(e, setState)} />
484
+ </div>
485
+ <div>
486
+ <label for="date-range">Date range (with prefix & disabled days)</label>
487
+ <Field
488
+ name="date-range"
489
+ type="date"
490
+ mode="range"
491
+ prefix="Date:"
492
+ state={state}
493
+ onChange={(e) => onChange(e, setState)}
494
+ DayPickerProps={{
495
+ disabled: { after: new Date(Date.now() + 1000 * 60 * 60 * 24 * 45) }
496
+ }}
497
+ />
498
+ </div>
499
+ <div>
500
+ <label for="date">Date multi-select (right aligned)</label>
501
+ <Field name="date" type="date" mode="multiple" state={state} onChange={(e) => onChange(e, setState)} dir="bottom-right" />
502
+ </div>
503
+ <div>
504
+ <label for="time">Time</label>
505
+ <Field name="time" type="time" state={state} onChange={(e) => onChange(e, setState)} />
506
+ </div>
507
+ </div>
485
508
  </div>
486
- </div>
509
+ )}
487
510
 
488
- <h2 class="h3">File Inputs & Calendar</h2>
489
- <div class="grid grid-cols-3 gap-x-6 mb-4">
511
+ {groups.includes('File Inputs & Calendar') && (
490
512
  <div>
491
- <label for="avatar">Avatar</label>
492
- <Drop class="is-small" name="avatar" state={state} onChange={(e) => onChange(e, setState)} awsUrl={injectedConfig.awsUrl} />
513
+ <h2 class="h3">File Inputs & Calendar</h2>
514
+ <div class="grid grid-cols-3 gap-x-6">
515
+ <div>
516
+ <label for="avatar">Avatar</label>
517
+ <Drop class="is-small" name="avatar" state={state} onChange={(e) => onChange(e, setState)} awsUrl={injectedConfig.awsUrl} />
518
+ </div>
519
+ <div>
520
+ <label for="calendar">Calendar</label>
521
+ <Calendar mode="range" value={state.calendar} numberOfMonths={1}
522
+ onChange={(value) => {
523
+ onChange({ target: { name: 'calendar', value: value } }, setState)
524
+ }}
525
+ />
526
+ </div>
527
+ </div>
493
528
  </div>
529
+ )}
530
+
531
+ {groups.includes('Tables') && (
494
532
  <div>
495
- <label for="calendar">Calendar</label>
496
- <Calendar mode="range" value={state.calendar} numberOfMonths={1}
497
- onChange={(value) => {
498
- onChange({ target: { name: 'calendar', value: value } }, setState)
499
- }}
533
+ <div class="flex justify-between items-start">
534
+ <h2 class="h3">Tables</h2>
535
+ <Field
536
+ name="tableFilter"
537
+ type="search"
538
+ state={state}
539
+ placeholder="Basic table filter..."
540
+ onChange={(e) => onChange(e, setState)}
541
+ className="my-0 [&>input]:font-normal [&>input]:text-xs [&>input]:py-1.5"
542
+ />
543
+ </div>
544
+ <Table
545
+ rows={rows.slice(0, perPage)}
546
+ columns={thead}
547
+ rowSideColor={(row) => ({ className: row?.status == 'pending' ? 'bg-yellow-400' : '', width: 5 })}
548
+ generateCheckboxActions={generateCheckboxActions}
549
+ generateTd={generateTd}
550
+ className="mb-6"
551
+ />
552
+ <Table
553
+ rows={[]}
554
+ columns={thead}
555
+ rowSideColor={(row) => ({ className: row?.status == 'pending' ? 'bg-yellow-400' : '', width: 5 })}
556
+ generateCheckboxActions={generateCheckboxActions}
557
+ generateTd={generateTd}
558
+ className="mb-6"
559
+ isLoading={true}
560
+ />
561
+ <Table
562
+ rows={rows.slice(0, 2).map(row => ({ ...row, _id: row._id + '1' }))}
563
+ columns={thead}
564
+ rowLinesMax={1}
565
+ headerHeightMin={35}
566
+ rowGap={8}
567
+ rowHeightMin={42}
568
+ rowSideColor={(row) => ({ className: `rounded-l-xl ${statusColors(row?.status as string)}`, width: 10 })}
569
+ rowOnClick={useCallback((row: QuoteExample) => {setStore((s) => ({ ...s, message: `Row ${row?._id} clicked` }))}, [setStore])}
570
+ generateCheckboxActions={generateCheckboxActions}
571
+ generateTd={generateTd}
572
+ className="mb-5"
573
+ tableClassName="rounded-3px"
574
+ rowClassName="[&:hover>div]:bg-gray-50"
575
+ columnClassName="border-t-1 first:rounded-l-xl last:rounded-r-xl"
576
+ columnSelectedClassName="bg-gray-50 border-indigo-300"
577
+ columnHeaderClassName="text-gray-500 text-2xs uppercase border-none"
578
+ checkboxClassName="rounded-[2px] shadow-none"
500
579
  />
501
580
  </div>
502
- </div>
581
+ )}
503
582
 
504
- <div class="flex justify-between items-start">
505
- <h2 class="h3">Tables</h2>
506
- <Field
507
- name="tableFilter"
508
- type="search"
509
- state={state}
510
- placeholder="Basic table filter..."
511
- onChange={(e) => onChange(e, setState)}
512
- className="!my-0 [&>input]:font-normal [&>input]:text-xs [&>input]:py-1.5" /////todo: need to allow twmerge here
513
- />
514
- </div>
515
- <div class="grid mb-4 last:mb-0">
516
- <Table
517
- rows={rows.slice(0, perPage)}
518
- columns={thead}
519
- rowSideColor={(row) => ({ className: row?.status == 'pending' ? 'bg-yellow-400' : '', width: 5 })}
520
- generateCheckboxActions={generateCheckboxActions}
521
- generateTd={generateTd}
522
- className="mb-6"
523
- />
524
- <Table
525
- rows={[]}
526
- columns={thead}
527
- rowSideColor={(row) => ({ className: row?.status == 'pending' ? 'bg-yellow-400' : '', width: 5 })}
528
- generateCheckboxActions={generateCheckboxActions}
529
- generateTd={generateTd}
530
- className="mb-6"
531
- isLoading={true}
532
- />
533
- <Table
534
- rows={rows.slice(0, 2).map(row => ({ ...row, _id: row._id + '1' }))}
535
- columns={thead}
536
- rowLinesMax={1}
537
- headerHeightMin={35}
538
- rowGap={8}
539
- rowHeightMin={42}
540
- rowSideColor={(row) => ({ className: `rounded-l-xl ${statusColors(row?.status as string)}`, width: 10 })}
541
- rowOnClick={useCallback((row: QuoteExample) => {setStore((s) => ({ ...s, message: `Row ${row?._id} clicked` }))}, [setStore])}
542
- generateCheckboxActions={generateCheckboxActions}
543
- generateTd={generateTd}
544
- className="mb-5"
545
- tableClassName="rounded-3px"
546
- rowClassName="[&:hover>div]:bg-gray-50"
547
- columnClassName="border-t-1 first:rounded-l-xl last:rounded-r-xl"
548
- columnSelectedClassName="bg-gray-50 border-indigo-300"
549
- columnHeaderClassName="text-gray-500 text-2xs uppercase border-none"
550
- checkboxClassName="rounded-[2px] shadow-none"
551
- />
552
- </div>
583
+ {groups.includes('Modals') && (
584
+ <>
585
+ <div>
586
+ <h2 class="h3">Modals</h2>
587
+ <div class="mb-6"><Button color="primary" onClick={() => setShowModal1(true)}>Modal (default)</Button></div>
588
+ </div>
589
+
590
+ <Modal show={showModal1} setShow={setShowModal1}>
591
+ <h3 class="h3">Edit Profile</h3>
592
+ <p class="mb-5">An example modal containing a basic form for editing profiles.</p>
593
+ <form class="mb-8 text-left">
594
+ <div>
595
+ <label for="firstName2">First Name</label>
596
+ <Field name="firstName2" state={state} onChange={(e) => onChange(e, setState)} />
597
+ </div>
598
+ <div>
599
+ <label for="email2">Email Address</label>
600
+ <Field name="email2" type="email" placeholder="Your email address..."/>
601
+ </div>
602
+ </form>
603
+ <div class="flex justify-end">
604
+ <Button color="primary" onClick={() => setShowModal1(false)}>Save</Button>
605
+ </div>
606
+ </Modal>
607
+ </>
608
+ )}
553
609
 
554
- {children}
610
+ {groups.includes('Custom Components') && (
611
+ <>
612
+ {children}
613
+ </>
614
+ )}
615
+
616
+ <GithubLink filename={__filename} />
555
617
  </div>
556
618
  )
557
619
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitro-web",
3
- "version": "0.0.138",
3
+ "version": "0.0.140",
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
@@ -787,13 +787,18 @@ export function toArray<T>(variable: T | undefined): (T extends any[] ? T : T[])
787
787
  * @returns {string}
788
788
  */
789
789
  export function trim(string: string): string;
790
+ /**
791
+ * Merge class conflicts together, but protect groups of classes from being merged together in the same argument. E.g. `(mb-1 mb-2) mx-1`
792
+ * @param {string[]} args
793
+ * @returns {string}
794
+ */
795
+ export function twMerge(...args: string[]): string;
790
796
  /**
791
797
  * Capitalize the first letter of a string
792
798
  * @param {string} string
793
799
  * @returns {string}
794
800
  */
795
801
  export function ucFirst(string: string): string;
796
- export const twMerge: (...classLists: import("tailwind-merge").ClassNameValue[]) => string;
797
802
  /**
798
803
  * Returns a list of response errors
799
804
  */
@@ -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":"AA2CA;;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;;;;;;;;;;;;;;;;;;;GAmBG;AACH,yBAnBuC,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,CAwKH;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,wBANa,CAAC,OACH,CAAC,QACD,MAAM,SACN,OAAO,WAAS,GACd,CAAC,CAKb;AAED;;;;;;;GAOG;AACH,gCANa,CAAC,QACH,CAAC,QACD,MAAM,SACN,OAAO,WAAS,GACd;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAgCpD;AAED;;;;;;GAMG;AACH,0BALW;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,GAAC,EAAE,GAAC,IAAI,gCAE5B,MAAM,GACJ,MAAM,GAAC,EAAE,GAAC,IAAI,CAmB1B;AAED;;;;;;;;;GASG;AACH,mCARW,MAAM,GAAC,IAAI,GAAC,IAAI,GAAC,UAAU,CAAC,WAAW,CAAC,YACxC,MAAM,SACN,MAAM,QACN,MAAM,GACJ,IAAI,CA+BhB;AAED;;;;;GAKG;AACH,mCAJW,MAAM,iBACN,OAAO,GACL,MAAM,CAMlB;AAED;;;;GAIG;AACH,mCAHW,MAAM,GACJ,MAAM,CAWlB;AAED;;;;;;;;GAQG;AACH,8BAPW,MAAM,QACN;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAAE,qBAC5G,QAAQ,cACR,MAAM,GACJ,QAAQ,CAwEpB;AAED;;;;GAIG;AACH,iCAHW;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GACnC,MAAM,CAIlB;AAED;;;;GAIG;AACH,sCAHW,MAAM,GACJ,MAAM,EAAE,CASpB;AAED;;;;GAIG;AACH,6CAHW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAS5D;AAED;;;;GAIG;AACH,+CAHW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAS9C;AAED;;;;;GAKG;AACH,yCAJW;IAAE,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GAAC,SAAS,QAC1D,MAAM,GAAC,MAAM,GACX;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAC,SAAS,CAQvD;AAED;;;;;GAKG;AACH,uCAJW,MAAM,iBACN,MAAM,GACJ,MAAM,CAYlB;AAED;;;;;GAKG;AACH,qCAJW;IAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;CAAE,QACvC,MAAM,GACJ,MAAM,CAYlB;AAED;;;;GAIG;AACH,6DAHW,MAAM,GACJ,OAAO,CAAC,OAAO,mBAAmB,EAAE,MAAM,GAAC,IAAI,CAAC,CAI5D;AAED;;;;;;GAMG;AACH,wCAHW,aAAa,GACX,UAAU,EAAE,CAgCxB;AAED;;;;GAIG;AACH,4CAHW,UAAU,EAAE,GAAC,SAAS,GACpB,MAAM,CAMlB;AAED;;;;;;GAMG;AACH,+BALW,GAAG,EAAE,UACL,OAAO,QACP,MAAM,GACJ,OAAO,CAcnB;AAED;;;;GAIG;AACH,kCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,iCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,oCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,+BAHW,MAAM,GACJ,OAAO,CAMnB;AAED;;;;;GAKG;AACH,8BAJW;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAC,GAAC,IAAI,qBAC7B,OAAO,GACL,OAAO,CASnB;AAED;;;;GAIG;AACH,qCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,+BAHW,OAAO,GACL,OAAO,CAmBnB;AAED;;;;GAIG;AACH,mCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,mCAHW,OAAO,GACL,OAAO,CAKnB;AAED;;;;GAIG;AACH,kCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,mCAHW,OAAO,GACL,OAAO,CAInB;AAED;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;GAMG;AACH,kCALW,MAAM,QACN,MAAM,iBACN,OAAO,GACL,MAAM,CAalB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qCAxBW,MAAM,mBACN,KAAK,GAAC,GAAG,aACT,KAAK,GACH,CAAC,KAAK,EAAE,KAAK,CAAC,GAAC,IAAI,CAuC/B;AAED;;;;;;;;;GASG;AACH,qDARW;IACN,IAAI,CAAC,EAAE;QAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAC,CAAA;IACjE,QAAQ,CAAC,EAAE;QAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAC,CAAA;CAC3C,MACO,MAAM,UACN,MAAM,OA+ChB;AAED;;;;;GAKG;AACH,6CAJW,MAAM,EAAE,UACR,MAAM,EAAE,GACP,MAAM,CAgBjB;AAED;;;;GAIG;AACH,kCAHW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,MACtB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,KAAK,GAAG;;EAS1C;AAED;;;;;GAKG;AACH,0BAJW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,UAC1B,MAAM,EAAE,GACN;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAStC;AAED;;GAEG;AAEH;;;;;;;;;;;;;GAaG;AACH,yBAXa,CAAC,oBACH,gBAAgB,YAChB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,mBACvC,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,8BAEzB,OAAO,CAAC,CAAC,CAAC,CA+CtB;AAED;;;;;;GAMG;AACH,0BALW,MAAM,YACN,MAAM,eACN,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,oCAvCW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,UAY1B;IACV,CAAK,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAC,QAAQ,GAAC,SAAS,GAAC,QAAQ,GAAC,WAAW,GAAC,SAAS,GAAC;QAAE,IAAI,EAAE,KAAK,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;CAC5G;;iBA6BmD,MAAM;;eAAY,MAAM;cAAQ,MAAM;eAAS,MAAM;cAAQ,MAAM;;aAC1G,QAAQ,EAAE;;EA+EzB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wCAhBW;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,GAAC,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,SAMnD;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,UACzC,MAAM,YACN,OAAO;;;;;;EAgCjB;AAED;;;;GAIG;AACH,0BAHW;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,QACtB,MAAM,GAAC,MAAM,GAAC,MAAM,EAAE,GAAC,MAAM,EAAE;;EAiBzC;AAED;;;;;;;;;;;;GAYG;AACH,0CAVW,MAAM,YAEd;IAA0B,iBAAiB,GAAnC,OAAO;IACW,mBAAmB,GAArC,OAAO;IACW,iBAAiB,GAAnC,OAAO;CAEf,GAAU;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAC,IAAI,GAAC,CAAC,MAAM,GAAC,IAAI,CAAC,EAAE,CAAA;CAAC,CAyCxD;AAED;;;;GAIG;AACH,yCAHW,MAAM,GACJ,MAAM,EAAE,CAOpB;AAED;;;;;;;;;GASG;AACH,iCARW;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAC,UACxB,MAAM,YACN;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAC,YAE/B;IAA0B,iBAAiB,GAAnC,OAAO;CAEf,GAAU,MAAM,CAkBlB;AAED;;;;;;;;;;;;GAYG;AACH,+BAXW,MAAM,SACN;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,UACtB;IAAC,cAAc,CAAC,WAAU;CAAC,cAC3B,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,aACnC,QAAQ,GACN,OAAO,CAAC,GAAG,CAAC,CAyDxB;AAED;;;;GAIG;AACH,0CAHW,EAAE,GAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,GACrB,EAAE,GAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,CAcnC;AAED;;;;;;;;GAQG;AACH,gCANW,MAAM,gBACN,KAAK,EAAE,GAAC,KAAK,SACb,MAAM,MACN,MAAM,GACJ,MAAM,CAclB;AAED;;;;GAIG;AACH,qCAHW,MAAM,GACJ,MAAM,CAMlB;AAED;;;;;;;;GAQG;AACH,yCAPW,MAAM,gBACN,MAAM,wBAEN,MAAM,aADN,MAAM,GAEJ,MAAM,CA8ClB;AAED;;;;;GAKG;AACH,uCAJW,MAAM,cACN,OAAO,GACL,MAAM,CAelB;AAED;;;;;GAKG;AACH,gEAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;AAED;;;;GAIG;AACH,oDAFW,aAAa,QAKvB;AAED;;;;;GAKG;AACH,sCAJW;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAC,EAAE,OACtB,MAAM,GACJ,MAAM,EAAE,CAQpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,yBAhBuC,CAAC,SAA3B,CAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAI,QAG3B,CAAC,SACD,MAAM,YACN;IACL,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACrB,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,CAmBH;AAED;;;;;GAKG;AACH,wBAJa,CAAC,YACH,CAAC,GAAG,SAAS,GACX,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CASvC;AAED;;;;GAIG;AACH,6BAHW,MAAM,GACJ,MAAM,CAKlB;AA4DD;;;;GAIG;AACH,iCAHW,MAAM,EAAE,GACN,MAAM,CAuElB;AAED;;;;GAIG;AACH,gCAHW,MAAM,GACJ,MAAM,CAKlB;;;;4BAnpCY,KAAK,GAAC,UAAU,EAAE,GAAC,UAAU,GAAC,eAAe,GAAC,MAAM,GAAC,GAAG;;;;oBA+NxD,CAAC,MAAM,EAAE,MAAM,CAAC;;;;kBAChB;IAAC,UAAU,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAA;CAAC;+BA0JpC,CAAC;IAAC,MAAM,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAC,CAAA;CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;;oBAic9D;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAC;uBA3kD7D,OAAO,OAAO,EAAE,QAAQ,CAAC,OAAO,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;;;;4BAI9D,OAAO,OAAO,EAAE,aAAa;;;;iCAC7B,OAAO,OAAO,EAAE,kBAAkB;;;;4BAClC,OAAO,OAAO,EAAE,aAAa;;;;wCAC7B,OAAO,aAAa,EAAE,yBAAyB;;;;0CAG/C,kBAAkB,GAAG;IAAE,aAAa,CAAC,EAAE,yBAAyB,CAAA;CAAE;;;;qCAGlE,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG;IACrC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACzG;uBAGW,MAAM;sBACN,CAAC,KAAK,EAAE,MAAM,KAAK,QAAQ;;;;wBAC3B,CAAC,MAAM,GAAC,MAAM,GAAC,OAAO,CAAC,EAAE;yBACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;yBACjC;IAAE,MAAM,EAAE,MAAM;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;8BACrC;IAAE,QAAQ,EAAE;QAAE,IAAI,EAAE;YAAE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE"}
package/util.js CHANGED
@@ -2,7 +2,7 @@ import _axios from 'axios'
2
2
  import axiosRetry from 'axios-retry'
3
3
  import dateformat from 'dateformat'
4
4
  import { loadStripe } from '@stripe/stripe-js/pure.js' // pure removes ping
5
- import { twMerge as _twMerge } from 'tailwind-merge'
5
+ import { twMerge as _twMerge, twJoin, createTailwindMerge, getDefaultConfig } from 'tailwind-merge'
6
6
 
7
7
  /** @typedef {import('react').Dispatch<import('react').SetStateAction<any>>} SetState */
8
8
 
@@ -1817,10 +1817,8 @@ export function trim (string) {
1817
1817
  return string.trim().replace(/\n\s+\n/g, '\n\n')
1818
1818
  }
1819
1819
 
1820
- import { createTailwindMerge, getDefaultConfig } from 'tailwind-merge'
1821
-
1822
1820
  // Create a custom twMerge instance
1823
- export const twMerge = createTailwindMerge(() => {
1821
+ const customTailwindMerge = createTailwindMerge(() => {
1824
1822
  const config = getDefaultConfig()
1825
1823
 
1826
1824
  /**
@@ -1875,18 +1873,84 @@ export const twMerge = createTailwindMerge(() => {
1875
1873
  'font-size': [...(config.classGroups['font-size'] || []), 'text-button-base', 'text-input-base'],
1876
1874
  },
1877
1875
  }
1878
- // console.dir(
1879
- // newSpacingSizes(['input-x', 'input-y', 'input-before', 'input-after']),
1880
- // { depth: null }
1881
- // )
1882
- // console.log(customTwMerge('mb-1 mb-2 mb-input-x')) // mb-input-x
1883
- // console.log(customTwMerge('mb-1 mb-2 my-input-y')) // my-input-y
1884
- // console.log(customTwMerge('mb-1 my-input-y mb-2')) // my-input-y mb-2
1885
- // console.log(customTwMerge('mb-1 my-input-y mb-2 my-input-x')) // my-input-x
1886
- // console.log(customTwMerge('mx-1 my-input-y mb-2 my-input-x')) // mx-1 my-input-x
1887
- // console.log(customTwMerge('text-xs text-base text-input text-button-base'))
1888
1876
  })
1889
1877
 
1878
+ /**
1879
+ * Merge class conflicts together, but protect groups of classes from being merged together in the same argument. E.g. `(mb-1 mb-2) mx-1`
1880
+ * @param {string[]} args
1881
+ * @returns {string}
1882
+ */
1883
+ export function twMerge(...args) {
1884
+ const raw = twJoin(args)
1885
+ if (!raw.includes('(')) return customTailwindMerge(raw)
1886
+
1887
+ // 1) Tokenize: either "(...)" group chunks or normal non-space tokens.
1888
+ /** @type {{ cls: string, groupId: number }[]} */
1889
+ const tokens = []
1890
+ let groupId = 0
1891
+
1892
+ const re = /\(([^()]*)\)|(\S+)/g
1893
+ for (let m; (m = re.exec(raw)); ) {
1894
+ const groupText = m[1]
1895
+ const single = m[2]
1896
+
1897
+ if (groupText != null) {
1898
+ const id = ++groupId
1899
+ for (const cls of groupText.trim().split(/\s+/).filter(Boolean)) {
1900
+ tokens.push({ cls: cls, groupId: id })
1901
+ }
1902
+ } else if (single) {
1903
+ tokens.push({ cls: single, groupId: 0 })
1904
+ }
1905
+ }
1906
+
1907
+ // 3) Merge, except don't merge-away conflicts inside the same "( ... )" group.
1908
+ /** @type {(string|null)[]} */
1909
+ const out = []
1910
+ /** @type {number[]} */
1911
+ const groupIds = []
1912
+
1913
+ for (const t of tokens) {
1914
+ for (let i = out.length - 1; i >= 0; i--) {
1915
+ const prev = out[i]
1916
+ const next = t.cls
1917
+ if (!prev) continue
1918
+
1919
+ // Does next override prev, according to tailwind-merge?
1920
+ const parts = customTailwindMerge(`${prev} ${next}`).trim().split(/\s+/).filter(Boolean)
1921
+ const isOverride = !parts.includes(prev) && parts.includes(next)
1922
+
1923
+ if (isOverride) {
1924
+ const sameProtectedGroup = t.groupId !== 0 && t.groupId === groupIds[i]
1925
+ if (!sameProtectedGroup) out[i] = null
1926
+ }
1927
+ }
1928
+
1929
+ out.push(t.cls)
1930
+ groupIds.push(t.groupId)
1931
+ }
1932
+
1933
+ return out.filter(Boolean).join(' ')
1934
+
1935
+ // const testCases = [
1936
+ // [['mb-1 mb-2 mb-input-x'], 'mb-input-x'],
1937
+ // [['mb-1 mb-2 my-input-y'], 'my-input-y'],
1938
+ // [['mb-1 my-input-y mb-2'], 'my-input-y mb-2'],
1939
+ // [['mb-1 my-input-y mb-2 my-input-x'], 'my-input-x'],
1940
+ // [['mx-1 my-input-y mb-2 my-input-x'], 'mx-1 my-input-x'],
1941
+ // [['text-xs text-nonexistent text-input-base'], 'text-nonexistent text-input-base'],
1942
+ // [['(mb-1 mb-input-x) mx-1 mx-2', ''], 'mb-1 mb-input-x mx-2'],
1943
+ // [['(mb-1 mb-input-x) mx-1 mx-2', 'mb-2'], 'mx-2 mb-2'],
1944
+ // ]
1945
+
1946
+ // testCases.forEach(testCase => {
1947
+ // const value = twMerge(...testCase[0])
1948
+ // if (value !== testCase[1]) {
1949
+ // console.log(`Test: ${testCase[1]}, received: ${value}`)
1950
+ // }
1951
+ // })
1952
+ }
1953
+
1890
1954
  /**
1891
1955
  * Capitalize the first letter of a string
1892
1956
  * @param {string} string