ferns-ui 1.4.0 → 1.5.1

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.
@@ -333,3 +333,38 @@ export function getIsoDate(date: string | undefined): string | undefined {
333
333
  }
334
334
  return convertNullToUndefined(DateTime.fromISO(date).toUTC().toISO());
335
335
  }
336
+
337
+ const usTimezoneOptions = [
338
+ {label: "Eastern", value: "America/New_York"},
339
+ {label: "Central", value: "America/Chicago"},
340
+ {label: "Mountain", value: "America/Denver"},
341
+ {label: "Pacific", value: "America/Los_Angeles"},
342
+ {label: "Alaska", value: "America/Anchorage"},
343
+ {label: "Hawaii", value: "Pacific/Honolulu"},
344
+ {label: "Arizona", value: "America/Phoenix"},
345
+ ];
346
+
347
+ export function getTimezoneOptions(location: "USA" | "Worldwide", shortTimezone = false) {
348
+ let timezones: [string, string][];
349
+ if (location === "USA") {
350
+ timezones = usTimezoneOptions.map((tz) => [tz.label, tz.value]);
351
+ } else {
352
+ timezones = (Intl as any).supportedValuesOf("timeZone").map((tz: any) => {
353
+ return [tz, tz];
354
+ });
355
+ }
356
+ return timezones.map(([name, tz]) => {
357
+ const dateTime = DateTime.now().setZone(tz);
358
+ let tzAbbr = dateTime.toFormat("ZZZZ"); // Gets timezone abbreviation like "EST", "CST", etc.
359
+
360
+ // Special case for Arizona which returns MST during standard time
361
+ if (tz === "America/Phoenix") {
362
+ tzAbbr = "AZ";
363
+ }
364
+
365
+ return {
366
+ label: shortTimezone ? tzAbbr : name,
367
+ value: tz,
368
+ };
369
+ });
370
+ }
package/src/Field.tsx CHANGED
@@ -50,7 +50,7 @@ export const Field: FC<FieldProps> = ({type, ...rest}) => {
50
50
  } else if (type && ["date", "time", "datetime"].includes(type)) {
51
51
  return (
52
52
  <DateTimeField
53
- {...(rest as DateTimeFieldProps)}
53
+ {...(rest as DateTimeFieldProps as any)}
54
54
  type={type as "date" | "time" | "datetime"}
55
55
  />
56
56
  );
@@ -25,7 +25,7 @@ export const PhoneNumberField: FC<PhoneNumberFieldProps> = ({
25
25
 
26
26
  const validatePhoneNumber = useCallback(
27
27
  (phoneNumber: string): string | undefined => {
28
- if (phoneNumber.trim() === "") {
28
+ if (!phoneNumber || phoneNumber.trim() === "") {
29
29
  return undefined;
30
30
  }
31
31
  const parsedNumber = parsePhoneNumberFromString(phoneNumber, defaultCountryCode);
@@ -85,10 +85,10 @@ export const PhoneNumberField: FC<PhoneNumberFieldProps> = ({
85
85
  if (error && !validationError) {
86
86
  setError(undefined);
87
87
  }
88
+
89
+ // Ensure invalid values don't propagate up
88
90
  if (!validationError) {
89
91
  onChange(formattedValue);
90
- } else {
91
- onChange(""); // Ensure invalid values don't propagate up
92
92
  }
93
93
  },
94
94
  [onChange, error, validatePhoneNumber, formatPhoneNumber]
@@ -1,37 +1,46 @@
1
1
  import React from "react";
2
2
 
3
- import {Box} from "./Box";
4
- import {TimezonePickerProps} from "./Common";
3
+ import {SelectFieldPropsBase} from "./Common";
4
+ import {getTimezoneOptions} from "./DateUtilities";
5
5
  import {SelectField} from "./SelectField";
6
6
 
7
- // TODO: Support world wide timezones
8
- const options = [
9
- {label: "Eastern", value: "America/New_York"},
10
- {label: "Central", value: "America/Chicago"},
11
- {label: "Mountain", value: "America/Denver"},
12
- {label: "Pacific", value: "America/Los_Angeles"},
13
- {label: "Alaska", value: "America/Anchorage"},
14
- {label: "Hawaii", value: "Pacific/Honolulu"},
15
- {label: "Arizona", value: "America/Phoenix"},
16
- ];
7
+ interface TimezonePickerProps extends Omit<SelectFieldPropsBase, "options"> {
8
+ timezone?: string;
9
+ onChange: (value: string) => void;
10
+ location?: "USA" | "Worldwide";
11
+ hideTitle?: boolean;
12
+ shortTimezone?: boolean;
13
+ }
17
14
 
18
- export const TimezonePicker = ({
15
+ export const TimezonePicker: React.FC<TimezonePickerProps> = ({
19
16
  timezone,
20
17
  onChange,
21
- showLabel,
22
- width = 100,
18
+ location = "USA",
19
+ hideTitle = false,
20
+ shortTimezone = false,
21
+ ...fieldProps
23
22
  }: TimezonePickerProps): React.ReactElement => {
24
- if (showLabel) {
25
- return (
26
- <Box maxWidth={width}>
27
- <SelectField options={options} title="Timezone" value={timezone} onChange={onChange} />
28
- </Box>
29
- );
30
- } else {
31
- return (
32
- <Box maxWidth={width}>
33
- <SelectField options={options} value={timezone} onChange={onChange} />
34
- </Box>
35
- );
23
+ // eslint-disable-next-line react/display-name
24
+ const tzOptions = React.useMemo(
25
+ () => getTimezoneOptions(location, shortTimezone),
26
+ [location, shortTimezone]
27
+ );
28
+
29
+ // Check that value is in the list of options
30
+ const valueIndex = tzOptions.findIndex((t) => t.value === timezone);
31
+ if (valueIndex === -1) {
32
+ console.warn(`${timezone} is not a valid timezone`);
36
33
  }
34
+
35
+ const title = hideTitle ? undefined : "Timezone";
36
+
37
+ return (
38
+ <SelectField
39
+ title={title}
40
+ {...fieldProps}
41
+ options={tzOptions}
42
+ value={timezone}
43
+ onChange={onChange}
44
+ />
45
+ );
37
46
  };
@@ -60,7 +60,7 @@ export const TableBoolean: FC<TableBooleanProps> = ({value, isEditing = false})
60
60
  justifyContent: "center",
61
61
  }}
62
62
  >
63
- <Icon color={value ? "success" : "secondaryLight"} iconName={value ? "check" : "x"} />
63
+ <Icon color={value ? "success" : "error"} iconName={value ? "check" : "x"} />
64
64
  </View>
65
65
  </View>
66
66
  );