nitro-web 0.2.14 → 0.2.15

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.
@@ -28,6 +28,8 @@ type GetSelectClassName = {
28
28
  export type SelectOption = {
29
29
  value: unknown,
30
30
  label: string | React.ReactNode,
31
+ /** Plain-string label shown in the input when selected (needed when `label` is not a string) **/
32
+ labelInput?: string,
31
33
  labelSearch?: string,
32
34
  noTruncate?: boolean,
33
35
  fixed?: boolean,
@@ -39,6 +41,9 @@ export type SelectOption = {
39
41
 
40
42
  export type SelectedOption = SelectOption | null
41
43
 
44
+ // Options/Control
45
+ // 1. Control value comes from value or state (so if its the option it will be the option.labe;)
46
+
42
47
  /** Select (all other props are passed to react-select) **/
43
48
  export type SelectProps<IsMulti extends boolean = false> = {
44
49
  /** field name or path on state (used to match errors), e.g. 'date', 'company.email' **/
@@ -110,14 +115,14 @@ function SelectBase<IsMulti extends boolean = false>({
110
115
  if (typeof state == 'object' && typeof value == 'undefined') value = ''
111
116
  else if (typeof value == 'undefined') value = null // new
112
117
 
113
- // Combobox: input text (option label when matched, else raw typed text) + matches, to gate the menu
118
+ // Combobox: input text (matched option's plain-string label, else raw typed text) + matches, to gate the menu
114
119
  const [focused, setFocused] = useState(false)
115
120
  const [pickedFromMenu, setPickedFromMenu] = useState(false) // keeps the menu closed after a selection until typing
116
- const comboInput = typeof value == 'object' && value && typeof (value as SelectOption).label == 'string'
117
- ? (value as SelectOption).label as string
118
- : String(rawValue ?? '')
121
+ const valueOption = typeof value == 'object' ? value as SelectOption | null : null
122
+ const comboLabel = valueOption?.labelInput ?? (typeof valueOption?.label == 'string' ? valueOption.label : undefined)
123
+ const comboInput = comboLabel ?? String(rawValue ?? '')
119
124
  const comboMatches = !isCombobox ? 0 : options.filter((o) => {
120
- const label = typeof o.label == 'string' ? o.label : (o.labelSearch || '')
125
+ const label = typeof o.label == 'string' ? o.label : (o.labelSearch || o.labelInput || '')
121
126
  return filterFn({ label: label, value: String(o.value), data: o }, comboInput)
122
127
  }).length
123
128
 
@@ -167,14 +172,15 @@ function SelectBase<IsMulti extends boolean = false>({
167
172
  * menuIsOpen={false}
168
173
  */
169
174
  {...props}
170
- _nitro={{ prefix, mode, showSearchIcon: showSearchIcon ?? isCombobox }}
175
+ _nitro={{ prefix: prefix, mode: mode, showSearchIcon: showSearchIcon ?? isCombobox }}
171
176
  key={isCombobox ? name : value as string}
172
177
  unstyled={true}
173
178
  inputId={id || name}
174
179
  id={containerId}
175
180
  filterOption={(option, searchText) => {
176
181
  if ((option.data as {fixed?: boolean}).fixed) return true
177
- const labelSearch = (option.data as {labelSearch?: string}).labelSearch
182
+ const o = option.data as SelectOption
183
+ const labelSearch = o.labelSearch || o.labelInput
178
184
  return filterFn(labelSearch ? { ...option, label: labelSearch } : option, searchText)
179
185
  }}
180
186
  menuPlacement="auto"
@@ -328,15 +334,15 @@ function ValueContainer({ children, ...props}: ValueContainerProps) {
328
334
  }
329
335
 
330
336
  function SingleValue({ children, ...props }: SingleValueProps) {
331
- const selectedOption = props.getValue()[0] as { labelControl?: string } & SelectOption
337
+ const selectedOption = props.getValue()[0] as SelectOption
332
338
  // @ts-expect-error
333
339
  const flagClassName = props.getClassNames('flag')
334
340
 
335
341
  return (
336
342
  <components.SingleValue {...props}>
337
343
  {
338
- selectedOption?.labelControl
339
- ? <Fragment>{selectedOption.labelControl}</Fragment>
344
+ selectedOption?.labelInput
345
+ ? <Fragment>{selectedOption.labelInput}</Fragment>
340
346
  : <Fragment>
341
347
  {selectedOption?.flag && <span className={flagClassName}>{selectedOption.flag}</span>}
342
348
  {selectedOption?.IconLeft}
@@ -10,20 +10,20 @@ import React from 'react'
10
10
 
11
11
  const perPage = 10
12
12
  const allGroups = [
13
- // 'Links',
14
- // 'Dropdowns',
15
- // 'Filters',
16
- // 'Button Colors & Sizes',
17
- // 'Button Icons',
18
- // 'Loading Elements',
19
- // 'Varients',
13
+ 'Links',
14
+ 'Dropdowns',
15
+ 'Filters',
16
+ 'Button Colors & Sizes',
17
+ 'Button Icons',
18
+ 'Loading Elements',
19
+ 'Varients',
20
20
  'Selects',
21
- // 'Inputs',
22
- // 'Date Inputs',
23
- // 'File Inputs & Calendar & Time',
24
- // 'Tables',
25
- // 'Modals & Notifications',
26
- // 'Custom Components',
21
+ 'Inputs',
22
+ 'Date Inputs',
23
+ 'File Inputs & Calendar & Time',
24
+ 'Tables',
25
+ 'Modals & Notifications',
26
+ 'Custom Components',
27
27
  ] as const
28
28
 
29
29
  const statusColors = function(status: string) {
@@ -80,7 +80,7 @@ export function Styleguide({ className, elements, children, currencies, groups }
80
80
  calendarSingle: Date.now(),
81
81
  calendarRange: [Date.now(), Date.now() + 1000 * 60 * 60 * 24 * 8],
82
82
  firstName: 'Bruce',
83
- combobox: 'blue',
83
+ combobox: '11',
84
84
  tableFilter: '',
85
85
  errors: [
86
86
  { title: 'address', detail: 'Address is required' },
@@ -103,7 +103,7 @@ export function Styleguide({ className, elements, children, currencies, groups }
103
103
  calendarRange: [Date.now(), Date.now() + 1000 * 60 * 60 * 24 * 3.2],
104
104
  firstName: 'John',
105
105
  tableFilter: '',
106
- combobox: 'green',
106
+ combobox: '22',
107
107
  errors: [
108
108
  { title: 'address', detail: 'Address is required' },
109
109
  ],
@@ -537,7 +537,24 @@ export function Styleguide({ className, elements, children, currencies, groups }
537
537
  />
538
538
  </div>
539
539
  <div>
540
- <label for="combobox">Combobox (Autocomplete /w or free text)</label>
540
+ <label for="combobox">JSX label + custom search</label>
541
+ <Select
542
+ name="jsxlabel"
543
+ state={state}
544
+ onChange={(e) => onChange(e, setState)}
545
+ menuIsOpen={true}
546
+ options={useMemo(() => [
547
+ { value: '11', label: <div class="inline-block bg-blue-300">Blue</div>, labelSearch: 'BL - blue', noTruncate: true },
548
+ { value: '22', label: <div class="inline-block bg-green-300">Green</div>, labelSearch: 'GR - green', noTruncate: true },
549
+ { value: '33', label: <div class="inline-block bg-yellow-300">Yellow</div>, labelSearch: 'YL - yellow', noTruncate: true },
550
+ { value: '44', label: <div class="inline-block bg-red-300">Red</div>, labelSearch: 'RD - red', noTruncate: true },
551
+ { value: '55', label: <div class="inline-block bg-orange-300">Orange</div>, labelSearch: 'OR - orange', noTruncate: true },
552
+ { value: '66', label: <div class="inline-block bg-purple-300">Purple</div>, labelSearch: 'PU - purple', noTruncate: true },
553
+ ], [])}
554
+ />
555
+ </div>
556
+ <div>
557
+ <label for="combobox">Combobox (value={state.combobox})</label>
541
558
  <Select
542
559
  name="combobox"
543
560
  mode="combobox"
@@ -547,16 +564,12 @@ export function Styleguide({ className, elements, children, currencies, groups }
547
564
  placeholder="Start typing to search for a color..."
548
565
  // hideDropdownIcon={true}
549
566
  options={useMemo(() => [
550
- { value: 'blue', label: 'Blue' },
551
- { value: 'green', label: 'Green' },
552
- { value: 'yellow', label: 'Yellow' },
553
- { value: 'red', label: 'Red' },
554
- { value: 'orange', label: 'Orange' },
555
- { value: 'purple', label: 'Purple' },
556
- { value: 'pink', label: 'Pink' },
557
- { value: 'gray', label: 'Gray' },
558
- { value: 'black', label: 'Black' },
559
- { value: 'white', label: 'White' },
567
+ { value: '11', label: <div class="inline-block bg-blue-300">Blue</div>, labelInput: 'BL - blue' },
568
+ { value: '22', label: <div class="inline-block bg-green-300">Green</div>, labelInput: 'GR - green' },
569
+ { value: '33', label: <div class="inline-block bg-yellow-300">Yellow</div>, labelInput: 'YL - yellow' },
570
+ { value: '44', label: <div class="inline-block bg-red-300">Red</div>, labelInput: 'RD - red' },
571
+ { value: '55', label: <div class="inline-block bg-orange-300">Orange</div>, labelInput: 'OR - orange' },
572
+ { value: '66', label: <div class="inline-block bg-purple-300">Purple</div>, labelInput: 'PU - purple' },
560
573
  ], [])}
561
574
  />
562
575
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitro-web",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
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 🚀",