@scm-manager/ui-components 4.0.0-REACT19-20250928-144148 → 4.0.0-REACT19-20251020-110745

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scm-manager/ui-components",
3
- "version": "4.0.0-REACT19-20250928-144148",
3
+ "version": "4.0.0-REACT19-20251020-110745",
4
4
  "description": "UI Components for SCM-Manager and its plugins",
5
5
  "main": "src/index.ts",
6
6
  "files": [
@@ -36,8 +36,8 @@
36
36
  "@scm-manager/eslint-config": "^2.18.2",
37
37
  "@scm-manager/prettier-config": "^2.12.0",
38
38
  "@scm-manager/tsconfig": "^2.13.0",
39
- "@scm-manager/ui-syntaxhighlighting": "4.0.0-REACT19-20250928-144148",
40
- "@scm-manager/ui-types": "4.0.0-REACT19-20250928-144148",
39
+ "@scm-manager/ui-syntaxhighlighting": "4.0.0-REACT19-20251020-110745",
40
+ "@scm-manager/ui-types": "4.0.0-REACT19-20251020-110745",
41
41
  "@storybook/addon-actions": "^9.0.8",
42
42
  "@storybook/addon-docs": "^9.1.5",
43
43
  "@storybook/addon-essentials": "^9.0.0-alpha.12",
@@ -68,9 +68,9 @@
68
68
  "vitest": "^3.2.4"
69
69
  },
