nitro-web 0.0.15 → 0.0.17

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.
@@ -1,21 +1,23 @@
1
- import { Drop, Dropdown, Input, Select, Button, Checkbox, GithubLink } from 'nitro-web'
1
+ import { Drop, Dropdown, Field, Select, Button, Checkbox, GithubLink, isDemo, Modal, Calendar } from 'nitro-web'
2
2
  import { getCountryOptions, getCurrencyOptions, ucFirst } from 'nitro-web/util'
3
3
  import { CheckIcon } from '@heroicons/react/20/solid'
4
4
  import { Config } from 'types'
5
5
 
6
6
  export function Styleguide({ config }: { config: Config }) {
7
7
  const [customerSearch, setCustomerSearch] = useState('')
8
+ const [showModal1, setShowModal1] = useState(false)
8
9
  const [state, setState] = useState({
9
10
  address: '',
10
- country: 'us',
11
- currency: 'nzd', // can be commented too
12
11
  amount: 100,
13
12
  brandColor: '#F3CA5F',
14
- firstName: 'Bruce',
13
+ country: 'us',
14
+ currency: 'nzd', // can be commented too
15
15
  date: Date.now(),
16
+ 'date-range': [Date.now(), Date.now() + 1000 * 60 * 60 * 24 * 33],
17
+ calendar: [Date.now(), Date.now() + 1000 * 60 * 60 * 24 * 8],
18
+ firstName: 'Bruce',
16
19
  errors: [
17
20
  { title: 'address', detail: 'Address is required' },
18
- { title: 'currency', detail: 'Currency is required' },
19
21
  ],
20
22
  })
21
23
 
@@ -52,7 +54,7 @@ export function Styleguide({ config }: { config: Config }) {
52
54
  <div class="mb-10 text-left max-w-[1100px]">
53
55
  <GithubLink filename={__filename} />
54
56
  <div class="mb-7">
55
- <h1 class="h1">Styleguide</h1>
57
+ <h1 class="h1">{isDemo ? 'Design System' : 'Style Guide'}</h1>
56
58
  <p>
57
59
  Components are styled using&nbsp;
58
60
  <a href="https://v3.tailwindcss.com/docs/configuration" class="underline" target="_blank" rel="noreferrer">TailwindCSS</a>.
@@ -60,33 +62,19 @@ export function Styleguide({ config }: { config: Config }) {
60
62
  </div>
61
63
 
62
64
  <h2 class="h3">Links</h2>
63
- <div class="mb-8">
65
+ <div class="mb-10">
64
66
  <a class="mr-2" href="#">Default</a>
65
67
  <a class="underline1 is-active mr-2" href="#">Underline1</a>
66
68
  <a class="underline2 is-active mr-2" href="#">Underline2</a>
67
69
  </div>
68
70
 
69
- <h2 class="h3">Checkboxes</h2>
70
- <div class="grid grid-cols-3 gap-x-6">
71
- <div>
72
- <label for="input0">Label</label>
73
- <Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." defaultChecked />
74
- </div>
75
- <div>
76
- <label for="input1">Label</label>
77
- <Checkbox name="input1" type="radio" text="Radio 1" subtext="some additional text here 1." id="input1-1" class="!mb-0"
78
- defaultChecked />
79
- <Checkbox name="input1" type="radio" text="Radio 2" subtext="some additional text here 2." id="input1-2" class="!mt-0" />
80
- </div>
81
- <div>
82
- <label for="input2">Label</label>
83
- <Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0" defaultChecked />
84
- <Checkbox name="input3" type="toggle" text="Toggle md" size="md" subtext="some additional text here." />
85
- </div>
71
+ <h2 class="h3">Modals</h2>
72
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
73
+ <div><Button color="primary" onClick={() => setShowModal1(true)}>Modal (default)</Button></div>
86
74
  </div>
87
75
 
88
76
  <h2 class="h3">Dropdowns</h2>
89
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-8">
77
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
90
78
  <div>
91
79
  <Dropdown options={options} minWidth="250px">
92
80
  <Button IconRight="v" class="gap-x-3">Dropdown</Button>
@@ -110,7 +98,7 @@ export function Styleguide({ config }: { config: Config }) {
110
98
  </div>
111
99
 
112
100
  <h2 class="h3">Buttons</h2>
113
- <div class="flex flex-wrap gap-x-6 gap-y-4 mb-8">
101
+ <div class="flex flex-wrap gap-x-6 gap-y-4 mb-10">
114
102
  <div><Button color="primary">primary (default)</Button></div>
115
103
  <div><Button color="secondary">secondary button</Button></div>
116
104
  <div><Button color="white">white button</Button></div>
@@ -124,8 +112,27 @@ export function Styleguide({ config }: { config: Config }) {
124
112
  <div><Button color="primary" IconRight="v" isLoading>primary isLoading</Button></div>
125
113
  </div>
126
114
 
115
+ <h2 class="h3">Checkboxes</h2>
116
+ <div class="grid grid-cols-3 gap-x-6 mb-4">
117
+ <div>
118
+ <label for="input2">Label</label>
119
+ <Checkbox name="input2" type="toggle" text="Toggle sm" subtext="some additional text here." class="!mb-0" defaultChecked />
120
+ <Checkbox name="input3" type="toggle" text="Toggle md" size="md" subtext="some additional text here." />
121
+ </div>
122
+ <div>
123
+ <label for="input1">Label</label>
124
+ <Checkbox name="input1" type="radio" text="Radio 1" subtext="some additional text here 1." id="input1-1" class="!mb-0"
125
+ defaultChecked />
126
+ <Checkbox name="input1" type="radio" text="Radio 2" subtext="some additional text here 2." id="input1-2" class="!mt-0" />
127
+ </div>
128
+ <div>
129
+ <label for="input0">Label</label>
130
+ <Checkbox name="input0" type="checkbox" text="Checkbox" subtext="some additional text here." defaultChecked />
131
+ </div>
132
+ </div>
133
+
127
134
  <h2 class="h3">Selects</h2>
128
- <div class="grid grid-cols-3 lg:grid-cols-3 gap-x-6">
135
+ <div class="grid grid-cols-3 lg:grid-cols-3 gap-x-6 mb-4">
129
136
  <div>
130
137
  <label for="action">Default</label>
131
138
  <Select
@@ -204,53 +211,88 @@ export function Styleguide({ config }: { config: Config }) {
204
211
  <div class="grid grid-cols-3 gap-x-6 mb-4">
205
212
  <div>
206
213
  <label for="firstName">First Name</label>
207
- <Input name="firstName" state={state} onChange={onInputChange} />
214
+ <Field name="firstName" state={state} onChange={onInputChange} />
208
215
  </div>
209
216
  <div>
210
217
  <label for="email">Email Address</label>
211
- <Input name="email" type="email" placeholder="Your email address..."/>
218
+ <Field name="email" type="email" placeholder="Your email address..."/>
212
219
  </div>
213
220
  <div>
214
221
  <div class="flex justify-between">
215
222
  <label for="password">Password</label>
216
223
  <a href="#" class="label">Forgot?</a>
217
224
  </div>
218
- <Input name="password" type="password"/>
225
+ <Field name="password" type="password"/>
219
226
  </div>
220
227
  <div>
221
228
  <label for="search">Search</label>
222
- <Input name="search" type="search" placeholder="Search..."/>
229
+ <Field name="search" type="search" placeholder="Search..." />
223
230
  </div>
224
231
  <div>
225
- <label for="filter">Filter</label>
226
- <Input name="filter" type="filter" />
232
+ <label for="filter">Filter by Code</label>
233
+ <Field name="filter" type="filter" iconPos="left" />
227
234
  </div>
228
235
  <div>
229
236
  <label for="address">Input Error</label>
230
- <Input name="address" type="address" placeholder="Address..." state={state} onChange={onInputChange} />
237
+ <Field name="address" placeholder="Address..." state={state} onChange={onInputChange} />
231
238
  </div>
232
- {/* <div>
233
- <label for="date">Date</label>
234
- <Input name="date" type="date" prefix="Date:" state={state} onChange={onInputChange} />
235
- </div> */}
236
239
  <div>
237
- <label for="brandColor">Brand Color</label>
238
- <Input name="brandColor" type="color" state={state} onChange={onInputChange} />
240
+ <label for="description">Description</label>
241
+ <Field name="description" type="textarea" rows={2} />
239
242
  </div>
240
243
  <div>
241
- <label for="description">Description</label>
242
- <Input name="description" type="textarea" />
244
+ <label for="brandColor">Brand Color</label>
245
+ <Field name="brandColor" type="color" state={state} iconPos="left" onChange={onInputChange} />
243
246
  </div>
244
247
  <div>
245
248
  <label for="amount">Amount ({state.amount})</label>
246
- <Input name="amount" type="currency" state={state} currency={state.currency || 'nzd'} onChange={onInputChange} config={config} />
249
+ <Field name="amount" type="currency" state={state} currency={state.currency || 'nzd'} onChange={onInputChange} config={config} />
250
+ </div>
251
+ </div>
252
+
253
+ <h2 class="h3">Date Inputs</h2>
254
+ <div class="grid grid-cols-3 gap-x-6 mb-4">
255
+ <div>
256
+ <label for="date">Date</label>
257
+ <Field name="date" type="date" state={state} onChange={onInputChange} />
247
258
  </div>
259
+ <div>
260
+ <label for="date-range">Date range with prefix</label>
261
+ <Field name="date-range" type="date" mode="range" prefix="Date:" state={state} onChange={onInputChange} />
262
+ </div>
263
+ </div>
264
+
265
+ <h2 class="h3">File Inputs & Calendar</h2>
266
+ <div class="grid grid-cols-3 gap-x-6 mb-4">
248
267
  <div>
249
268
  <label for="avatar">Avatar</label>
250
269
  <Drop class="is-small" name="avatar" state={state} onChange={onInputChange} awsUrl={config.awsUrl} />
251
270
  </div>
271
+ <div>
272
+ <label for="calendar">Calendar</label>
273
+ <Calendar mode="range" value={state.calendar} numberOfMonths={1} onChange={(mode, value) => {
274
+ onInputChange({ target: { id: 'calendar', value: value } })
275
+ }} />
276
+ </div>
252
277
  </div>
253
278
 
279
+ <Modal show={showModal1} setShow={setShowModal1} class="p-9">
280
+ <h3 class="h3">Edit Profile</h3>
281
+ <p class="mb-5">An example modal containing a basic form for editing profiles.</p>
282
+ <form class="mb-8 text-left">
283
+ <div>
284
+ <label for="firstName2">First Name</label>
285
+ <Field name="firstName2" state={state} onChange={onInputChange} />
286
+ </div>
287
+ <div>
288
+ <label for="email2">Email Address</label>
289
+ <Field name="email2" type="email" placeholder="Your email address..."/>
290
+ </div>
291
+ </form>
292
+ <div class="flex justify-end">
293
+ <Button color="primary" onClick={() => setShowModal1(false)}>Save</Button>
294
+ </div>
295
+ </Modal>
254
296
  </div>
255
297
  )
256
298
  }
@@ -2,7 +2,7 @@
2
2
  // todo: finish tailwind conversion
3
3
  import * as util from 'nitro-web/util'
4
4
  import SvgTick from 'nitro-web/client/imgs/icons/tick.svg'
5
- import { Button, FormError, Input, Modal, Topbar, Tabbar } from 'nitro-web'
5
+ import { Button, FormError, Field, Modal, Topbar, Tabbar } from 'nitro-web'
6
6
 
7
7
  export function SettingsAccount() {
8
8
  const isLoading = useState('')
@@ -48,21 +48,21 @@ export function SettingsAccount() {
48
48
  <div class="cols cols-6 cols-gap-3">
49
49
  <div class="col">
50
50
  <label for="firstName">First Name(s)</label>
51
- <Input name="firstName" placeholder="E.g. Bruce" state={state} onChange={onChange(setState)} />
51
+ <Field name="firstName" placeholder="E.g. Bruce" state={state} onChange={onChange.bind(setState)} />
52
52
  </div>
53
53
  <div class="col">
54
54
  <label for="lastName">Last Name</label>
55
- <Input name="lastName" placeholder="E.g. Wayne" state={state} onChange={onChange(setState)} />
55
+ <Field name="lastName" placeholder="E.g. Wayne" state={state} onChange={onChange.bind(setState)} />
56
56
  </div>
57
57
  <div class="col">
58
58
  <label for="email">Email Address</label>
59
- <Input name="email" type="email" placeholder="Your email address..." state={state}
60
- onChange={onChange(setState)} />
59
+ <Field name="email" type="email" placeholder="Your email address..." state={state}
60
+ onChange={onChange.bind(setState)} />
61
61
  </div>
62
62
  <div class="col">
63
63
  <Link to="/reset" class="label-right link2 underline2 is-active">Reset Password?</Link>
64
64
  <label for="password">Password</label>
65
- <Input name="password" placeholder="•••••••••••" disabled={true} />
65
+ <Field name="password" placeholder="•••••••••••" disabled={true} />
66
66
  </div>
67
67
  </div>
68
68
 
@@ -1,10 +1,10 @@
1
- // @ts-nocheck
1
+ //@ts-nocheck
2
2
  // todo: finish tailwind conversio
3
3
 
4
4
  ////// look at the select type error below
5
5
  import * as util from 'nitro-web/util'
6
6
  import SvgTick from 'nitro-web/client/imgs/icons/tick.svg'
7
- import { Button, Input, Select, Topbar, Tabbar } from 'nitro-web'
7
+ import { Button, Field, Select, Topbar, Tabbar } from 'nitro-web'
8
8
 
9
9
  export function SettingsBusiness({ config }) {
10
10
  const isLoading = useState('')
@@ -65,7 +65,7 @@ export function SettingsBusiness({ config }) {
65
65
  type="country"
66
66
  state={state}
67
67
  options={useMemo(() => util.getCountryOptions(config.countries), [])}
68
- onChange={onChange(setState)}
68
+ onChange={onChange.bind(setState)}
69
69
  />
70
70
  </div>
71
71
  <div class="col">
@@ -75,37 +75,37 @@ export function SettingsBusiness({ config }) {
75
75
  type="country"
76
76
  state={state}
77
77
  options={useMemo(() => util.getCurrencyOptions(config.currencies), [])}
78
- onChange={onChange(setState)}
78
+ onChange={onChange.bind(setState)}
79
79
  />
80
80
  </div>
81
81
  <div class="col">
82
82
  <label for="business.name">Trading Name</label>
83
- <Input name="business.name" placeholder="E.g. Wayne Enterprises" state={state} onChange={onChange(setState)} />
83
+ <Field name="business.name" placeholder="E.g. Wayne Enterprises" state={state} onChange={onChange.bind(setState)} />
84
84
  </div>
85
85
  <div class="col">
86
86
  <Link to="#" class="label-right link2 underline2 is-active">Custom Address</Link>
87
87
  <label for="business.address">Address (Start Typing...)</label>
88
- <Input name="business.address.full" placeholder="" state={state} onChange={onChange(setState)} />
88
+ <Field name="business.address.full" placeholder="" state={state} onChange={onChange.bind(setState)} />
89
89
  </div>
90
90
  <div class="col">
91
91
  <label for="business.website">Website</label>
92
- <Input name="business.website" placeholder="https://" state={state} onChange={onChange(setState)} />
92
+ <Field name="business.website" placeholder="https://" state={state} onChange={onChange.bind(setState)} />
93
93
  </div>
94
94
  <div class="col">
95
95
  <label for="business.phone">Mobile Number</label>
96
- <Input name="business.phone" placeholder="" state={state} onChange={onChange(setState)} />
96
+ <Field name="business.phone" placeholder="" state={state} onChange={onChange.bind(setState)} />
97
97
  </div>
98
98
  <div class="col">
99
99
  <Link to="#" class="label-right link2 underline2 is-active">What&apos;s this for?</Link>
100
100
  <label for="tax.number">GST Number</label>
101
- <Input class="mb-0" name="tax.number" placeholder="Appears on your documents" state={state}
102
- onChange={onChange(setState)} />
101
+ <Field class="mb-0" name="tax.number" placeholder="Appears on your documents" state={state}
102
+ onChange={onChange.bind(setState)} />
103
103
  </div>
104
104
  <div class="col">
105
105
  <Link to="#" class="label-right link2 underline2 is-active">What&apos;s this for?</Link>
106
106
  <label for="business.number">NZBN</label>
107
- <Input class="mb-0" name="business.number" placeholder="Appears on your documents" state={state}
108
- onChange={onChange(setState)} />
107
+ <Field class="mb-0" name="business.number" type="text" rows="23" placeholder="Appears on your documents" state={state}
108
+ onChange={onChange.bind(setState)} />
109
109
  </div>
110
110
  </div>
111
111
  </form>
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  // todo: finish tailwind conversion
3
- import { Button, FormError, Input, Modal, Select } from 'nitro-web'
3
+ import { Button, FormError, Field, Modal, Select } from 'nitro-web'
4
4
  import SvgTick from 'nitro-web/client/imgs/icons/tick.svg'
5
5
 
6
6
  export function SettingsTeamMember ({ showModal, setShowModal }) {
@@ -38,7 +38,7 @@ export function SettingsTeamMember ({ showModal, setShowModal }) {
38
38
  name="role"
39
39
  isSearchable={false}
40
40
  placeholder="Select a role"
41
- onChange={onChange(setState)}
41
+ onChange={onChange.bind(setState)}
42
42
  state={state}
43
43
  minMenuWidth={460}
44
44
  options={[
@@ -65,26 +65,26 @@ export function SettingsTeamMember ({ showModal, setShowModal }) {
65
65
  </div>
66
66
  <div class="col">
67
67
  <label for="email">Email Address</label>
68
- <Input
68
+ <Field
69
69
  name="email" type="email" placeholder="Your email address..." state={state}
70
- onChange={onChange(setState)}
70
+ onChange={onChange.bind(setState)}
71
71
  />
72
72
  </div>
73
73
  <div class="col">
74
74
  <label for="firstName">First Name</label>
75
- <Input name="firstName" placeholder="E.g. Bruce" state={state} onChange={onChange(setState)} />
75
+ <Field name="firstName" placeholder="E.g. Bruce" state={state} onChange={onChange.bind(setState)} />
76
76
  </div>
77
77
  <div class="col">
78
78
  <label for="lastName">Last Name</label>
79
- <Input name="lastName" placeholder="E.g. Wayne" state={state} onChange={onChange(setState)} />
79
+ <Field name="lastName" placeholder="E.g. Wayne" state={state} onChange={onChange.bind(setState)} />
80
80
  </div>
81
81
  <div class="col-12">
82
82
  <label for="message">Invitation Message</label>
83
- <Input
83
+ <Field
84
84
  name="message"
85
85
  type="textarea"
86
86
  placeholder={`${user.firstName} is inviting you to collaborate on Nitro.`}
87
- state={state} onChange={onChange(setState)}
87
+ state={state} onChange={onChange.bind(setState)}
88
88
  />
89
89
  </div>
90
90
  </div>
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Nitro is a battle-tested, modular base project to turbocharge your projects, styled using Tailwind 🚀",
4
4
  "repository": "github:boycce/nitro-web",
5
5
  "homepage": "https://boycce.github.io/nitro-web/",
6
- "version": "0.0.15",
6
+ "version": "0.0.17",
7
7
  "main": "./client/index.ts",
8
8
  "type": "module",
9
9
  "keywords": [
@@ -35,10 +35,10 @@
35
35
  },
36
36
  "scripts": {
37
37
  "dev": "npm run dev -w example",
38
- "dev:client": "npm run dev:client -w example",
39
- "dev:client-only": "isStatic=true npm run dev:client -w example",
38
+ "dev:client": "isDemo=true npm run dev:client -w example",
39
+ "dev:client-only": "isDemo=true isStatic=true npm run dev:client -w example",
40
40
  "dev:server": "npm run dev:server -w example",
41
- "build": "isStatic=true npm run build -w example",
41
+ "build": "isDemo=true isStatic=true npm run build -w example",
42
42
  "major": "npm run types && standard-version --release-as major && npm publish",
43
43
  "minor": "npm run types && standard-version --release-as minor && npm publish",
44
44
  "patch": "npm run types && standard-version --release-as patch && npm publish",
@@ -67,7 +67,7 @@
67
67
  "passport": "^0.4.1",
68
68
  "passport-local": "^1.0.0",
69
69
  "react-currency-input-field": "^3.8.0",
70
- "react-day-picker": "^8.10.1",
70
+ "react-day-picker": "^9.6.4",
71
71
  "react-number-format": "^5.4.0",
72
72
  "react-router-dom": "6.24.1",
73
73
  "react-select": "^5.9.0",
@@ -107,5 +107,9 @@
107
107
  ]
108
108
  },
109
109
  "author": "",
110
- "license": "ISC"
110
+ "license": "ISC",
111
+ "devDependencies": {
112
+ "@types/lodash": "^4.17.15",
113
+ "lodash": "^4.17.21"
114
+ }
111
115
  }
package/readme.md CHANGED
@@ -11,7 +11,7 @@ npm i nitro-web
11
11
  ### Install
12
12
 
13
13
  1. Copy ./_example into your project
14
- 2. In package.json, replace `"nitro-web": "file:.."` with `"nitro-web": "~0.0.15"`
14
+ 2. In package.json, replace `"nitro-web": "file:.."` with `"nitro-web": "~0.0.17"`
15
15
  3. In package.json, replace `"../.eslintrc.json"` with `"./node_modules/nitro-web/.eslintrc.json"`
16
16
  4. Run `npm i`
17
17
 
@@ -31,21 +31,25 @@ const server = await setupRouter(config)
31
31
  server.listen(3001, '0.0.0.0')
32
32
  ```
33
33
 
34
- ### Running in development
34
+ ### Run
35
35
 
36
36
  ```bash
37
+ # Running in development (watching for changes)
37
38
  npm run dev:server # run and watch the nodemon server
38
39
  npm run dev:client # run and watch the webpack dev server
39
- npm run dev # or, run and watch both server and client
40
- ```
41
-
42
- ### Building for production
40
+ npm run dev # or run and watch both the server and client
43
41
 
44
- ```bash
42
+ # Building for production
45
43
  npm run build
46
44
  npm run start
47
45
  ```
48
46
 
47
+ ### Nitro Development
48
+
49
+ The same run commands can be used in ./ which are actually executed in ./example/ via npm workspaces (`-w` flag).
50
+
51
+ If util.js is updated, you must run `npm run types` to update the types file.
52
+
49
53
  ### Versions
50
54
 
51
55
  - Express `^4.17`
@@ -7,6 +7,7 @@ import { CSSInterpolation } from '@emotion/serialize'
7
7
  declare global {
8
8
  /** Webpack injected config variables */
9
9
  const INJECTED: Record<string, string|boolean|object>
10
+ const ISDEMO: boolean
10
11
  /** Webpack svg loader */
11
12
  module '*.svg' {
12
13
  const content: React.FC<React.SVGProps<SVGElement>>
package/types/util.d.ts CHANGED
@@ -78,7 +78,13 @@ export function getCurrencyOptions(currencies: any): {
78
78
  value: string;
79
79
  label: any;
80
80
  }[];
81
- export function getCurrencyPrefixWidth(prefix: any, paddingRight?: number): number;
81
+ /**
82
+ * Get the width of a prefix
83
+ * @param {string} prefix
84
+ * @param {number} paddingRight
85
+ * @returns {number}
86
+ */
87
+ export function getPrefixWidth(prefix: string, paddingRight?: number): number;
82
88
  export function getDirectories(path: any, pwd: any): {
83
89
  clientDir: any;
84
90
  componentsDir: any;
@@ -99,7 +105,12 @@ export function isEmpty(obj: any, truthyValuesOnly: any): boolean;
99
105
  export function isFunction(variable: any): boolean;
100
106
  export function isHex24(value: any): boolean;
101
107
  export function isNumber(variable: any): boolean;
102
- export function isObject(variable: any): boolean;
108
+ /**
109
+ * Checks if a variable is an object
110
+ * @param {unknown} variable
111
+ * @returns {boolean}
112
+ */
113
+ export function isObject(variable: unknown): boolean;
103
114
  export function isRegex(variable: any): boolean;
104
115
  export function isString(variable: any): boolean;
105
116
  export function lcFirst(string: any): any;
@@ -135,16 +146,14 @@ export function objectMap(object: any, fn: any): {};
135
146
  export function omit(obj: any, fields: any): any;
136
147
  /**
137
148
  * Updates state from an input event, you can also update deep state properties
138
- * @param {Function} setState
139
- * @param {Empty | Event | Array[{string}, {string|number|fn}]}
140
- * {Empty} - pass undefined to return a reusable function, e.g. const _onChange = onChange(setState)
141
- * {Event} - pass the event object, e.g. <input onChange={_onChange}>
142
- * {Array} - pass an array with [path, value], e.g. <input onChange={() => _onChange(['name', 'Joe'])}>
149
+ * @param {Event|Array[{string},{string|number|fn}]}
150
+ * {Event} - pass the event object e.g. <input onChange={(e) => onChange.call(setState, e)}>
151
+ * {Array} - pass an array with [path, value] e.g. <input onChange={(e) => onChange.call(setState, e, ['name', 'Joe'])}>
143
152
  * @param {Function} [beforeSetState] - optional function to run before setting the state
144
- *
145
- * @return {Function | Promise({state, chunks, target})}
153
+ * @this {Function} setState
154
+ * @return {Promise({state, chunks, target})}
146
155
  */
147
- export function onChange(setState: Function, event: any, beforeSetState?: Function): Function | Promise<any>;
156
+ export function onChange(this: Function, event: any, beforeSetState?: Function): Promise<any>;
148
157
  export function pad(num: any, padLeft: any, fixedRight: any): any;
149
158
  export function pick(obj: any, keys: any): {};
150
159
  export function queryObject(search: any, assignTrue: any): any;
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BC;AAED,6DAaC;AAED,4DAQC;AAED,iFAaC;AAED,0EAIC;AAED,gDAEC;AAED,0CAEC;AAED,qFAQC;AAED,uDAIC;AAED,iEAoBC;AAED;;;;EAgIC;AAED,wCASC;AAED,mDAYC;AAED,+DAyBC;AAED,iEAeC;AAED,kFA2BC;AAED,gEAIC;AAED,6CASC;AAED,qEAsEC;AAED,8CAGC;AAED,kDAQC;AAED;;;;IAOC;AAED;;;IAOC;AAED,mFAUC;AAED;;;;;;;EAUC;AAED,sDAYC;AAED,uEAEC;AAED,kDAsBC;AAED,+DAaC;AAED,0DAEC;AAED,+CAEC;AAED,kDAEC;AAED,6CAIC;AAED,kEAOC;AAED,mDAEC;AAED,6CAiBC;AAED,iDAEC;AAED,iDAGC;AAED,gDAEC;AAED,iDAEC;AAED,0CAEC;AAED,yEAWC;AAED,mFAwCC;AAED;;;;;;;;;;;;;;;;;;;;;;;;EA0CC;AAED,uEAmBC;AAED,oDAKC;AAED,iDAOC;AAED;;;;;;;;;;GAUG;AAEH,qFAHY,uBAAkB,CA4C7B;AAED,kEAQC;AAED,8CAeC;AAED,+DAiCC;AAED,8CAcC;AAED,yFAiDC;AAED,oDAYC;AAED,4EAmBC;AAED,kDAUC;AAED,mFAiDC;AAED,oEAaC;AAED,8EAIC;AAED,0DAQC;AAED,uDAMC;AAED,mFAwBC;AAED;;;;EAyBC;AAED,8CAIC;AAED,uCAGC;AAED,0CAGC;AAhoCD,6BAAoC"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../util.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BC;AAED,6DAaC;AAED,4DAQC;AAED,iFAaC;AAED,0EAIC;AAED,gDAEC;AAED,0CAEC;AAED,qFAQC;AAED,uDAIC;AAED,iEAoBC;AAED;;;;EAgIC;AAED,wCASC;AAED,mDAYC;AAED,+DAyBC;AAED,iEAeC;AAED,kFA2BC;AAED,gEAIC;AAED,6CASC;AAED,qEAsEC;AAED,8CAGC;AAED,kDAQC;AAED;;;;IAOC;AAED;;;IAOC;AAED;;;;;GAKG;AACH,uCAJW,MAAM,iBACN,MAAM,GACJ,MAAM,CAYlB;AAED;;;;;;;EAUC;AAED,sDAYC;AAED,uEAEC;AAED,kDAsBC;AAED,+DAaC;AAED,0DAEC;AAED,+CAEC;AAED,kDAEC;AAED,6CAIC;AAED,kEAOC;AAED,mDAEC;AAED,6CAiBC;AAED,iDAEC;AAED;;;;GAIG;AACH,mCAHW,OAAO,GACL,OAAO,CAKnB;AAED,gDAEC;AAED,iDAEC;AAED,0CAEC;AAED,yEAWC;AAED,mFAwCC;AAED;;;;;;;;;;;;;;;;;;;;;;;;EA0CC;AAED,uEAmBC;AAED,oDAKC;AAED,iDAOC;AAED;;;;;;;;GAQG;AACH,8FAyCC;AAED,kEAQC;AAED,8CAeC;AAED,+DAiCC;AAED,8CAcC;AAED,yFAiDC;AAED,oDAYC;AAED,4EAmBC;AAED,kDAUC;AAED,mFAiDC;AAED,oEAaC;AAED,8EAIC;AAED,0DAQC;AAED,uDAMC;AAED,mFAwBC;AAED;;;;EAyBC;AAED,8CAIC;AAED,uCAGC;AAED,0CAGC;AAxoCD,6BAAoC"}
package/types.ts CHANGED
@@ -3,8 +3,9 @@ export type Config = {
3
3
  clientUrl: string
4
4
  env: string
5
5
  awsUrl?: string
6
- currencies?: object
7
- countries?: object
6
+ // needed for input-currency.tsx
7
+ currencies: { [key: string]: { symbol: string, digits: number } }
8
+ countries: { [key: string]: { numberFormats: { currency: string } } }
8
9
  googleMapsApiKey?: string
9
10
  isStatic?: boolean
10
11
  placeholderEmail?: string
@@ -22,7 +23,8 @@ export type User = {
22
23
  avatar?: MonasteryImage
23
24
  }
24
25
 
25
- export type Errors = Array<{ title: string, detail: string }> | null
26
+ export type Error = { title: string, detail: string }
27
+ export type Errors = Array<Error> | null
26
28
 
27
29
  export type MonasteryImage = {
28
30
  url: string
package/util.js CHANGED
@@ -479,8 +479,14 @@ export function getCurrencyOptions (currencies) {
479
479
  return output
480
480
  }
481
481
 
482
- export function getCurrencyPrefixWidth (prefix, paddingRight=0) {
483
- if (!prefix) return
482
+ /**
483
+ * Get the width of a prefix
484
+ * @param {string} prefix
485
+ * @param {number} paddingRight
486
+ * @returns {number}
487
+ */
488
+ export function getPrefixWidth (prefix, paddingRight=0) {
489
+ if (!prefix) return 0
484
490
  const span = document.createElement('span')
485
491
  span.classList.add('input-prefix')
486
492
  span.style.visibility = 'hidden'
@@ -614,6 +620,11 @@ export function isNumber (variable) {
614
620
  return !isNaN(parseFloat(variable)) && isFinite(variable)
615
621
  }
616
622
 
623
+ /**
624
+ * Checks if a variable is an object
625
+ * @param {unknown} variable
626
+ * @returns {boolean}
627
+ */
617
628
  export function isObject (variable) {
618
629
  // Excludes null and array's
619
630
  return variable !== null && typeof variable === 'object' && !(variable instanceof Array) ? true : false
@@ -769,19 +780,16 @@ export function omit (obj, fields) {
769
780
 
770
781
  /**
771
782
  * Updates state from an input event, you can also update deep state properties
772
- * @param {Function} setState
773
- * @param {Empty | Event | Array[{string}, {string|number|fn}]}
774
- * {Empty} - pass undefined to return a reusable function, e.g. const _onChange = onChange(setState)
775
- * {Event} - pass the event object, e.g. <input onChange={_onChange}>
776
- * {Array} - pass an array with [path, value], e.g. <input onChange={() => _onChange(['name', 'Joe'])}>
783
+ * @param {Event|Array[{string},{string|number|fn}]}
784
+ * {Event} - pass the event object e.g. <input onChange={(e) => onChange.call(setState, e)}>
785
+ * {Array} - pass an array with [path, value] e.g. <input onChange={(e) => onChange.call(setState, e, ['name', 'Joe'])}>
777
786
  * @param {Function} [beforeSetState] - optional function to run before setting the state
778
- *
779
- * @return {Function | Promise({state, chunks, target})}
787
+ * @this {Function} setState
788
+ * @return {Promise({state, chunks, target})}
780
789
  */
781
- /////////////////////////////////////////////////////////////////////convert to bind
782
- export function onChange (setState, event, beforeSetState) {
783
- if (typeof event === 'undefined') {
784
- return onChange.bind(this, setState)
790
+ export function onChange (event, beforeSetState) {
791
+ if (!isFunction(this)) {
792
+ throw new Error('Missing setState, please either call or bind setState to the function. E.g. onChange.call(setState, e)')
785
793
  }
786
794
  let elem = event.target ? event.target : { id: event[0], value: event[1] }
787
795
  let chunks = (elem.id || elem.name).split('.')
@@ -800,7 +808,7 @@ export function onChange (setState, event, beforeSetState) {
800
808
 
801
809
  // Update state
802
810
  return new Promise((resolve) => {
803
- setState((state) => {
811
+ this((state) => {
804
812
  const newState = { ...state, ...(elem.files ? { hasFiles: true } : {}) }
805
813
  let target = newState
806
814
  for (var i = 0, l = chunks.length; i < l; i++) {
package/webpack.config.js CHANGED
@@ -161,11 +161,6 @@ export const getConfig = (config) => {
161
161
  replace: 'if (false && unsafePseudoClasses',
162
162
  },
163
163
  },
164
- {
165
- test: /styleguide\.html$/i,
166
- exclude: [/\/server\/email/],
167
- loader: 'html-loader',
168
- },
169
164
  {
170
165
  test: /\.csv$/,
171
166
  use: [
@@ -278,6 +273,7 @@ export const getConfig = (config) => {
278
273
  ],
279
274
  }),
280
275
  new webpack.DefinePlugin({
276
+ ISDEMO: !!process.env.isDemo,
281
277
  INJECTED: JSON.stringify({
282
278
  ...pick(config, config.inject ? config.inject.split(' ') : []),
283
279
  }),