nitro-web 0.0.138 → 0.0.139

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.
@@ -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" /////todo: need to allow twmerge here
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.139",
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 🚀",