70
70
  "dependencies": {
71
- "@scm-manager/ui-api": "4.0.0-REACT19-20250928-144148",
72
- "@scm-manager/ui-core": "4.0.0-REACT19-20250928-144148",
73
- "@scm-manager/ui-extensions": "4.0.0-REACT19-20250928-144148",
71
+ "@scm-manager/ui-api": "4.0.0-REACT19-20251020-110745",
72
+ "@scm-manager/ui-core": "4.0.0-REACT19-20251020-110745",
73
+ "@scm-manager/ui-extensions": "4.0.0-REACT19-20251020-110745",
74
74
  "deepmerge": "^4.2.2",
75
75
  "hast-util-sanitize": "^3.0.2",
76
76
  "react-diff-view": "2.6.0",
@@ -68,7 +68,7 @@ import type { Meta, StoryObj } from "@storybook/react";
68
68
 
69
69
  import CardColumn from "./CardColumn";
70
70
  import Icon from "./Icon";
71
- import { DateFromNow } from ".";
71
+ import { DateFromNow } from "@scm-manager/ui-core";
72
72
  import repository from "./__resources__/repository";
73
73
 
74
74
  const Wrapper = styled.div`
@@ -122,7 +122,7 @@ export const WithHoverableDate: Story = {
122
122
  footerLeft: footerLeft,
123
123
  footerRight: (
124
124
  <small className="level-item">
125
- <DateFromNow baseDate={baseDate} date={repository.creationDate} />
125
+ <DateFromNow date={repository.creationDate} />
126
126
  </small>
127
127
  ),
128
128
  },
@@ -65,7 +65,7 @@
65
65
  import React from "react";
66
66
  import type { Meta, StoryObj } from "@storybook/react";
67
67
 
68
- import DateShort from "./DateShort";
68
+ import { DateShort } from "@scm-manager/ui-core";
69
69
 
70
70
  const baseProps = {
71
71
  timeZone: "Europe/Berlin",
@@ -1,4 +1,4 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`Storyshots BranchSelector Default 1`] = `
4
4
  <div
package/src/index.ts CHANGED
@@ -34,9 +34,6 @@ import {
34
34
 
35
35
  export { validation, repositories };
36
36
 
37
- export { default as DateFromNow } from "./DateFromNow";
38
- export { default as DateShort } from "./DateShort";
39
- export { default as useDateFormatter } from "./useDateFormatter";
40
37
  export { default as Duration } from "./Duration";
41
38
  export { default as ErrorNotification } from "./ErrorNotification";
42
39
  export { default as ErrorPage } from "./ErrorPage";
@@ -181,7 +181,7 @@ const bindBeforeTitle = (binder: Binder, extension: ReactNode) => {
181
181
 
182
182
  const withBinder = (binder: Binder, repo: Repository) => (
183
183
  <BinderContext.Provider value={binder}>
184
- <RepositoryEntry repository={repo} baseDate={baseDate} />
184
+ <RepositoryEntry repository={repo} />
185
185
  </BinderContext.Provider>
186
186
  );
187
187
 
@@ -215,7 +215,8 @@ const meta: Meta<typeof RepositoryEntry> = {
215
215
  component: RepositoryEntry,
216
216
  decorators: [
217
217
  (Story) => <MemoryRouter initialEntries={["/"]}>{Story()}</MemoryRouter>,
218
- (Story) => <Container>{Story()}</Container>],
218
+ (Story) => <Container>{Story()}</Container>,
219
+ ],
219
220
  tags: ["autodocs"],
220
221
  };
221
222
 
@@ -226,7 +227,6 @@ type Story = StoryObj<typeof meta>;
226
227
  export const Default: Story = {
227
228
  args: {
228
229
  repository: repository,
229
- baseDate: baseDate,
230
230
  },
231
231
  };
232
232
 
@@ -234,7 +234,6 @@ export const WithLongTexts: Story = {
234
234
  name: "With Long Texts",
235
235
  args: {
236
236
  repository: longTextRepository,
237
- baseDate: baseDate,
238
237
  },
239
238
  };
240
239
 
@@ -18,20 +18,14 @@ import React, { FC } from "react";
18
18
  import { useTranslation } from "react-i18next";
19
19
  import { Link } from "react-router-dom";
20
20
  import styled from "styled-components";
21
- import { Card, Icon, Menu, useKeyboardIteratorTargetV2 } from "@scm-manager/ui-core";
21
+ import { Card, Icon, Menu, useKeyboardIteratorTargetV2, DateFromNow } from "@scm-manager/ui-core";
22
22
  import { ExtensionPoint, extensionPoints } from "@scm-manager/ui-extensions";
23
23
  import { Repository } from "@scm-manager/ui-types";
24
- import DateFromNow from "../DateFromNow";
25
24
  import RepositoryAvatar from "./RepositoryAvatar";
26
25
  import RepositoryFlags from "./RepositoryFlags";
27
26
 
28
- type DateProp = Date | string;
29
-
30
27
  type Props = {
31
28
  repository: Repository;
32
- // @VisibleForTesting
33
- // the baseDate is only to avoid failing snapshot tests
34
- baseDate?: DateProp;
35
29
  expectedIndex?: number;
36
30
  };
37
31
 
@@ -57,7 +51,7 @@ const DetailsRow = styled(Card.Row)`
57
51
  gap: 0.5rem;
58
52
  `;
59
53
 
60
- const RepositoryEntry: FC<Props> = ({ repository, baseDate, expectedIndex }) => {
54
+ const RepositoryEntry: FC<Props> = ({ repository, expectedIndex }) => {
61
55
  const [t] = useTranslation("repos");
62
56
  const ref = useKeyboardIteratorTargetV2({ expectedIndex: expectedIndex ?? 0 });
63
57
 
@@ -120,8 +114,7 @@ const RepositoryEntry: FC<Props> = ({ repository, baseDate, expectedIndex }) =>
120
114
  <DescriptionRow className="is-size-7">{repository.description}</DescriptionRow>
121
115
  <DetailsRow className="is-flex is-align-items-center is-justify-content-space-between is-flex-wrap-wrap">
122
116
  <span className="is-size-7 has-text-secondary is-relative">
123
- {t("overview.lastModified")}{" "}
124
- <DateFromNow baseDate={baseDate} date={repository.lastModified ?? repository.creationDate} />
117
+ {t("overview.lastModified")} <DateFromNow date={repository.lastModified ?? repository.creationDate} />
125
118
  </span>
126
119
  <RepositoryFlags repository={repository} />
127
120
  </DetailsRow>
@@ -260,7 +260,6 @@ export const Default: Story = {
260
260
  // Die Props für die Komponente werden in das `args`-Objekt verschoben.
261
261
  source: source,
262
262
  repository: repository,
263
- baseDate: new Date("2020-04-16T09:22:42Z"),
264
263
  },
265
264
  };
266
265
 
@@ -268,7 +267,6 @@ export const Markdown: Story = {
268
267
  args: {
269
268
  source: markdownSource,
270
269
  repository: repository,
271
- baseDate: new Date("2020-04-15T09:47:42Z"),
272
270
  },
273
271
  };
274
272
 
@@ -16,7 +16,6 @@
16
16
 
17
17
  import React, { FC, useReducer } from "react";
18
18
  import { AnnotatedLine, AnnotatedSource, Repository } from "@scm-manager/ui-types";
19
- import { DateInput } from "../../useDateFormatter";
20
19
  import AnnotatePopover from "./AnnotatePopover";
21
20
  import AnnotateLine from "./AnnotateLine";
22
21
  import { Action } from "./actions";
@@ -26,7 +25,6 @@ import { SyntaxHighlighter } from "@scm-manager/ui-syntaxhighlighting";
26
25
  type Props = {
27
26
  source: AnnotatedSource;
28
27
  repository: Repository;
29
- baseDate?: DateInput;
30
28
  };
31
29
 
32
30
  type State = {
@@ -83,7 +81,7 @@ const reducer = (state: State, action: Action): State => {
83
81
  }
84
82
  };
85
83
 
86
- const Annotate: FC<Props> = ({ source, repository, baseDate }) => {
84
+ const Annotate: FC<Props> = ({ source, repository }) => {
87
85
  const [state, dispatch] = useReducer(reducer, initialState);
88
86
 
89
87
  const defaultRenderer: FC = ({ children }: any) => {
@@ -122,7 +120,6 @@ const Annotate: FC<Props> = ({ source, repository, baseDate }) => {
122
120
  dispatch={dispatch}
123
121
  offsetTop={state.offset}
124
122
  repository={repository}
125
- baseDate={baseDate}
126
123
  />
127
124
  );
128
125
  }
@@ -17,7 +17,7 @@
17
17
  import React, { FC, Dispatch, useRef, ReactNode } from "react";
18
18
  import styled from "styled-components";
19
19
  import AuthorImage from "./AuthorImage";
20
- import DateShort from "../../DateShort";
20
+ import { DateShort } from "@scm-manager/ui-core";
21
21
  import { Action } from "./actions";
22
22
  import { AnnotatedLine } from "@scm-manager/ui-types";
23
23
 
@@ -17,9 +17,8 @@
17
17
  import React, { FC, useState, useRef, useLayoutEffect, Dispatch } from "react";
18
18
  import styled from "styled-components";
19
19
  import { Link } from "react-router-dom";
20
- import DateFromNow from "../../DateFromNow";
20
+ import { AbsoluteDate } from "@scm-manager/ui-core";
21
21
  import { SingleContributor } from "../changesets";
22
- import { DateInput } from "../../useDateFormatter";
23
22
  import { Repository, AnnotatedLine } from "@scm-manager/ui-types";
24
23
  import AuthorImage from "./AuthorImage";
25
24
  import { Action } from "./actions";
@@ -73,11 +72,10 @@ type PopoverProps = {
73
72
  annotation: AnnotatedLine;
74
73
  offsetTop?: number;
75
74
  repository: Repository;
76
- baseDate?: DateInput;
77
75
  dispatch: Dispatch<Action>;
78
76
  };
79
77
 
80
- const AnnotatePopover: FC<PopoverProps> = ({ annotation, offsetTop, repository, baseDate, dispatch }) => {
78
+ const AnnotatePopover: FC<PopoverProps> = ({ annotation, offsetTop, repository, dispatch }) => {
81
79
  const [t] = useTranslation("repos");
82
80
  const [height, setHeight] = useState(125);
83
81
  const ref = useRef<HTMLDivElement>(null);
@@ -113,7 +111,7 @@ const AnnotatePopover: FC<PopoverProps> = ({ annotation, offsetTop, repository,
113
111
  <AuthorImage person={annotation.author} />
114
112
  <SingleContributor person={annotation.author} displayTextOnly={true} />
115
113
  </span>
116
- <DateFromNow className="is-pulled-right" date={annotation.when} baseDate={baseDate} />
114
+ <AbsoluteDate className="is-pulled-right" date={annotation.when} />
117
115
  </PopoverHeading>
118
116
  <hr className="my-2" />
119
117
  <p>
@@ -24,7 +24,7 @@ import ChangesetAuthor from "./ChangesetAuthor";
24
24
  import SignatureIcon from "./SignatureIcon";
25
25
  import ChangesetTags from "./ChangesetTags";
26
26
  import { parseDescription } from "./changesets";
27
- import DateFromNow from "../../DateFromNow";
27
+ import { DateFromNow } from "@scm-manager/ui-core";
28
28
  import { Changeset, Repository } from "@scm-manager/ui-types";
29
29
  import styled from "styled-components";
30
30
  import ChangesetId from "./ChangesetId";
@@ -1,99 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- // import React from "react";
18
- // import { storiesOf } from "@storybook/react";
19
- // import DateFromNow from "./DateFromNow";
20
- // import DateShort from "./DateShort";
21
- //
22
- // const baseProps = {
23
- // timeZone: "Europe/Berlin",
24
- // baseDate: "2019-10-12T13:56:42+02:00",
25
- // };
26
- //
27
- // const dates = [
28
- // "2009-06-30T18:30:00+02:00",
29
- // "2019-06-30T18:30:00+02:00",
30
- // "2019-10-12T13:56:40+02:00",
31
- // "2019-10-11T13:56:40+02:00",
32
- // ];
33
- //
34
- // storiesOf("Date", module)
35
- // .add("Date from now", () => (
36
- // <div className="p-5">
37
- // {dates.map((d) => (
38
- // <p>
39
- // <DateFromNow date={d} {...baseProps} />
40
- // </p>
41
- // ))}
42
- // </div>
43
- // ))
44
- // .add("Short", () => (
45
- // <div className="p-5">
46
- // {dates.map((d) => (
47
- // <p>
48
- // <DateShort date={d} {...baseProps} />
49
- // </p>
50
- // ))}
51
- // </div>
52
- // ));
53
-
54
- import React from "react";
55
- import type { Meta, StoryObj } from "@storybook/react";
56
-
57
- import DateFromNow from "./DateFromNow";
58
-
59
- const baseProps = {
60
- timeZone: "Europe/Berlin",
61
- baseDate: "2019-10-12T13:56:42+02:00",
62
- };
63
-
64
- const dates = [
65
- "2009-06-30T18:30:00+02:00",
66
- "2019-06-30T18:30:00+02:00",
67
- "2019-10-12T13:56:40+02:00",
68
- "2019-10-11T13:56:40+02:00",
69
- ];
70
-
71
- const meta: Meta<typeof DateFromNow> = {
72
- title: "Components/DateFromNow",
73
- component: DateFromNow,
74
- decorators: [(Story) => <div className="p-5">{Story()}</div>],
75
- tags: ["autodocs"],
76
- };
77
-
78
- export default meta;
79
-
80
- type Story = StoryObj<typeof meta>;
81
-
82
- export const Primary: Story = {
83
- args: {
84
- date: dates[3],
85
- ...baseProps,
86
- },
87
- };
88
-
89
- export const AllExamples: Story = {
90
- render: () => (
91
- <div>
92
- {dates.map((d, i) => (
93
- <p key={i}>
94
- <DateFromNow date={d} {...baseProps} />
95
- </p>
96
- ))}
97
- </div>
98
- ),
99
- };
@@ -1,24 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- import styled from "styled-components";
18
-
19
- const DateElement = styled.time`
20
- border-bottom: 1px dotted rgb(219, 219, 219);
21
- cursor: help;
22
- `;
23
-
24
- export default DateElement;
@@ -1,39 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- import React, { FC } from "react";
18
- import useDateFormatter, { DateProps } from "./useDateFormatter";
19
- import DateElement from "./DateElement";
20
-
21
- type Props = DateProps & {
22
- className?: string;
23
- };
24
-
25
- const DateFromNow: FC<Props> = ({ className, ...dateProps }) => {
26
- const formatter = useDateFormatter(dateProps);
27
- if (!formatter) {
28
- return null;
29
- }
30
-
31
- const dateTime = formatter.formatFull();
32
- return (
33
- <DateElement className={className} dateTime={dateTime} title={dateTime}>
34
- {formatter.formatDistance()}
35
- </DateElement>
36
- );
37
- };
38
-
39
- export default DateFromNow;
package/src/DateShort.tsx DELETED
@@ -1,39 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- import React, { FC } from "react";
18
- import useDateFormatter, { DateProps } from "./useDateFormatter";
19
- import DateElement from "./DateElement";
20
-
21
- type Props = DateProps & {
22
- className?: string;
23
- };
24
-
25
- const DateShort: FC<Props> = ({ className, ...dateProps }) => {
26
- const formatter = useDateFormatter(dateProps);
27
- if (!formatter) {
28
- return null;
29
- }
30
-
31
- const dateTime = formatter.formatFull();
32
- return (
33
- <DateElement className={className} dateTime={dateTime} title={dateTime}>
34
- {formatter.formatShort()}
35
- </DateElement>
36
- );
37
- };
38
-
39
- export default DateShort;
@@ -1,39 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- import { chooseLocale, supportedLocales } from "./useDateFormatter";
18
-
19
- describe("test choose locale", () => {
20
- it("should choose de", () => {
21
- const locale = chooseLocale("de_DE", ["de", "en"]);
22
- expect(locale).toBe(supportedLocales.de);
23
- });
24
-
25
- it("should choose de, even without language array", () => {
26
- const locale = chooseLocale("de", []);
27
- expect(locale).toBe(supportedLocales.de);
28
- });
29
-
30
- it("should choose es", () => {
31
- const locale = chooseLocale("de", ["af", "be", "es"]);
32
- expect(locale).toBe(supportedLocales.es);
33
- });
34
-
35
- it("should fallback en", () => {
36
- const locale = chooseLocale("af", ["af", "be"]);
37
- expect(locale).toBe(supportedLocales.en);
38
- });
39
- });
@@ -1,118 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - present Cloudogu GmbH
3
- *
4
- * This program is free software: you can redistribute it and/or modify it under
5
- * the terms of the GNU Affero General Public License as published by the Free
6
- * Software Foundation, version 3.
7
- *
8
- * This program is distributed in the hope that it will be useful, but WITHOUT
9
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10
- * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
11
- * details.
12
- *
13
- * You should have received a copy of the GNU Affero General Public License
14
- * along with this program. If not, see https://www.gnu.org/licenses/.
15
- */
16
-
17
- import { useTranslation } from "react-i18next";
18
- import { enUS, de, es } from "date-fns/locale";
19
- import { formatDistance, format, Locale, parseISO } from "date-fns";
20
-
21
- type LocaleMap = {
22
- [key: string]: Locale;
23
- };
24
-
25
- export const supportedLocales: LocaleMap = {
26
- enUS,
27
- en: enUS,
28
- de,
29
- es,
30
- };
31
-
32
- type Options = {
33
- addSuffix: boolean;
34
- locale: Locale;
35
- timeZone?: string;
36
- };
37
-
38
- export const chooseLocale = (language: string, languages?: readonly string[]) => {
39
- for (const lng of languages || []) {
40
- const locale = supportedLocales[lng];
41
- if (locale) {
42
- return locale;
43
- }
44
- }
45
-
46
- const locale = supportedLocales[language];
47
- if (locale) {
48
- return locale;
49
- }
50
-
51
- return enUS;
52
- };
53
-
54
- export type DateInput = Date | string;
55
-
56
- export type DateProps = {
57
- date?: DateInput;
58
- timeZone?: string;
59
-
60
- /**
61
- * baseDate is the date from which the distance is calculated,
62
- * default is the current time (new Date()). This property
63
- * is required to keep snapshots tests green over the time on
64
- * ci server.
65
- */
66
- baseDate?: DateInput;
67
- };
68
-
69
- const createOptions = (locale: Locale, timeZone?: string) => {
70
- const options: Options = {
71
- addSuffix: true,
72
- locale,
73
- };
74
- if (timeZone) {
75
- options.timeZone = timeZone;
76
- }
77
- return options;
78
- };
79
-
80
- const createBaseDate = (baseDate?: DateInput) => {
81
- if (baseDate) {
82
- return toDate(baseDate);
83
- }
84
- return new Date();
85
- };
86
-
87
- const toDate = (value: DateInput): Date => {
88
- if (value instanceof Date) {
89
- return value;
90
- }
91
- return parseISO(value);
92
- };
93
-
94
- const useDateFormatter = ({ date, baseDate, timeZone }: DateProps) => {
95
- const { i18n } = useTranslation();
96
- if (!date) {
97
- return null;
98
- }
99
-
100
- const isoDate = toDate(date);
101
- const base = createBaseDate(baseDate);
102
-
103
- const locale = chooseLocale(i18n.language, i18n.languages);
104
- const options = createOptions(locale, timeZone);
105
- return {
106
- formatShort() {
107
- return format(isoDate, "yyyy-MM-dd", options);
108
- },
109
- formatFull() {
110
- return format(isoDate, "yyyy-MM-dd HH:mm:ss", options);
111
- },
112
- formatDistance() {
113
- return formatDistance(isoDate, base, options);
114
- },
115
- };
116
- };
117
-
118
- export default useDateFormatter;