laif-ds 0.2.45 → 0.2.46

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.
@@ -11,7 +11,7 @@ Dynamic form component that integrates with React Hook Form to provide a configu
11
11
  ### AppFormItem
12
12
 
13
13
  ```ts
14
- interface AppFormItem {
14
+ export interface AppFormItem {
15
15
  label: string; // Field label
16
16
  component:
17
17
  | "input"
@@ -36,6 +36,54 @@ interface AppFormItem {
36
36
  }
37
37
  ```
38
38
 
39
+ ### Submit Button Inside vs Outside
40
+
41
+ ```tsx
42
+ import { AppForm, Button } from "laif-ds";
43
+ import { useForm } from "react-hook-form";
44
+
45
+ export function SubmitInsideVsOutside() {
46
+ const formInside = useForm({ mode: "onChange" });
47
+ const formOutside = useForm({ mode: "onChange" });
48
+
49
+ const onSubmitInside = (data: any) => console.log("inside", data);
50
+ const onSubmitOutside = (data: any) => console.log("outside", data);
51
+
52
+ return (
53
+ <div className="grid grid-cols-2 gap-6">
54
+ <div>
55
+ {/* Internal submit button rendered by AppForm */}
56
+ <AppForm
57
+ form={formInside}
58
+ items={[{ label: "Name", component: "input", name: "name" }]}
59
+ onSubmit={onSubmitInside}
60
+ showSubmitButton
61
+ />
62
+ </div>
63
+ <div>
64
+ {/* External submit button managed outside */}
65
+ <AppForm
66
+ form={formOutside}
67
+ items={[{ label: "Name", component: "input", name: "name" }]}
68
+ onSubmit={onSubmitOutside}
69
+ />
70
+ <div className="mt-4 flex justify-end">
71
+ <Button
72
+ type="button"
73
+ disabled={
74
+ !formOutside.formState.isValid || !formOutside.formState.isDirty
75
+ }
76
+ onClick={formOutside.handleSubmit(onSubmitOutside)}
77
+ >
78
+ Submit (external)
79
+ </Button>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ );
84
+ }
85
+ ```
86
+
39
87
  ---
40
88
 
41
89
  ## Props
