nitro-web 0.0.11 → 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.
- package/.eslintrc.json +4 -19
- package/_example/.env +1 -1
- package/_example/client/config.ts +2 -1
- package/_example/client/index.ts +6 -24
- package/_example/components/index.tsx +1 -1
- package/_example/package.json +0 -1
- package/_example/server/config.js +6 -7
- package/_example/tailwind.config.js +1 -1
- package/_example/tsconfig.json +5 -1
- package/_example/types.ts +1 -0
- package/client/{app.js → app.tsx} +101 -99
- package/client/globals.ts +42 -0
- package/client/index.ts +52 -0
- package/client/store.ts +31 -0
- package/components/auth/auth.api.js +3 -2
- package/components/auth/{reset.jsx → reset.tsx} +21 -23
- package/components/auth/{signin.jsx → signin.tsx} +14 -16
- package/components/auth/{signup.jsx → signup.tsx} +15 -17
- package/components/billing/stripe.api.js +2 -1
- package/components/dashboard/{dashboard.jsx → dashboard.tsx} +3 -3
- package/components/partials/element/{accordion.jsx → accordion.tsx} +21 -13
- package/components/partials/element/avatar.tsx +40 -0
- package/components/partials/element/{button.jsx → button.tsx} +20 -16
- package/components/partials/element/{dropdown.jsx → dropdown.tsx} +32 -30
- package/components/partials/element/{github-link.jsx → github-link.tsx} +3 -3
- package/components/partials/element/{initials.jsx → initials.tsx} +11 -2
- package/components/partials/element/{message.jsx → message.tsx} +22 -23
- package/components/partials/element/{modal.jsx → modal.tsx} +4 -3
- package/components/partials/element/{sidebar.jsx → sidebar.tsx} +14 -7
- package/components/partials/element/{tooltip.jsx → tooltip.tsx} +11 -3
- package/components/partials/element/{topbar.jsx → topbar.tsx} +9 -7
- package/components/partials/form/{checkbox.jsx → checkbox.tsx} +13 -13
- package/components/partials/form/drop-handler.tsx +68 -0
- package/components/partials/form/{drop.jsx → drop.tsx} +51 -33
- package/components/partials/form/form-error.tsx +27 -0
- package/components/partials/form/{input-color.jsx → input-color.tsx} +27 -15
- package/components/partials/form/{input-currency.jsx → input-currency.tsx} +37 -32
- package/components/partials/form/{input-date.jsx → input-date.tsx} +4 -3
- package/components/partials/form/{input.jsx → input.tsx} +35 -19
- package/components/partials/form/{location.jsx → location.tsx} +21 -8
- package/components/partials/form/{select.jsx → select.tsx} +142 -143
- package/components/partials/form/{toggle.jsx → toggle.tsx} +10 -2
- package/components/partials/{is-first-render.js → is-first-render.ts} +1 -2
- package/components/partials/layout/layout1.tsx +29 -0
- package/components/partials/layout/{layout2.jsx → layout2.tsx} +3 -3
- package/components/partials/{styleguide.jsx → styleguide.tsx} +16 -19
- package/components/settings/{settings-account.jsx → settings-account.tsx} +9 -13
- package/components/settings/{settings-business.jsx → settings-business.tsx} +7 -8
- package/components/settings/{settings-team--member.jsx → settings-team--member.tsx} +4 -11
- package/components/settings/{settings-team.jsx → settings-team.tsx} +4 -8
- package/components/settings/settings.api.js +1 -0
- package/package.json +14 -28
- package/readme.md +1 -1
- package/server/email/index.js +2 -1
- package/server/index.js +1 -0
- package/server/models/company.js +2 -1
- package/server/models/user.js +2 -1
- package/server/router.js +3 -2
- package/tsconfig.json +31 -0
- package/types/required-globals.d.ts +39 -0
- package/types/util.d.ts +12 -2
- package/types/util.d.ts.map +1 -1
- package/types.ts +43 -0
- package/util.js +14 -34
- package/webpack.config.js +23 -4
- package/_example/types/index.d.ts +0 -13
- package/_example/types/twin.d.ts +0 -19
- package/client/index.js +0 -44
- package/components/partials/element/avatar.jsx +0 -31
- package/components/partials/form/drop-handler.jsx +0 -62
- package/components/partials/form/form-error.jsx +0 -21
- package/components/partials/layout/layout1.jsx +0 -38
- package/types/client/app.d.ts +0 -2
- package/types/client/app.d.ts.map +0 -1
- package/types/client/index.d.ts +0 -29
- package/types/client/index.d.ts.map +0 -1
- package/types/components/auth/reset.d.ts +0 -3
- package/types/components/auth/reset.d.ts.map +0 -1
- package/types/components/auth/signin.d.ts +0 -4
- package/types/components/auth/signin.d.ts.map +0 -1
- package/types/components/auth/signup.d.ts +0 -4
- package/types/components/auth/signup.d.ts.map +0 -1
- package/types/components/dashboard/dashboard.d.ts +0 -4
- package/types/components/dashboard/dashboard.d.ts.map +0 -1
- package/types/components/partials/element/accordion.d.ts +0 -7
- package/types/components/partials/element/accordion.d.ts.map +0 -1
- package/types/components/partials/element/avatar.d.ts +0 -8
- package/types/components/partials/element/avatar.d.ts.map +0 -1
- package/types/components/partials/element/button.d.ts +0 -11
- package/types/components/partials/element/button.d.ts.map +0 -1
- package/types/components/partials/element/dropdown.d.ts +0 -17
- package/types/components/partials/element/dropdown.d.ts.map +0 -1
- package/types/components/partials/element/initials.d.ts +0 -9
- package/types/components/partials/element/initials.d.ts.map +0 -1
- package/types/components/partials/element/message.d.ts +0 -2
- package/types/components/partials/element/message.d.ts.map +0 -1
- package/types/components/partials/element/modal.d.ts +0 -10
- package/types/components/partials/element/modal.d.ts.map +0 -1
- package/types/components/partials/element/sidebar.d.ts +0 -6
- package/types/components/partials/element/sidebar.d.ts.map +0 -1
- package/types/components/partials/element/tooltip.d.ts +0 -8
- package/types/components/partials/element/tooltip.d.ts.map +0 -1
- package/types/components/partials/element/topbar.d.ts +0 -8
- package/types/components/partials/element/topbar.d.ts.map +0 -1
- package/types/components/partials/form/checkbox.d.ts +0 -14
- package/types/components/partials/form/checkbox.d.ts.map +0 -1
- package/types/components/partials/form/drop-handler.d.ts +0 -6
- package/types/components/partials/form/drop-handler.d.ts.map +0 -1
- package/types/components/partials/form/drop.d.ts +0 -11
- package/types/components/partials/form/drop.d.ts.map +0 -1
- package/types/components/partials/form/form-error.d.ts +0 -6
- package/types/components/partials/form/form-error.d.ts.map +0 -1
- package/types/components/partials/form/input-color.d.ts +0 -10
- package/types/components/partials/form/input-color.d.ts.map +0 -1
- package/types/components/partials/form/input-currency.d.ts +0 -10
- package/types/components/partials/form/input-currency.d.ts.map +0 -1
- package/types/components/partials/form/input.d.ts +0 -9
- package/types/components/partials/form/input.d.ts.map +0 -1
- package/types/components/partials/form/location.d.ts +0 -12
- package/types/components/partials/form/location.d.ts.map +0 -1
- package/types/components/partials/form/select.d.ts +0 -27
- package/types/components/partials/form/select.d.ts.map +0 -1
- package/types/components/partials/form/toggle.d.ts +0 -9
- package/types/components/partials/form/toggle.d.ts.map +0 -1
- package/types/components/partials/is-first-render.d.ts +0 -2
- package/types/components/partials/is-first-render.d.ts.map +0 -1
- package/types/components/partials/layout/layout1.d.ts +0 -13
- package/types/components/partials/layout/layout1.d.ts.map +0 -1
- package/types/components/partials/layout/layout2.d.ts +0 -4
- package/types/components/partials/layout/layout2.d.ts.map +0 -1
- package/types/components/partials/not-found.d.ts +0 -2
- package/types/components/partials/not-found.d.ts.map +0 -1
- package/types/components/partials/styleguide.d.ts +0 -4
- package/types/components/partials/styleguide.d.ts.map +0 -1
- package/types/components/settings/settings-account.d.ts +0 -6
- package/types/components/settings/settings-account.d.ts.map +0 -1
- package/types/components/settings/settings-business.d.ts +0 -4
- package/types/components/settings/settings-business.d.ts.map +0 -1
- package/types/components/settings/settings-team--member.d.ts +0 -5
- package/types/components/settings/settings-team--member.d.ts.map +0 -1
- package/types/components/settings/settings-team.d.ts +0 -4
- package/types/components/settings/settings-team.d.ts.map +0 -1
- /package/components/partials/{not-found.jsx → not-found.tsx} +0 -0
|
@@ -1,26 +1,36 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-nocheck
|
|
2
2
|
import { NumericFormat } from 'react-number-format'
|
|
3
|
-
import { getCurrencyPrefixWidth } from '
|
|
3
|
+
import { getCurrencyPrefixWidth } from 'nitro-web/util'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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 '
|
|
6
|
-
import { Dropdown } from '
|
|
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 =
|
|
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
|
|
3
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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 (
|
|
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
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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 =
|
|
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 '
|
|
3
|
+
import * as util from 'nitro-web/util'
|
|
3
4
|
|
|
4
|
-
|
|
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 (
|
|
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
|
-
|
|
115
|
+
const place = this.getPlace()
|
|
103
116
|
if (!place.geometry) return
|
|
104
117
|
if (clear) setInputValue('')
|
|
105
118
|
else setInputValue(place.formatted_address)
|
|
106
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
215
|
+
const cachedCallback = script.onload
|
|
203
216
|
script.onload = () => {
|
|
204
217
|
cachedCallback()
|
|
205
218
|
res()
|