nitro-web 0.0.10 → 0.0.12

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.
Files changed (144) hide show
  1. package/.eslintrc.json +4 -19
  2. package/_example/.env +1 -1
  3. package/_example/client/config.ts +2 -1
  4. package/_example/client/index.ts +6 -24
  5. package/_example/components/index.tsx +1 -1
  6. package/_example/package.json +0 -1
  7. package/_example/server/config.js +6 -7
  8. package/_example/tailwind.config.js +1 -1
  9. package/_example/tsconfig.json +5 -1
  10. package/_example/types.ts +1 -0
  11. package/client/{app.js → app.tsx} +101 -99
  12. package/client/globals.ts +42 -0
  13. package/client/index.ts +52 -0
  14. package/client/store.ts +31 -0
  15. package/components/auth/auth.api.js +3 -2
  16. package/components/auth/{reset.jsx → reset.tsx} +21 -23
  17. package/components/auth/{signin.jsx → signin.tsx} +14 -16
  18. package/components/auth/{signup.jsx → signup.tsx} +15 -17
  19. package/components/billing/stripe.api.js +2 -1
  20. package/components/dashboard/{dashboard.jsx → dashboard.tsx} +3 -3
  21. package/components/partials/element/{accordion.jsx → accordion.tsx} +21 -13
  22. package/components/partials/element/avatar.tsx +40 -0
  23. package/components/partials/element/{button.jsx → button.tsx} +20 -16
  24. package/components/partials/element/{dropdown.jsx → dropdown.tsx} +32 -30
  25. package/components/partials/element/github-link.tsx +16 -0
  26. package/components/partials/element/{initials.jsx → initials.tsx} +11 -2
  27. package/components/partials/element/{message.jsx → message.tsx} +22 -23
  28. package/components/partials/element/{modal.jsx → modal.tsx} +4 -3
  29. package/components/partials/element/{sidebar.jsx → sidebar.tsx} +14 -7
  30. package/components/partials/element/{tooltip.jsx → tooltip.tsx} +11 -3
  31. package/components/partials/element/{topbar.jsx → topbar.tsx} +9 -7
  32. package/components/partials/form/{checkbox.jsx → checkbox.tsx} +13 -13
  33. package/components/partials/form/drop-handler.tsx +68 -0
  34. package/components/partials/form/{drop.jsx → drop.tsx} +51 -33
  35. package/components/partials/form/form-error.tsx +27 -0
  36. package/components/partials/form/{input-color.jsx → input-color.tsx} +27 -15
  37. package/components/partials/form/{input-currency.jsx → input-currency.tsx} +37 -32
  38. package/components/partials/form/{input-date.jsx → input-date.tsx} +4 -3
  39. package/components/partials/form/{input.jsx → input.tsx} +35 -19
  40. package/components/partials/form/{location.jsx → location.tsx} +21 -8
  41. package/components/partials/form/{select.jsx → select.tsx} +142 -143
  42. package/components/partials/form/{toggle.jsx → toggle.tsx} +10 -2
  43. package/components/partials/{is-first-render.js → is-first-render.ts} +1 -2
  44. package/components/partials/layout/layout1.tsx +29 -0
  45. package/components/partials/layout/{layout2.jsx → layout2.tsx} +3 -3
  46. package/components/partials/{styleguide.jsx → styleguide.tsx} +16 -19
  47. package/components/settings/{settings-account.jsx → settings-account.tsx} +9 -13
  48. package/components/settings/{settings-business.jsx → settings-business.tsx} +7 -8
  49. package/components/settings/{settings-team--member.jsx → settings-team--member.tsx} +4 -11
  50. package/components/settings/{settings-team.jsx → settings-team.tsx} +4 -8
  51. package/components/settings/settings.api.js +1 -0
  52. package/package.json +14 -28
  53. package/readme.md +1 -1
  54. package/server/email/index.js +2 -1
  55. package/server/index.js +1 -0
  56. package/server/models/company.js +2 -1
  57. package/server/models/user.js +2 -1
  58. package/server/router.js +3 -2
  59. package/tsconfig.json +31 -0
  60. package/types/required-globals.d.ts +39 -0
  61. package/types/util.d.ts +12 -2
  62. package/types/util.d.ts.map +1 -1
  63. package/types.ts +43 -0
  64. package/util.js +14 -34
  65. package/webpack.config.js +23 -4
  66. package/_example/types/index.d.ts +0 -13
  67. package/_example/types/twin.d.ts +0 -19
  68. package/client/index.js +0 -44
  69. package/components/partials/element/avatar.jsx +0 -31
  70. package/components/partials/element/github-link.jsx +0 -14
  71. package/components/partials/form/drop-handler.jsx +0 -62
  72. package/components/partials/form/form-error.jsx +0 -21
  73. package/components/partials/layout/layout1.jsx +0 -38
  74. package/types/client/app.d.ts +0 -2
  75. package/types/client/app.d.ts.map +0 -1
  76. package/types/client/index.d.ts +0 -29
  77. package/types/client/index.d.ts.map +0 -1
  78. package/types/components/auth/reset.d.ts +0 -3
  79. package/types/components/auth/reset.d.ts.map +0 -1
  80. package/types/components/auth/signin.d.ts +0 -4
  81. package/types/components/auth/signin.d.ts.map +0 -1
  82. package/types/components/auth/signup.d.ts +0 -4
  83. package/types/components/auth/signup.d.ts.map +0 -1
  84. package/types/components/dashboard/dashboard.d.ts +0 -4
  85. package/types/components/dashboard/dashboard.d.ts.map +0 -1
  86. package/types/components/partials/element/accordion.d.ts +0 -7
  87. package/types/components/partials/element/accordion.d.ts.map +0 -1
  88. package/types/components/partials/element/avatar.d.ts +0 -8
  89. package/types/components/partials/element/avatar.d.ts.map +0 -1
  90. package/types/components/partials/element/button.d.ts +0 -11
  91. package/types/components/partials/element/button.d.ts.map +0 -1
  92. package/types/components/partials/element/dropdown.d.ts +0 -17
  93. package/types/components/partials/element/dropdown.d.ts.map +0 -1
  94. package/types/components/partials/element/initials.d.ts +0 -9
  95. package/types/components/partials/element/initials.d.ts.map +0 -1
  96. package/types/components/partials/element/message.d.ts +0 -2
  97. package/types/components/partials/element/message.d.ts.map +0 -1
  98. package/types/components/partials/element/modal.d.ts +0 -10
  99. package/types/components/partials/element/modal.d.ts.map +0 -1
  100. package/types/components/partials/element/sidebar.d.ts +0 -6
  101. package/types/components/partials/element/sidebar.d.ts.map +0 -1
  102. package/types/components/partials/element/tooltip.d.ts +0 -8
  103. package/types/components/partials/element/tooltip.d.ts.map +0 -1
  104. package/types/components/partials/element/topbar.d.ts +0 -8
  105. package/types/components/partials/element/topbar.d.ts.map +0 -1
  106. package/types/components/partials/form/checkbox.d.ts +0 -14
  107. package/types/components/partials/form/checkbox.d.ts.map +0 -1
  108. package/types/components/partials/form/drop-handler.d.ts +0 -6
  109. package/types/components/partials/form/drop-handler.d.ts.map +0 -1
  110. package/types/components/partials/form/drop.d.ts +0 -11
  111. package/types/components/partials/form/drop.d.ts.map +0 -1
  112. package/types/components/partials/form/form-error.d.ts +0 -6
  113. package/types/components/partials/form/form-error.d.ts.map +0 -1
  114. package/types/components/partials/form/input-color.d.ts +0 -10
  115. package/types/components/partials/form/input-color.d.ts.map +0 -1
  116. package/types/components/partials/form/input-currency.d.ts +0 -10
  117. package/types/components/partials/form/input-currency.d.ts.map +0 -1
  118. package/types/components/partials/form/input.d.ts +0 -9
  119. package/types/components/partials/form/input.d.ts.map +0 -1
  120. package/types/components/partials/form/location.d.ts +0 -12
  121. package/types/components/partials/form/location.d.ts.map +0 -1
  122. package/types/components/partials/form/select.d.ts +0 -27
  123. package/types/components/partials/form/select.d.ts.map +0 -1
  124. package/types/components/partials/form/toggle.d.ts +0 -9
  125. package/types/components/partials/form/toggle.d.ts.map +0 -1
  126. package/types/components/partials/is-first-render.d.ts +0 -2
  127. package/types/components/partials/is-first-render.d.ts.map +0 -1
  128. package/types/components/partials/layout/layout1.d.ts +0 -13
  129. package/types/components/partials/layout/layout1.d.ts.map +0 -1
  130. package/types/components/partials/layout/layout2.d.ts +0 -4
  131. package/types/components/partials/layout/layout2.d.ts.map +0 -1
  132. package/types/components/partials/not-found.d.ts +0 -2
  133. package/types/components/partials/not-found.d.ts.map +0 -1
  134. package/types/components/partials/styleguide.d.ts +0 -4
  135. package/types/components/partials/styleguide.d.ts.map +0 -1
  136. package/types/components/settings/settings-account.d.ts +0 -6
  137. package/types/components/settings/settings-account.d.ts.map +0 -1
  138. package/types/components/settings/settings-business.d.ts +0 -4
  139. package/types/components/settings/settings-business.d.ts.map +0 -1
  140. package/types/components/settings/settings-team--member.d.ts +0 -5
  141. package/types/components/settings/settings-team--member.d.ts.map +0 -1
  142. package/types/components/settings/settings-team.d.ts +0 -4
  143. package/types/components/settings/settings-team.d.ts.map +0 -1
  144. /package/components/partials/{not-found.jsx → not-found.tsx} +0 -0