@@ -48,6 +96,7 @@ interface AppFormItem {
48
96
  | `submitText` | `string` | `"Invia"` | Text for submit button |
49
97
  | `onSubmit` | `(data: any) => void` | `undefined` | Form submission callback |
50
98
  | `isSubmitting` | `boolean` | `false` | Shows loading state on submit button |
99
+ | `showSubmitButton` | `boolean` | `false` | Renders an internal submit button at the end of the form |
51
100
 
52
101
  ---
53
102
 
@@ -56,7 +105,7 @@ interface AppFormItem {
56
105
  - **React Hook Form Integration**: Uses `Controller` from React Hook Form for each field
57
106
  - **Validation Display**: Shows validation errors inline with each field
58
107
  - **Grid Layout**: Automatically arranges fields in a responsive grid based on `cols` prop
59
- - **Submit Button**: Automatically disabled when form is invalid or pristine
108
+ - **Submit Button**: Rendered only when `showSubmitButton` is `true`. When shown, it is disabled when the form is invalid or pristine. Otherwise, manage submit externally with `form.handleSubmit(...)`.
60
109
  - **Last Field Spanning**: The last field automatically spans full width
61
110
  - **Error Highlighting**: Fields with errors get red border styling
62
111
 
@@ -238,5 +287,5 @@ export function DateRangeForm() {
238
287
  - **React Hook Form Required**: This component requires React Hook Form to be installed and configured
239
288
  - **Validation**: Use React Hook Form's resolver (e.g., Zod, Yup) for validation
240
289
  - **Grid Layout**: The grid uses Tailwind's grid system with `grid-cols-{n}` classes
241
- - **Submit Button**: Always appears at the end of the form on the right
290
+ - **Submit Button**: Use `showSubmitButton` to render the internal submit button at the end of the form, or provide your own external submit control.
242
291
  - **Error Display**: Errors appear inline above each field and as border highlighting
@@ -1,48 +1,49 @@
1
1
  "use client";
2
- import { jsxs as l, jsx as a } from "react/jsx-runtime";
2
+ import { jsxs as n, jsx as a } from "react/jsx-runtime";
3
3
  import { cn as o } from "../../lib/utils.js";
4
- import { Controller as w } from "../../node_modules/react-hook-form/dist/index.esm.js";
4
+ import { Controller as V } from "../../node_modules/react-hook-form/dist/index.esm.js";
5
5
  import { AppSelect as m } from "./app-select.js";
6
- import { Button as V } from "./button.js";
7
- import { Checkbox as j } from "./checkbox.js";
8
- import { DatePicker as A } from "./date-picker.js";
9
- import { Input as F } from "./input.js";
6
+ import { Button as j } from "./button.js";
7
+ import { Checkbox as A } from "./checkbox.js";
8
+ import { DatePicker as F } from "./date-picker.js";
9
+ import { Input as I } from "./input.js";
10
10
  import { Label as t } from "./label.js";
11
- import { RadioGroup as I, RadioGroupItem as R } from "./radio-group.js";
12
- import { Slider as B } from "./slider.js";
13
- import { Switch as $ } from "./switch.js";
14
- import { Textarea as D } from "./textarea.js";
11
+ import { RadioGroup as R, RadioGroupItem as B } from "./radio-group.js";
12
+ import { Slider as $ } from "./slider.js";
13
+ import { Switch as D } from "./switch.js";
14
+ import { Textarea as G } from "./textarea.js";
15
15
  import { Typo as i } from "./typo.js";
16
- const U = ({
16
+ const X = ({
17
17
  items: h,
18
18
  cols: v = "2",
19
19
  form: b,
20
20
  submitText: g = "Invia",
21
21
  onSubmit: x,
22
- isSubmitting: p = !1
22
+ isSubmitting: p = !1,
23
+ showSubmitButton: C = !1
23
24
  }) => {
24
25
  const {
25
- control: C,
26
- handleSubmit: N,
27
- formState: { errors: y, isValid: f, isDirty: S }
28
- } = b, k = (e) => {
29
- const c = y[e.name]?.message, d = c ? String(c) : void 0;
26
+ control: N,
27
+ handleSubmit: y,
28
+ formState: { errors: f, isValid: S, isDirty: k }
29
+ } = b, w = (e) => {
30
+ const c = f[e.name]?.message, d = c ? String(c) : void 0;
30
31
  return /* @__PURE__ */ a("div", { children: /* @__PURE__ */ a(
31
- w,
32
+ V,
32
33
  {
33
34
  name: e.name,
34
- control: C,
35
+ control: N,
35
36
  render: ({ field: r }) => {
36
- const s = /* @__PURE__ */ l("div", { className: "mb-2 flex items-center justify-between", children: [
37
+ const s = /* @__PURE__ */ n("div", { className: "mb-2 flex items-center justify-between", children: [
37
38
  /* @__PURE__ */ a(t, { children: e.label }),
38
39
  d && /* @__PURE__ */ a("span", { className: "text-d-destructive text-xs", children: d })
39
40
  ] });
40
41
  switch (e.component) {
41
42
  case "input":
42
- return /* @__PURE__ */ l("div", { children: [
43
+ return /* @__PURE__ */ n("div", { children: [
43
44
  s,
44
45
  /* @__PURE__ */ a(
45
- F,
46
+ I,
46
47
  {
47
48
  ...r,
48
49
  placeholder: e.placeholder,
@@ -52,10 +53,10 @@ const U = ({
52
53
  )
53
54
  ] });
54
55
  case "textarea":
55
- return /* @__PURE__ */ l("div", { children: [
56
+ return /* @__PURE__ */ n("div", { children: [
56
57
  s,
57
58
  /* @__PURE__ */ a(
58
- D,
59
+ G,
59
60
  {
60
61
  ...r,
61
62
  placeholder: e.placeholder,
@@ -65,27 +66,27 @@ const U = ({
65
66
  )
66
67
  ] });
67
68
  case "radio":
68
- return /* @__PURE__ */ l("div", { children: [
69
+ return /* @__PURE__ */ n("div", { children: [
69
70
  s,
70
71
  /* @__PURE__ */ a(
71
- I,
72
+ R,
72
73
  {
73
74
  value: r.value != null ? String(r.value) : "",
74
- onValueChange: (n) => r.onChange(n),
75
+ onValueChange: (l) => r.onChange(l),
75
76
  className: "space-y-2",
76
77
  disabled: e.disabled,
77
- children: (e.options ?? []).map((n) => {
78
- const u = `${e.name}-${n.value}`;
79
- return /* @__PURE__ */ l(
78
+ children: (e.options ?? []).map((l) => {
79
+ const u = `${e.name}-${l.value}`;
80
+ return /* @__PURE__ */ n(
80
81
  "div",
81
82
  {
82
83
  className: "flex items-center gap-2",
83
84
  children: [
84
85
  /* @__PURE__ */ a(
85
- R,
86
+ B,
86
87
  {
87
88
  id: u,
88
- value: String(n.value),
89
+ value: String(l.value),
89
90
  disabled: e.disabled
90
91
  }
91
92
  ),
@@ -97,25 +98,25 @@ const U = ({
97
98
  "cursor-pointer",
98
99
  e.disabled && "cursor-not-allowed opacity-60"
99
100
  ),
100
- children: n.label
101
+ children: l.label
101
102
  }
102
103
  )
103
104
  ]
104
105
  },
105
- n.value
106
+ l.value
106
107
  );
107
108
  })
108
109
  }
109
110
  )
110
111
  ] });
111
112
  case "select":
112
- return /* @__PURE__ */ l("div", { children: [
113
+ return /* @__PURE__ */ n("div", { children: [
113
114
  s,
114
115
  /* @__PURE__ */ a(
115
116
  m,
116
117
  {
117
118
  ...r,
118
- onValueChange: (n) => r.onChange(n),
119
+ onValueChange: (l) => r.onChange(l),
119
120
  options: e.options ?? [],
120
121
  placeholder: e.placeholder,
121
122
  disabled: e.disabled
@@ -123,14 +124,14 @@ const U = ({
123
124
  )
124
125
  ] });
125
126
  case "multiselect":
126
- return /* @__PURE__ */ l("div", { children: [
127
+ return /* @__PURE__ */ n("div", { children: [
127
128
  s,
128
129
  /* @__PURE__ */ a(
129
130
  m,
130
131
  {
131
132
  ...r,
132
133
  multiple: !0,
133
- onValueChange: (n) => r.onChange(n),
134
+ onValueChange: (l) => r.onChange(l),
134
135
  options: e.options ?? [],
135
136
  placeholder: e.placeholder,
136
137
  disabled: e.disabled
@@ -138,13 +139,13 @@ const U = ({
138
139
  )
139
140
  ] });
140
141
  case "datepicker":
141
- return /* @__PURE__ */ l("div", { className: "relative", children: [
142
+ return /* @__PURE__ */ n("div", { className: "relative", children: [
142
143
  s,
143
144
  /* @__PURE__ */ a(
144
- A,
145
+ F,
145
146
  {
146
147
  value: r.value,
147
- onChange: e.disabled || e.calendarRange ? void 0 : (n) => r.onChange(n),
148
+ onChange: e.disabled || e.calendarRange ? void 0 : (l) => r.onChange(l),
148
149
  placeholder: e.placeholder,
149
150
  disabled: e.disabled,
150
151
  customCalendarProps: e.disabled ? {
@@ -153,20 +154,20 @@ const U = ({
153
154
  } : e.calendarRange ? {
154
155
  mode: "range",
155
156
  selected: r.value,
156
- onSelect: (n) => r.onChange(n)
157
+ onSelect: (l) => r.onChange(l)
157
158
  } : void 0
158
159
  }
159
160
  )
160
161
  ] });
161
162
  case "checkbox":
162
- return /* @__PURE__ */ l("div", { className: "space-y-1.5", children: [
163
- /* @__PURE__ */ l("div", { className: "flex items-center gap-2", children: [
163
+ return /* @__PURE__ */ n("div", { className: "space-y-1.5", children: [
164
+ /* @__PURE__ */ n("div", { className: "flex items-center gap-2", children: [
164
165
  /* @__PURE__ */ a(
165
- j,
166
+ A,
166
167
  {
167
168
  ...r,
168
169
  id: e.name,
169
- onCheckedChange: (n) => r.onChange(n),
170
+ onCheckedChange: (l) => r.onChange(l),
170
171
  defaultChecked: !!e.defaultValue,
171
172
  disabled: e.disabled
172
173
  }
@@ -194,9 +195,9 @@ const U = ({
194
195
  )
195
196
  ] });
196
197
  case "switch":
197
- return /* @__PURE__ */ l("div", { className: "space-y-1.5", children: [
198
- /* @__PURE__ */ l("div", { className: "flex items-center justify-between", children: [
199
- /* @__PURE__ */ l("div", { children: [
198
+ return /* @__PURE__ */ n("div", { className: "space-y-1.5", children: [
199
+ /* @__PURE__ */ n("div", { className: "flex items-center justify-between", children: [
200
+ /* @__PURE__ */ n("div", { children: [
200
201
  /* @__PURE__ */ a(t, { htmlFor: e.name, children: e.label }),
201
202
  e.caption && /* @__PURE__ */ a(
202
203
  i,
@@ -208,11 +209,11 @@ const U = ({
208
209
  )
209
210
  ] }),
210
211
  /* @__PURE__ */ a(
211
- $,
212
+ D,
212
213
  {
213
214
  id: e.name,
214
215
  checked: !!r.value,
215
- onCheckedChange: (n) => r.onChange(n),
216
+ onCheckedChange: (l) => r.onChange(l),
216
217
  disabled: e.disabled
217
218
  }
218
219
  )
@@ -220,13 +221,13 @@ const U = ({
220
221
  d && /* @__PURE__ */ a("span", { className: "text-d-destructive text-xs", children: d })
221
222
  ] });
222
223
  case "slider":
223
- return /* @__PURE__ */ l("div", { children: [
224
+ return /* @__PURE__ */ n("div", { children: [
224
225
  s,
225
226
  /* @__PURE__ */ a(
226
- B,
227
+ $,
227
228
  {
228
229
  value: Array.isArray(r.value) ? r.value : [r.value || e.min || 0],
229
- onValueChange: (n) => r.onChange(n[0]),
230
+ onValueChange: (l) => r.onChange(l[0]),
230
231
  min: e.min ?? 0,
231
232
  max: e.max ?? 100,
232
233
  step: e.step ?? 1,
@@ -248,20 +249,20 @@ const U = ({
248
249
  }
249
250
  ) });
250
251
  };
251
- return /* @__PURE__ */ l("form", { onSubmit: N((e) => x?.(e)), children: [
252
+ return /* @__PURE__ */ n("form", { onSubmit: y((e) => x?.(e)), children: [
252
253
  /* @__PURE__ */ a("div", { className: o("grid gap-4", `grid-cols-${v}`), children: h.map((e, c) => /* @__PURE__ */ a(
253
254
  "div",
254
255
  {
255
256
  className: o(c === h.length - 1 && "col-span-full"),
256
- children: k(e)
257
+ children: w(e)
257
258
  },
258
259
  e.name
259
260
  )) }),
260
- /* @__PURE__ */ a("div", { className: "mt-4 flex justify-end", children: /* @__PURE__ */ a(
261
- V,
261
+ C && /* @__PURE__ */ a("div", { className: "mt-4 flex justify-end", children: /* @__PURE__ */ a(
262
+ j,
262
263
  {
263
264
  type: "submit",
264
- disabled: !f || !S || p,
265
+ disabled: !S || !k || p,
265
266
  isLoading: p,
266
267
  children: g
267
268
  }
@@ -269,5 +270,5 @@ const U = ({
269
270
  ] });
270
271
  };
271
272
  export {
272
- U as AppForm
273
+ X as AppForm
273
274
  };
@@ -7,9 +7,10 @@ import { Popover as I, PopoverTrigger as E, PopoverContent as R } from "./popove
7
7
  import { cn as T } from "../../lib/utils.js";
8
8
  import * as x from "react";
9
9
  import { useEffect as V } from "react";
10
+ import { it as q } from "../../node_modules/date-fns/locale/it.js";
10
11
  import { formatDate as m } from "../../node_modules/date-fns/format.js";
11
- import { isSameDay as q } from "../../node_modules/date-fns/isSameDay.js";
12
- function U({
12
+ import { isSameDay as A } from "../../node_modules/date-fns/isSameDay.js";
13
+ function X({
13
14
  value: e,
14
15
  onChange: c,
15
16
  placeholder: b = "Seleziona data",
@@ -21,7 +22,7 @@ function U({
21
22
  firstDate: a,
22
23
  lastDate: p,
23
24
  availableDates: l,
24
- locale: C,
25
+ locale: C = q,
25
26
  initialCalendarMonth: u,
26
27
  customCalendarProps: P
27
28
  }) {
@@ -33,7 +34,7 @@ function U({
33
34
  let s = [];
34
35
  return a && s.push({ before: a }), p && s.push({ after: p }), l?.length && s.push(
35
36
  (n) => !l.some(
36
- (M) => q(M, n)
37
+ (M) => A(M, n)
37
38
  )
38
39
  ), t && (s = [!0]), V(() => {
39
40
  h(r), g(r || u);
@@ -88,5 +89,5 @@ function U({
88
89
  ] });
89
90
  }
90
91
  export {
91
- U as DatePicker
92
+ X as DatePicker
92
93
  };
package/dist/index.d.ts CHANGED
@@ -146,9 +146,9 @@ declare interface AppEditorProps {
146
146
 
147
147
  declare type AppEditorToolbar = "block-format" | "font-format" | "history";
148
148
 
149
- export declare const AppForm: ({ items, cols, form, submitText, onSubmit, isSubmitting, }: AppFormProps) => JSX.Element;
149
+ export declare const AppForm: ({ items, cols, form, submitText, onSubmit, isSubmitting, showSubmitButton, }: AppFormProps) => JSX.Element;
150
150
 
151
- declare interface AppFormItem {
151
+ export declare interface AppFormItem {
152
152
  label: string;
153
153
  component: "input" | "select" | "textarea" | "checkbox" | "multiselect" | "datepicker" | "radio" | "switch" | "slider";
154
154
  name: string;
@@ -164,12 +164,13 @@ declare interface AppFormItem {
164
164
  }
165
165
 
166
166
  declare interface AppFormProps {
167
- cols?: "2" | "1" | "3";
167
+ cols?: "1" | "2" | "3";
168
168
  items: AppFormItem[];
169
169
  form: UseFormReturn<any>;
170
170
  submitText?: string;
171
171
  onSubmit?: (data: any) => void;
172
172
  isSubmitting?: boolean;
173
+ showSubmitButton?: boolean;
173
174
  }
174
175
 
175
176
  /**
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { constructFrom as e } from "../constructFrom.js";
3
- function i(r, ...n) {
4
- const o = e.bind(
3
+ function c(o, ...n) {
4
+ const t = e.bind(
5
5
  null,
6
- n.find((t) => typeof t == "object")
6
+ o || n.find((r) => typeof r == "object")
7
7
  );
8
- return n.map(o);
8
+ return n.map(t);
9
9
  }
10
10
  export {
11
- i as normalizeDates
11
+ c as normalizeDates
12
12
  };
@@ -0,0 +1,15 @@
1
+ "use client";
2
+ import { normalizeDates as f } from "./_lib/normalizeDates.js";
3
+ import { startOfWeek as r } from "./startOfWeek.js";
4
+ function o(t, a, e) {
5
+ const [i, m] = f(
6
+ e?.in,
7
+ t,
8
+ a
9
+ );
10
+ return +r(i, e) == +r(m, e);
11
+ }
12
+ export {
13
+ o as default,
14
+ o as isSameWeek
15
+ };
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ const i = {
3
+ lessThanXSeconds: {
4
+ one: "meno di un secondo",
5
+ other: "meno di {{count}} secondi"
6
+ },
7
+ xSeconds: {
8
+ one: "un secondo",
9
+ other: "{{count}} secondi"
10
+ },
11
+ halfAMinute: "alcuni secondi",
12
+ lessThanXMinutes: {
13
+ one: "meno di un minuto",
14
+ other: "meno di {{count}} minuti"
15
+ },
16
+ xMinutes: {
17
+ one: "un minuto",
18
+ other: "{{count}} minuti"
19
+ },
20
+ aboutXHours: {
21
+ one: "circa un'ora",
22
+ other: "circa {{count}} ore"
23
+ },
24
+ xHours: {
25
+ one: "un'ora",
26
+ other: "{{count}} ore"
27
+ },
28
+ xDays: {
29
+ one: "un giorno",
30
+ other: "{{count}} giorni"
31
+ },
32
+ aboutXWeeks: {
33
+ one: "circa una settimana",
34
+ other: "circa {{count}} settimane"
35
+ },
36
+ xWeeks: {
37
+ one: "una settimana",
38
+ other: "{{count}} settimane"
39
+ },
40
+ aboutXMonths: {
41
+ one: "circa un mese",
42
+ other: "circa {{count}} mesi"
43
+ },
44
+ xMonths: {
45
+ one: "un mese",
46
+ other: "{{count}} mesi"
47
+ },
48
+ aboutXYears: {
49
+ one: "circa un anno",
50
+ other: "circa {{count}} anni"
51
+ },
52
+ xYears: {
53
+ one: "un anno",
54
+ other: "{{count}} anni"
55
+ },
56
+ overXYears: {
57
+ one: "più di un anno",
58
+ other: "più di {{count}} anni"
59
+ },
60
+ almostXYears: {
61
+ one: "quasi un anno",
62
+ other: "quasi {{count}} anni"
63
+ }
64
+ }, r = (a, t, o) => {
65
+ let n;
66
+ const e = i[a];
67
+ return typeof e == "string" ? n = e : t === 1 ? n = e.one : n = e.other.replace("{{count}}", t.toString()), o?.addSuffix ? o.comparison && o.comparison > 0 ? "tra " + n : n + " fa" : n;
68
+ };
69
+ export {
70
+ r as formatDistance
71
+ };
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { buildFormatLongFn as t } from "../../_lib/buildFormatLongFn.js";
3
+ const m = {
4
+ full: "EEEE d MMMM y",
5
+ long: "d MMMM y",
6
+ medium: "d MMM y",
7
+ short: "dd/MM/y"
8
+ }, e = {
9
+ full: "HH:mm:ss zzzz",
10
+ long: "HH:mm:ss z",
11
+ medium: "HH:mm:ss",
12
+ short: "HH:mm"
13
+ }, d = {
14
+ full: "{{date}} {{time}}",
15
+ long: "{{date}} {{time}}",
16
+ medium: "{{date}} {{time}}",
17
+ short: "{{date}} {{time}}"
18
+ }, l = {
19
+ date: t({
20
+ formats: m,
21
+ defaultWidth: "full"
22
+ }),
23
+ time: t({
24
+ formats: e,
25
+ defaultWidth: "full"
26
+ }),
27
+ dateTime: t({
28
+ formats: d,
29
+ defaultWidth: "full"
30
+ })
31
+ };
32
+ export {
33
+ l as formatLong
34
+ };
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ import { isSameWeek as l } from "../../../isSameWeek.js";
3
+ const a = [
4
+ "domenica",
5
+ "lunedì",
6
+ "martedì",
7
+ "mercoledì",
8
+ "giovedì",
9
+ "venerdì",
10
+ "sabato"
11
+ ];
12
+ function i(e) {
13
+ switch (e) {
14
+ case 0:
15
+ return "'domenica scorsa alle' p";
16
+ default:
17
+ return "'" + a[e] + " scorso alle' p";
18
+ }
19
+ }
20
+ function s(e) {
21
+ return "'" + a[e] + " alle' p";
22
+ }
23
+ function c(e) {
24
+ switch (e) {
25
+ case 0:
26
+ return "'domenica prossima alle' p";
27
+ default:
28
+ return "'" + a[e] + " prossimo alle' p";
29
+ }
30
+ }
31
+ const u = {
32
+ lastWeek: (e, r, o) => {
33
+ const t = e.getDay();
34
+ return l(e, r, o) ? s(t) : i(t);
35
+ },
36
+ yesterday: "'ieri alle' p",
37
+ today: "'oggi alle' p",
38
+ tomorrow: "'domani alle' p",
39
+ nextWeek: (e, r, o) => {
40
+ const t = e.getDay();
41
+ return l(e, r, o) ? s(t) : c(t);
42
+ },
43
+ other: "P"
44
+ }, f = (e, r, o, t) => {
45
+ const n = u[e];
46
+ return typeof n == "function" ? n(r, o, t) : n;
47
+ };
48
+ export {
49
+ f as formatRelative
50
+ };