@dbcdk/react-components 0.0.24 → 0.0.26
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/dist/components/filter-field/FilterField.module.css +4 -1
- package/dist/components/forms/checkbox/Checkbox.js +1 -1
- package/dist/components/forms/checkbox/Checkbox.module.css +16 -3
- package/dist/components/forms/input/Input.module.css +1 -0
- package/dist/components/forms/select/Select.js +1 -1
- package/dist/components/menu/Menu.js +1 -1
- package/dist/components/overlay/modal/Modal.d.ts +2 -0
- package/dist/components/overlay/modal/Modal.js +1 -1
- package/dist/components/overlay/modal/Modal.module.css +1 -1
- package/dist/components/overlay/modal/provider/ModalProvider.d.ts +2 -0
- package/dist/components/overlay/modal/provider/ModalProvider.js +1 -2
- package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +0 -1
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +1 -0
- package/dist/components/table/Table.js +1 -1
- package/dist/components/table/Table.module.css +23 -6
- package/dist/components/tabs/Tabs.js +1 -1
- package/dist/utils/date/formatDate.d.ts +11 -3
- package/dist/utils/date/formatDate.js +35 -10
- package/package.json +1 -1
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
border-color var(--transition-fast) var(--ease-standard),
|
|
16
16
|
box-shadow var(--transition-fast) var(--ease-standard),
|
|
17
17
|
color var(--transition-fast) var(--ease-standard);
|
|
18
|
-
line-height: 20px;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
/* =========================
|
|
@@ -311,6 +310,10 @@
|
|
|
311
310
|
font-size: var(--font-size-xs);
|
|
312
311
|
}
|
|
313
312
|
|
|
313
|
+
.filterField input {
|
|
314
|
+
height: 100%;
|
|
315
|
+
}
|
|
316
|
+
|
|
314
317
|
.filterField input::placeholder {
|
|
315
318
|
color: var(--color-fg-subtle);
|
|
316
319
|
}
|
|
@@ -4,7 +4,7 @@ import { Check } from 'lucide-react';
|
|
|
4
4
|
import { useId, useState } from 'react';
|
|
5
5
|
import styles from './Checkbox.module.css';
|
|
6
6
|
import { InputContainer } from '../input-container/InputContainer';
|
|
7
|
-
export function Checkbox({ checked: controlled, onChange, variant = '
|
|
7
|
+
export function Checkbox({ checked: controlled, onChange, variant = 'default', disabled, label, size = 'md', modified, containerLabel, error, helpText, orientation = 'horizontal', labelWidth = '160px', fullWidth = false, required = false, noContainer = false, id, 'data-cy': dataCy, }) {
|
|
8
8
|
const [internal, setInternal] = useState(false);
|
|
9
9
|
const isChecked = controlled !== null && controlled !== void 0 ? controlled : internal;
|
|
10
10
|
const generatedId = useId();
|
|
@@ -50,10 +50,11 @@
|
|
|
50
50
|
pointer-events: none;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
.
|
|
54
|
-
background-color: var(--
|
|
53
|
+
.default {
|
|
54
|
+
background-color: var(--color-bg-toolbar);
|
|
55
|
+
border-color: var(--color-bg-toolbar);
|
|
55
56
|
&:not(:hover) {
|
|
56
|
-
border-color:
|
|
57
|
+
border-color: var(--color-bg-toolbar);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
.icon {
|
|
@@ -61,6 +62,18 @@
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
.outlined.checked {
|
|
66
|
+
background-color: transparent;
|
|
67
|
+
border-color: var(--color-border-default);
|
|
68
|
+
&:not(:hover) {
|
|
69
|
+
border-color: var(--color-brand);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.icon {
|
|
73
|
+
color: var(--color-brand);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
.success.checked {
|
|
65
78
|
background-color: var(--color-status-success);
|
|
66
79
|
&:not(:hover) {
|
|
@@ -112,7 +112,7 @@ export function Select({ label, error, helpText, orientation = 'vertical', label
|
|
|
112
112
|
returnFocus: true, trigger: (toggle, icon, isOpen) => (_jsx(Button, { disabled: disabled, ...(tooltipEnabled ? triggerProps : {}), id: controlId, "data-cy": dataCy !== null && dataCy !== void 0 ? dataCy : 'select-button', onKeyDown: handleKeyDown, fullWidth: fullWidth, variant: variant, onClick: e => {
|
|
113
113
|
resetActiveToSelected();
|
|
114
114
|
toggle(e);
|
|
115
|
-
}, size: size, type: "button", "data-forminput": true, "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsx("span", { children: selected ? selected.label : placeholder }), onClear && selected && _jsx(ClearButton, { onClick: onClear }), icon] }) })), children: _jsx(Menu, { onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
|
|
115
|
+
}, size: size, type: "button", "data-forminput": true, "aria-haspopup": "listbox", "aria-expanded": !!isOpen, "aria-controls": listboxId, "aria-invalid": Boolean(error) || undefined, "aria-describedby": describedBy, children: _jsxs("span", { className: "dbc-flex dbc-justify-between dbc-items-center dbc-gap-xxs", style: { width: '100%' }, children: [_jsx("span", { children: selected ? selected.label : _jsx("span", { className: "dbc-muted-text", children: placeholder }) }), onClear && selected && _jsx(ClearButton, { onClick: onClear }), icon] }) })), children: _jsx(Menu, { onKeyDown: handleKeyDown, role: "listbox", children: options.map((opt, index) => {
|
|
116
116
|
const isSelected = typeof opt.value === 'object' && typeof selectedValue === 'object' && datakey
|
|
117
117
|
? (selectedValue === null || selectedValue === void 0 ? void 0 : selectedValue[datakey]) === opt.value[datakey]
|
|
118
118
|
: opt.value === selectedValue;
|
|
@@ -57,7 +57,7 @@ const MenuItem = React.forwardRef(({ children, active, disabled, className, item
|
|
|
57
57
|
});
|
|
58
58
|
MenuItem.displayName = 'Menu.Item';
|
|
59
59
|
const MenuCheckItem = React.forwardRef(({ label, checked, disabled, onCheckedChange, className, ...liProps }, ref) => {
|
|
60
|
-
return (_jsx("li", { ref: ref, role: "none", className: [styles.row, className].filter(Boolean).join(' '), ...liProps, children: _jsx("div", { className: styles.interactiveChild, children: _jsx(Checkbox, { noContainer: true, checked: checked, disabled: disabled, label: label, onChange: (next, _e) => onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(next) }) }) }));
|
|
60
|
+
return (_jsx("li", { ref: ref, role: "none", className: [styles.row, className].filter(Boolean).join(' '), ...liProps, children: _jsx("div", { className: styles.interactiveChild, children: _jsx(Checkbox, { variant: "default", size: "md", noContainer: true, checked: checked, disabled: disabled, label: label, onChange: (next, _e) => onCheckedChange === null || onCheckedChange === void 0 ? void 0 : onCheckedChange(next) }) }) }));
|
|
61
61
|
});
|
|
62
62
|
MenuCheckItem.displayName = 'Menu.CheckItem';
|
|
63
63
|
const MenuRadioItem = React.forwardRef(({ name, value, checked, disabled, label, onValueChange, className, ...liProps }, ref) => {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React, { ReactNode } from 'react';
|
|
2
|
+
import { ButtonVariant } from '../../../components/button/Button';
|
|
2
3
|
import { Severity } from '../../../constants/severity.types';
|
|
3
4
|
export type ModalActionConfig = {
|
|
4
5
|
label: string;
|
|
6
|
+
severity?: ButtonVariant;
|
|
5
7
|
onClick?: () => void;
|
|
6
8
|
icon?: ReactNode;
|
|
7
9
|
disabled?: boolean;
|
|
@@ -88,5 +88,5 @@ export function Modal({ isOpen, onRequestClose, header, content, children, prima
|
|
|
88
88
|
const resolvedWidth = typeof width === 'number' ? `${width}px` : typeof width === 'string' ? width : undefined;
|
|
89
89
|
return (_jsx("div", { className: styles.overlay, onClick: handleOverlayClick, children: _jsxs("div", { "data-cy": dataCy, ref: dialogRef, className: `${styles.modal} ${disableContentSpacing ? '' : styles.contentSpacing}`, style: resolvedWidth
|
|
90
90
|
? { ['--modal-width']: resolvedWidth }
|
|
91
|
-
: undefined, onClick: stopPropagation, role: "dialog", "aria-modal": "true", "aria-labelledby": header ? titleId : undefined, tabIndex: -1, children: [_jsxs("div", { className: styles.header, children: [header && (_jsx(Headline, { severity: severity, size: 3, disableMargin: true, children: header })), _jsx(Button, { type: "button", variant: "inline", onClick: () => onRequestCloseRef.current(), "aria-label": "Luk", shape: "round", icon: _jsx(X, {}) })] }), _jsx("div", { className: styles.body, children: body }), shouldRenderFooter && (_jsxs("div", { className: styles.footer, children: [resolvedSecondaryAction && (_jsxs(Button, { type: "button",
|
|
91
|
+
: undefined, onClick: stopPropagation, role: "dialog", "aria-modal": "true", "aria-labelledby": header ? titleId : undefined, tabIndex: -1, children: [_jsxs("div", { className: styles.header, children: [header && (_jsx(Headline, { severity: severity, size: 3, disableMargin: true, children: header })), _jsx(Button, { type: "button", variant: "inline", onClick: () => onRequestCloseRef.current(), "aria-label": "Luk", shape: "round", icon: _jsx(X, {}) })] }), _jsx("div", { className: styles.body, children: body }), shouldRenderFooter && (_jsxs("div", { className: styles.footer, children: [resolvedSecondaryAction && (_jsxs(Button, { type: "button", onClick: resolvedSecondaryAction.onClick, disabled: isLoading, children: [resolvedSecondaryAction.icon && (_jsx("span", { className: styles.icon, children: resolvedSecondaryAction.icon })), _jsx("span", { children: resolvedSecondaryAction.label })] })), primaryAction && (_jsxs(Button, { type: "button", variant: primaryAction.severity || 'primary', onClick: primaryAction.onClick, disabled: primaryAction.disabled || isLoading, loading: isLoading, children: [primaryAction.icon && _jsx("span", { className: styles.icon, children: primaryAction.icon }), _jsx("span", { children: primaryAction.label })] }))] }))] }) }));
|
|
92
92
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
|
+
import { ButtonVariant } from '../../../../components/button/Button';
|
|
2
3
|
import { type ModalProps } from '../Modal';
|
|
3
4
|
type ModalConfig = Omit<ModalProps, 'isOpen' | 'onRequestClose'> & {
|
|
4
5
|
onRequestClose?: () => void;
|
|
5
6
|
};
|
|
6
7
|
type ConfirmModalConfig = Omit<ModalConfig, 'primaryAction' | 'secondaryAction' | 'onRequestClose'> & {
|
|
7
8
|
confirmLabel?: string;
|
|
9
|
+
confirmButtonSeverity?: ButtonVariant;
|
|
8
10
|
cancelLabel?: string;
|
|
9
11
|
};
|
|
10
12
|
type ModalContextValue = {
|
|
@@ -9,7 +9,6 @@ export function ModalProvider({ children }) {
|
|
|
9
9
|
const [config, setConfig] = useState(null);
|
|
10
10
|
const [mounted, setMounted] = useState(false);
|
|
11
11
|
useEffect(() => setMounted(true), []);
|
|
12
|
-
// Holds the resolver for the current "confirm" call, if any
|
|
13
12
|
const pendingResolverRef = useRef(null);
|
|
14
13
|
const resolvePending = useCallback((value) => {
|
|
15
14
|
if (pendingResolverRef.current) {
|
|
@@ -21,7 +20,6 @@ export function ModalProvider({ children }) {
|
|
|
21
20
|
setIsOpen(false);
|
|
22
21
|
}, []);
|
|
23
22
|
const openModal = useCallback((newConfig) => {
|
|
24
|
-
// if a confirm was in progress, resolve it as "false" (cancelled/overridden)
|
|
25
23
|
resolvePending(false);
|
|
26
24
|
setConfig(newConfig);
|
|
27
25
|
setIsOpen(true);
|
|
@@ -41,6 +39,7 @@ export function ModalProvider({ children }) {
|
|
|
41
39
|
...rest,
|
|
42
40
|
primaryAction: {
|
|
43
41
|
label: confirmLabel,
|
|
42
|
+
severity: confirmConfig.confirmButtonSeverity || 'primary',
|
|
44
43
|
onClick: () => {
|
|
45
44
|
resolvePending(true);
|
|
46
45
|
},
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
inline-size: var(--sidebar-width);
|
|
10
10
|
box-sizing: border-box;
|
|
11
11
|
border-inline-end: var(--border-width-thin) solid var(--color-border-default);
|
|
12
|
-
|
|
13
12
|
transition:
|
|
14
13
|
width var(--transition-fast) var(--ease-standard),
|
|
15
14
|
inline-size var(--transition-fast) var(--ease-standard);
|
|
@@ -143,7 +143,7 @@ export function Table({ data, columns, selectedRows, onRowSelect, selectionMode
|
|
|
143
143
|
]
|
|
144
144
|
.filter(Boolean)
|
|
145
145
|
.join(' '), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? (cellValue) : (_jsx("div", { className: styles.cellValueEllipsis, children: cellValue })) }) }, column.id));
|
|
146
|
-
})] }, `gridRow-${
|
|
146
|
+
})] }, `gridRow-${rowId}`));
|
|
147
147
|
}) }));
|
|
148
148
|
const bodyContent = loading && !data.length ? loadingBodyEl : dataBodyEl;
|
|
149
149
|
const tableClassName = [
|
|
@@ -165,7 +165,6 @@
|
|
|
165
165
|
vertical-align: top;
|
|
166
166
|
min-width: 0;
|
|
167
167
|
overflow: hidden;
|
|
168
|
-
text-overflow: ellipsis;
|
|
169
168
|
}
|
|
170
169
|
|
|
171
170
|
.sm .cell {
|
|
@@ -188,15 +187,16 @@
|
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
.selectionCell {
|
|
191
|
-
padding-block: inherit !important;
|
|
192
|
-
padding-inline: 0 !important;
|
|
193
190
|
overflow: visible !important;
|
|
194
191
|
display: flex;
|
|
195
|
-
align-items:
|
|
192
|
+
align-items: flex-start;
|
|
196
193
|
justify-content: flex-start;
|
|
197
194
|
min-width: 0;
|
|
198
195
|
}
|
|
199
196
|
|
|
197
|
+
.headerCell.selectionCell {
|
|
198
|
+
align-items: center;
|
|
199
|
+
}
|
|
200
200
|
.clickableRow {
|
|
201
201
|
cursor: pointer;
|
|
202
202
|
}
|
|
@@ -346,8 +346,8 @@
|
|
|
346
346
|
min-width: 0;
|
|
347
347
|
max-inline-size: 100%;
|
|
348
348
|
white-space: nowrap;
|
|
349
|
-
overflow: hidden;
|
|
350
|
-
text-overflow: ellipsis;
|
|
349
|
+
/* overflow: hidden; */
|
|
350
|
+
/* text-overflow: ellipsis; */
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
.allowWrap .cellContent {
|
|
@@ -467,3 +467,20 @@
|
|
|
467
467
|
width: 1px;
|
|
468
468
|
background: var(--table-divider);
|
|
469
469
|
}
|
|
470
|
+
|
|
471
|
+
.newRow {
|
|
472
|
+
animation: tableRowFadeIn 1000ms ease-out;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.newRow {
|
|
476
|
+
animation: tableRowFadeIn 600ms ease-out;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
@keyframes tableRowFadeIn {
|
|
480
|
+
from {
|
|
481
|
+
opacity: 0;
|
|
482
|
+
}
|
|
483
|
+
to {
|
|
484
|
+
opacity: 1;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
@@ -117,7 +117,7 @@ export function Tabs({ header, variant, panelStyle = false, tabs, value, default
|
|
|
117
117
|
const selected = index === activeIndex;
|
|
118
118
|
const tabDomId = `${uid}-tab-${String(tab.id)}`;
|
|
119
119
|
const panelDomId = `${uid}-panel-${String(tab.id)}`;
|
|
120
|
-
return (_jsx("div", { className: `${styles.tab} ${selected ? styles.active : ''}`, children: _jsxs("button", { id: tabDomId, type: "button", className: styles.tabButton, role: "tab", "aria-selected": selected, "aria-controls": panelDomId, tabIndex: selected ? 0 : -1, disabled: tab.disabled, onClick: () => setValue(tab.id), onKeyDown: e => onKeyDownTab(e, index), children: [tab.headerIcon ? _jsx("span", { className: styles.icon, children: tab.headerIcon }) : null, _jsx("span", { className: styles.label, children: tab.header }), tab.badge !== undefined && tab.badge > 0 ? (_jsx("span", { className: styles.badge, children: _jsx(Chip, {
|
|
120
|
+
return (_jsx("div", { className: `${styles.tab} ${selected ? styles.active : ''}`, children: _jsxs("button", { id: tabDomId, type: "button", className: styles.tabButton, role: "tab", "aria-selected": selected, "aria-controls": panelDomId, tabIndex: selected ? 0 : -1, disabled: tab.disabled, onClick: () => setValue(tab.id), onKeyDown: e => onKeyDownTab(e, index), children: [tab.headerIcon ? _jsx("span", { className: styles.icon, children: tab.headerIcon }) : null, _jsx("span", { className: styles.label, children: tab.header }), tab.badge !== undefined && tab.badge > 0 ? (_jsx("span", { className: styles.badge, children: _jsx(Chip, { type: "subtle", severity: null, size: "sm", children: tab.badge.toLocaleString('da-DK') }) })) : null] }) }, tab.id));
|
|
121
121
|
}) }), _jsx("div", { id: activeTab ? `${uid}-panel-${String(activeTab.id)}` : undefined, role: "tabpanel", "aria-labelledby": activeTab ? `${uid}-tab-${String(activeTab.id)}` : undefined, className: styles.tabContent, children: activeTab === null || activeTab === void 0 ? void 0 : activeTab.content })] })] }));
|
|
122
122
|
}
|
|
123
123
|
Tabs.Item = TabsItem;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Formats a Date as "dd
|
|
3
|
-
*
|
|
2
|
+
* Formats a Date as "dd/mm/yyyy" or "dd/mm/yyyy hh:mm:ss".
|
|
3
|
+
* Optionally returns user-friendly Danish labels like "I dag" or "I går".
|
|
4
|
+
*
|
|
5
|
+
* Examples:
|
|
6
|
+
* - formatDate(new Date(), { userFriendlyLabel: true }) => "I dag"
|
|
7
|
+
* - formatDate(new Date(), { userFriendlyLabel: true, showTime: true }) => "I dag, kl. 14:30"
|
|
8
|
+
* - formatDate(date, { showTime: true }) => "10/03/2026 14:30"
|
|
4
9
|
*
|
|
5
10
|
* @param date - The Date or date-parsable value to format
|
|
6
|
-
* @param options.
|
|
11
|
+
* @param options.showTime - If true, append time "hh:mm" or "hh:mm:ss"
|
|
12
|
+
* @param options.showSeconds - If true, append seconds when showTime is enabled
|
|
13
|
+
* @param options.userFriendlyLabel - If true, use "I dag" / "I går" when applicable
|
|
7
14
|
* @returns A formatted string
|
|
8
15
|
*/
|
|
9
16
|
export declare function formatDate(date: Date | string | number, options?: {
|
|
10
17
|
showTime?: boolean;
|
|
11
18
|
showSeconds?: boolean;
|
|
19
|
+
userFriendlyLabel?: boolean;
|
|
12
20
|
}): string;
|
|
@@ -1,26 +1,51 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Formats a Date as "dd
|
|
3
|
-
*
|
|
2
|
+
* Formats a Date as "dd/mm/yyyy" or "dd/mm/yyyy hh:mm:ss".
|
|
3
|
+
* Optionally returns user-friendly Danish labels like "I dag" or "I går".
|
|
4
|
+
*
|
|
5
|
+
* Examples:
|
|
6
|
+
* - formatDate(new Date(), { userFriendlyLabel: true }) => "I dag"
|
|
7
|
+
* - formatDate(new Date(), { userFriendlyLabel: true, showTime: true }) => "I dag, kl. 14:30"
|
|
8
|
+
* - formatDate(date, { showTime: true }) => "10/03/2026 14:30"
|
|
4
9
|
*
|
|
5
10
|
* @param date - The Date or date-parsable value to format
|
|
6
|
-
* @param options.
|
|
11
|
+
* @param options.showTime - If true, append time "hh:mm" or "hh:mm:ss"
|
|
12
|
+
* @param options.showSeconds - If true, append seconds when showTime is enabled
|
|
13
|
+
* @param options.userFriendlyLabel - If true, use "I dag" / "I går" when applicable
|
|
7
14
|
* @returns A formatted string
|
|
8
15
|
*/
|
|
9
16
|
export function formatDate(date, options = {}) {
|
|
10
17
|
const d = date instanceof Date ? date : new Date(date);
|
|
11
18
|
if (isNaN(d.getTime()))
|
|
12
19
|
return '';
|
|
20
|
+
const { showTime = false, showSeconds = false, userFriendlyLabel = false } = options;
|
|
13
21
|
const pad = (n) => n.toString().padStart(2, '0');
|
|
22
|
+
const formatTime = () => {
|
|
23
|
+
const hours = pad(d.getHours());
|
|
24
|
+
const minutes = pad(d.getMinutes());
|
|
25
|
+
if (!showSeconds)
|
|
26
|
+
return `${hours}:${minutes}`;
|
|
27
|
+
const seconds = pad(d.getSeconds());
|
|
28
|
+
return `${hours}:${minutes}:${seconds}`;
|
|
29
|
+
};
|
|
30
|
+
const isSameCalendarDay = (a, b) => a.getDate() === b.getDate() &&
|
|
31
|
+
a.getMonth() === b.getMonth() &&
|
|
32
|
+
a.getFullYear() === b.getFullYear();
|
|
33
|
+
if (userFriendlyLabel) {
|
|
34
|
+
const now = new Date();
|
|
35
|
+
const yesterday = new Date(now);
|
|
36
|
+
yesterday.setDate(now.getDate() - 1);
|
|
37
|
+
if (isSameCalendarDay(d, now)) {
|
|
38
|
+
return showTime ? `I dag, kl. ${formatTime()}` : 'I dag';
|
|
39
|
+
}
|
|
40
|
+
if (isSameCalendarDay(d, yesterday)) {
|
|
41
|
+
return showTime ? `I går, kl. ${formatTime()}` : 'I går';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
14
44
|
const day = pad(d.getDate());
|
|
15
45
|
const month = pad(d.getMonth() + 1);
|
|
16
46
|
const year = d.getFullYear();
|
|
17
47
|
const base = `${day}/${month}/${year}`;
|
|
18
|
-
if (!
|
|
48
|
+
if (!showTime)
|
|
19
49
|
return base;
|
|
20
|
-
|
|
21
|
-
const minutes = pad(d.getMinutes());
|
|
22
|
-
if (!options.showSeconds)
|
|
23
|
-
return `${base} ${hours}:${minutes}`;
|
|
24
|
-
const seconds = pad(d.getSeconds());
|
|
25
|
-
return `${base} ${hours}:${minutes}:${seconds}`;
|
|
50
|
+
return `${base} ${formatTime()}`;
|
|
26
51
|
}
|