@@ -1,26 +1,36 @@
1
- /*eslint-disable*/
1
+ // @ts-nocheck
2
2
  import { NumericFormat } from 'react-number-format'
3
- import { getCurrencyPrefixWidth } from '../../../util.js'
3
+ import { getCurrencyPrefixWidth } from 'nitro-web/util'
4
4
 
5
- /**
6
- * @param {string} id - field name or path on state
7
- * @param {object} config - e.g. { currencies: { nzd: { symbol: '$', digits: 2 } } }
8
- * @param {string} [currency] - currency iso
9
- * @param {function} [onChange] - e.g. (event) => onInputChange(event)
10
- * @param {string} [placeholder] - e.g. 'Amount'
11
- * @param {cents} [value] - e.g. 123 (input is always controlled if state is passed in)
12
- */
13
- export function InputCurrency({ id, config, className, currency='nzd', onChange, placeholder, value }) {
5
+ type InputCurrencyProps = {
6
+ /** field name or path on state */
7
+ id: string
8
+ /** e.g. { currencies: { nzd: { symbol: '$', digits: 2 } } } */
9
+ config: {
10
+ currencies: { [key: string]: { symbol: string, digits: number } },
11
+ countries: { [key: string]: { numberFormats: { currency: string } } }
12
+ }
13
+ className: string
14
+ /** currency iso */
15
+ currency: string
16
+ onChange: (event: { target: { id: string, value: string } }) => void
17
+ /** e.g. 'Amount' */
18
+ placeholder: string
19
+ /** e.g. 123 (input is always controlled if state is passed in) */
20
+ value: number
21
+ }
22
+
23
+ export function InputCurrency({ id, config, className, currency='nzd', onChange, placeholder, value }: InputCurrencyProps) {
14
24
  if (!config?.currencies || !config?.countries) {
15
25
  throw new Error(
16
26
  'InputCurrency: `config.currencies` and `config.countries` is required, check out the nitro example for more info.'
17
27
  )
18
28
  }
19
- const ref = useRef()
20
29
  const [dontFix, setDontFix] = useState()
21
30
  const [settings, setSettings] = useState(() => getCurrencySettings(currency))
22
31
  const [dollars, setDollars] = useState(() => toDollars(value, true, settings))
23
32
  const [prefixWidth, setPrefixWidth] = useState()
33
+ const ref = useRef({ settings, dontFix }) // was null
24
34
  ref.current = { settings, dontFix }
25
35
 
26
36
  useEffect(() => {
@@ -46,36 +56,31 @@ export function InputCurrency({ id, config, className, currency='nzd', onChange,
46
56
  setPrefixWidth(settings.prefix == '$' ? getCurrencyPrefixWidth(settings.prefix, 1) : 0)
47
57
  }, [settings.prefix])
48
58
 
49
- function toCents(num) {
59
+ function toCents(num: number) {
50
60
  if (!num && num !== 0) return null
51
61
  const value = Math.round(num * Math.pow(10, ref.current.settings.maxDecimals)) // e.g. 1.23 => 123
52
62
  // console.log('toCents', num, value)
53
63
  return value
54
64
  }
55
65
 
56
- function toDollars(num, toFixed, settings) {
66
+ function toDollars(num: string|number, toFixed: boolean, settings: { maxDecimals: number }) {
57
67
  if (!num && num !== 0) return null
58
- const value = num / Math.pow(10, (settings||ref.current.settings).maxDecimals) // e.g. 1.23 => 123
68
+ const value = num / Math.pow(10, (settings || ref.current.settings).maxDecimals) // e.g. 1.23 => 123
59
69
  // console.log('toDollars', num, value)
60
- return toFixed ? value.toFixed((settings||ref.current.settings).maxDecimals) : value
70
+ return toFixed ? value.toFixed((settings || ref.current.settings).maxDecimals) : value
61
71
  }
62
72
 
63
- function getCurrencySettings(currency) {
64
- /**
65
- * parse CLDR currency format, e.g. '¤#,##0.00'
66
- * @param {string} currency - currency iso
67
- * @returns {object}
68
- * {
69
- * currency: 'nzd',
70
- * decimalSeparator: '.',
71
- * thousandSeparator: ',',
72
- * minDecimals: 2,
73
- * maxDecimals: 2,
74
- * prefix: '$',
75
- * suffix: '',
76
- * }
77
- */
78
- const output = { currency }
73
+ function getCurrencySettings(currency: string) {
74
+ // parse CLDR currency string format, e.g. '¤#,##0.00'
75
+ const output: {
76
+ currency: string, // e.g. 'nzd'
77
+ decimalSeparator?: string, // e.g. '.'
78
+ thousandSeparator?: string, // e.g. ','
79
+ minDecimals?: number, // e.g. 2
80
+ maxDecimals?: number, // e.g. 2
81
+ prefix?: string, // e.g. '$'
82
+ suffix?: string // e.g. ''
83
+ } = { currency }
79
84
  const { symbol, digits } = config.currencies[currency]
80
85
  let format = config.countries['nz'].numberFormats.currency
81
86
 
@@ -1,9 +1,10 @@
1
+ // @ts-nocheck
1
2
  // todo: finish tailwind conversion
2
3
  import { css } from 'twin.macro'
3
4
  import { DayPicker } from 'react-day-picker'
4
5
  import { format, isValid, parse } from 'date-fns'
5
- import { getCurrencyPrefixWidth } from '../../../util.js'
6
- import { Dropdown } from '../element/dropdown.jsx'
6
+ import { getCurrencyPrefixWidth } from 'nitro-web/util'
7
+ import { Dropdown } from 'nitro-web'
7
8
  import 'react-day-picker/dist/style.css'
8
9
 
9
10
  export function InputDate({ className, prefix, id, onChange, mode='single', value, ...props }) {
@@ -120,7 +121,7 @@ export function InputDate({ className, prefix, id, onChange, mode='single', valu
120
121
  )
121
122
  }
122
123
 
123
- const style = () => css`
124
+ const style = css`
124
125
  .rdp {
125
126
  --rdp-cell-size: 34px;
126
127
  --rdp-caption-font-size: 12px;
@@ -1,8 +1,7 @@
1
+ // @ts-nocheck
1
2
  import { css } from 'twin.macro'
2
- import * as util from '../../../util.js'
3
- import { InputCurrency } from './input-currency.jsx'
4
- import { InputColor } from './input-color.jsx'
5
- // import { InputDate } from './input-date.jsx'
3
+ import { InputColor, InputCurrency, util } from 'nitro-web' // InputDate
4
+
6
5
  import {
7
6
  EnvelopeIcon,
8
7
  // CalendarIcon,
@@ -12,17 +11,27 @@ import {
12
11
  EyeSlashIcon,
13
12
  } from '@heroicons/react/20/solid'
14
13
 
15
- /**
16
- * Input
17
- * @param {string} name - field name or path on state (used to match errors), e.g. 'date', 'company.email'
18
- * @param {object} state - State object to get the value, and check errors against
19
- * @param {string} [id] - not required, name used if not provided
20
- * @param {('password'|'email'|'text'|'date'|'filter'|'search'|'color'|'textarea'|'currency')} [type='text']
21
- */
22
- export function Input({ name='', state, id, type='text', ...props }) {
14
+ interface InputProps {
15
+ name: string
16
+ state?: any
17
+ id?: string
18
+ type?: string
19
+ [key: string]: any
20
+ }
21
+
22
+ export function Input({ name='', state, id, type='text', ...props }: InputProps) {
23
+ /**
24
+ * Input
25
+ * @param {string} name - field name or path on state (used to match errors), e.g. 'date', 'company.email'
26
+ * @param {object} state - State object to get the value, and check errors against
27
+ * @param {string} [id] - not required, name used if not provided
28
+ * @param {('password'|'email'|'text'|'date'|'filter'|'search'|'color'|'textarea'|'currency')} [type='text']
29
+ */
30
+ let IconSvg: React.ReactNode
31
+ let onClick: () => void
23
32
  let iconDir = 'right'
24
33
  let InputEl = 'input'
25
- const [inputType, setInputType] = useState(() => {
34
+ const [inputType, setInputType] = useState(() => { // eslint-disable-line
26
35
  return type == 'password' ? 'password' : (type == 'textarea' ? type : 'text')
27
36
  })
28
37
 
@@ -37,15 +46,15 @@ export function Input({ name='', state, id, type='text', ...props }) {
37
46
  }
38
47
 
39
48
  // Find any errors that match this input path
40
- for (let item of (state?.errors || [])) {
49
+ for (const item of (state?.errors || [])) {
41
50
  if (util.isRegex(name) && (item.title||'').match(name)) var error = item
42
51
  else if (item.title == name) error = item
43
52
  }
44
53
 
45
54
  // Special input types
46
55
  if (type == 'password') {
47
- var onClick = () => setInputType(o => o == 'password' ? 'text' : 'password')
48
- var IconSvg = inputType == 'password' ? <EyeSlashIcon /> : <EyeIcon />
56
+ onClick = () => setInputType(o => o == 'password' ? 'text' : 'password')
57
+ IconSvg = inputType == 'password' ? <EyeSlashIcon /> : <EyeIcon />
49
58
  } else if (type == 'email') {
50
59
  IconSvg = <EnvelopeIcon />
51
60
  // } else if (type == 'date') {
@@ -98,7 +107,14 @@ export function Input({ name='', state, id, type='text', ...props }) {
98
107
  )
99
108
  }
100
109
 
101
- function IconEl({ iconDir, IconSvg, onClick, type }) {
110
+ type IconElProps = {
111
+ iconDir: string
112
+ IconSvg: React.ReactNode
113
+ onClick: () => void
114
+ type: string
115
+ }
116
+
117
+ function IconEl({ iconDir, IconSvg, onClick, type }: IconElProps) {
102
118
  const iconSize = type == 'color' ? 'size-[18px]' : 'size-4'
103
119
  return (
104
120
  !!IconSvg &&
@@ -112,13 +128,13 @@ function IconEl({ iconDir, IconSvg, onClick, type }) {
112
128
  )
113
129
  }
114
130
 
115
- function ColorIcon({ hex }) {
131
+ function ColorIcon({ hex }: { hex: string }) {
116
132
  return (
117
133
  <span class="block size-full rounded-md" style={{ backgroundColor: hex ? hex : '#f1f1f1' }}></span>
118
134
  )
119
135
  }
120
136
 
121
- const style = () => css`
137
+ const style = css`
122
138
  input {
123
139
  appearance: textfield;
124
140
  -moz-appearance: textfield;
@@ -1,7 +1,20 @@
1
+ // @ts-nocheck
1
2
  // todo: finish tailwind conversion
2
- import * as util from '../../../util.js'
3
+ import * as util from 'nitro-web/util'
3
4
 
4
- export function Location({ clear, id, name, onInput, onSelect, placeholder, placeTypes, value, googleMapsApiKey }) {
5
+ type LocationProps = {
6
+ clear: boolean
7
+ id?: string
8
+ name: string
9
+ onInput?: (place: Place) => void
10
+ onSelect?: (place: Place) => void
11
+ placeholder?: string
12
+ placeTypes?: string[]
13
+ value?: Place
14
+ googleMapsApiKey: string
15
+ }
16
+
17
+ export function Location({ clear, id, name, onInput, onSelect, placeholder, placeTypes, value, googleMapsApiKey }: LocationProps) {
5
18
  /**
6
19
  * Get location or area of place (requires both 'maps javascript' and 'places' APIs)
7
20
  *
@@ -42,7 +55,7 @@ export function Location({ clear, id, name, onInput, onSelect, placeholder, plac
42
55
  // It seems like autoComplete cleans up both listeners, handy links if needing to remove sooner..
43
56
  // Cleanup listners: https://stackoverflow.com/a/22862011/1900648
44
57
  // Cleanup .pac-container: https://stackoverflow.com/a/21419890/1900648
45
- for (let elem of document.getElementsByClassName('pac-container')) elem.remove()
58
+ for (const elem of document.getElementsByClassName('pac-container')) elem.remove()
46
59
  }
47
60
  }, [])
48
61
 
@@ -99,11 +112,11 @@ export function Location({ clear, id, name, onInput, onSelect, placeholder, plac
99
112
  }
100
113
 
101
114
  function onPlaceSelect() {
102
- let place = this.getPlace()
115
+ const place = this.getPlace()
103
116
  if (!place.geometry) return
104
117
  if (clear) setInputValue('')
105
118
  else setInputValue(place.formatted_address)
106
- let addressObject = formatAddressObject(place)
119
+ const addressObject = formatAddressObject(place)
107
120
  onSelect({
108
121
  city: addressObject.city,
109
122
  country: addressObject.country,
@@ -151,7 +164,7 @@ export function Location({ clear, id, name, onInput, onSelect, placeholder, plac
151
164
  // Stop form submission if there is a google autocomplete dropdown opened
152
165
  let prevented
153
166
  if (event.key === 'Enter') {
154
- for (let el of document.getElementsByClassName('pac-container')) {
167
+ for (const el of document.getElementsByClassName('pac-container')) {
155
168
  if (el.offsetParent !== null && !prevented) { // google autocomplete opened somewhere
156
169
  event.preventDefault()
157
170
  prevented = true
@@ -181,7 +194,7 @@ function loadGoogleMaps(googleMapsApiKey) {
181
194
  }
182
195
 
183
196
  return new Promise((res) => {
184
- let scriptId = 'googleMapsUrl'
197
+ const scriptId = 'googleMapsUrl'
185
198
  let script = document.getElementById(scriptId)
186
199
  // script not yet inserted
187
200
  if (script === null) {
@@ -199,7 +212,7 @@ function loadGoogleMaps(googleMapsApiKey) {
199
212
  res()
200
213
  // script hasn't been loaded yet
201
214
  } else {
202
- let cachedCallback = script.onload
215
+ const cachedCallback = script.onload
203
216
  script.onload = () => {
204
217
  cachedCallback()
205
218
  res()