@olenbetong/appframe-ds 1.3.5 → 1.3.7
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/CHANGELOG.md +17 -0
- package/package.json +5 -5
- package/scripts/copyAssets.mjs +27 -27
- package/src/AfLookup/Lookup.css +129 -129
- package/src/AfLookup/Lookup.tsx +186 -186
- package/src/AfLookup/LookupCombobox.css +78 -78
- package/src/AfLookup/LookupCombobox.tsx +237 -237
- package/src/AfLookup/LookupEdit.tsx +130 -130
- package/src/AfLookup/LookupGrid.tsx +124 -124
- package/src/AfLookup/index.ts +5 -5
- package/src/autocomplete/Autocomplete.css +256 -256
- package/src/autocomplete/Autocomplete.tsx +320 -320
- package/src/autocomplete/AutocompleteFrame.tsx +168 -168
- package/src/autocomplete/Combobox.tsx +286 -286
- package/src/autocomplete/index.ts +4 -4
- package/src/autocomplete/types.ts +204 -204
- package/src/autocomplete/utils.ts +183 -183
- package/src/binding/BoundNumericTextField.tsx +102 -102
- package/src/binding/BoundTextField.tsx +49 -49
- package/src/binding/CancelButton.tsx +30 -30
- package/src/binding/CancelIconButton.tsx +30 -30
- package/src/binding/DataEditToolbar.css +23 -23
- package/src/binding/DataEditToolbar.tsx +84 -84
- package/src/binding/DeleteButton.tsx +35 -35
- package/src/binding/DeleteIconButton.tsx +35 -35
- package/src/binding/RefreshButton.tsx +31 -31
- package/src/binding/RefreshIconButton.tsx +33 -33
- package/src/binding/RefreshRowIconButton.tsx +33 -33
- package/src/binding/SaveButton.tsx +37 -37
- package/src/binding/SaveIconButton.tsx +38 -38
- package/src/container/Container.tsx +49 -49
- package/src/container/index.ts +1 -1
- package/src/cutoff/CutOffPicker.css +12 -12
- package/src/cutoff/CutOffPicker.tsx +165 -165
- package/src/cutoff/context.tsx +194 -194
- package/src/cutoff/dsCutOffDates.ts +21 -21
- package/src/cutoff/index.ts +4 -4
- package/src/cutoff/utils.test.ts +59 -59
- package/src/cutoff/utils.ts +276 -276
- package/src/filter/ChipListInput.tsx +79 -79
- package/src/filter/FieldFilterPanel.css +150 -150
- package/src/filter/FieldFilterPanel.tsx +309 -309
- package/src/filter/FilterBuilder.css +152 -152
- package/src/filter/FilterBuilder.test.tsx +153 -153
- package/src/filter/FilterBuilder.tsx +435 -435
- package/src/filter/FilterEditor.css +231 -231
- package/src/filter/FilterEditor.test.tsx +285 -285
- package/src/filter/FilterEditor.tsx +75 -75
- package/src/filter/FilterGroupEditor.tsx +160 -160
- package/src/filter/FilterNameDialog.css +22 -22
- package/src/filter/FilterNameDialog.tsx +81 -81
- package/src/filter/FilterRow.tsx +117 -117
- package/src/filter/FilterShareDialog.css +28 -28
- package/src/filter/FilterShareDialog.tsx +201 -201
- package/src/filter/FilterStringField.tsx +78 -78
- package/src/filter/FilterValueEditor.tsx +239 -239
- package/src/filter/SavedFilterTree.css +107 -107
- package/src/filter/SavedFilterTree.test.tsx +94 -94
- package/src/filter/SavedFilterTree.tsx +218 -218
- package/src/filter/fieldFilter.test.ts +158 -158
- package/src/filter/fieldFilter.ts +139 -139
- package/src/filter/index.ts +27 -27
- package/src/filter/types.ts +38 -38
- package/src/filter/useDistinctValues.test.ts +102 -102
- package/src/filter/useDistinctValues.ts +230 -230
- package/src/global.d.ts +11 -11
- package/src/grid/AfGridColumnsPanel.tsx +118 -118
- package/src/grid/AfGridContext.tsx +51 -51
- package/src/grid/AfGridError.tsx +46 -46
- package/src/grid/AfHeaderFilterCell.tsx +147 -147
- package/src/grid/AfHeaderFilterPanel.tsx +111 -111
- package/src/grid/GridEditLookup.css +12 -12
- package/src/grid/GridEditLookup.tsx +121 -121
- package/src/grid/Toolbar.tsx +233 -233
- package/src/grid/editing.ts +100 -100
- package/src/grid/filter.ts +78 -78
- package/src/grid/formatters.ts +48 -48
- package/src/grid/index.css +245 -245
- package/src/grid/index.tsx +503 -503
- package/src/grid/license.ts +48 -48
- package/src/grid/localization.ts +369 -369
- package/src/grid/slots/index.tsx +334 -334
- package/src/grid/slots/slots.css +64 -64
- package/src/grid/slots/slots.test.tsx +39 -39
- package/src/grid/theme.tsx +138 -138
- package/src/grid/useAfColumns.tsx +371 -371
- package/src/grid/useAfCurrentIndex.ts +63 -63
- package/src/grid/useAfData.ts +20 -20
- package/src/grid/useAfFilter.ts +160 -160
- package/src/grid/useAfFilterFields.ts +55 -55
- package/src/grid/useAfGridApi.ts +71 -71
- package/src/grid/useAfKeyBindings.ts +36 -36
- package/src/grid/useAfNewItemRow.ts +258 -258
- package/src/grid/useAfPagination.ts +53 -53
- package/src/grid/useAfPersistedState.ts +230 -230
- package/src/grid/useAfRowEditModel.ts +145 -145
- package/src/grid/useAfRowGrouping.ts +47 -47
- package/src/grid/useAfServerAggregation.test.ts +68 -68
- package/src/grid/useAfServerAggregation.ts +158 -158
- package/src/grid/useAfSortModel.ts +84 -84
- package/src/i18n.ts +13 -13
- package/src/index.ts +14 -14
- package/src/input/InputAdornments.css +84 -84
- package/src/input/InputAdornments.tsx +102 -102
- package/src/input/index.ts +1 -1
- package/src/layout/AppMenu.tsx +74 -74
- package/src/layout/AppMenuDrawer.css +70 -70
- package/src/layout/AppMenuDrawer.tsx +122 -122
- package/src/layout/ErrorBoundary.tsx +162 -162
- package/src/layout/PageContainer.css +48 -48
- package/src/layout/PageContainer.tsx +41 -41
- package/src/layout/ResponsiveDialog.css +86 -86
- package/src/layout/ResponsiveDialog.tsx +55 -55
- package/src/layout/index.tsx +69 -69
- package/src/link/Link.tsx +23 -23
- package/src/link/index.ts +1 -1
- package/src/mdi/Mdi.css +138 -138
- package/src/mdi/Mdi.test.tsx +91 -91
- package/src/mdi/Mdi.tsx +141 -141
- package/src/mdi/MdiConfirmCloseDialog.tsx +47 -47
- package/src/mdi/MdiContext.tsx +59 -59
- package/src/mdi/MdiDocumentContext.tsx +60 -60
- package/src/mdi/MdiPanel.tsx +61 -61
- package/src/mdi/MdiRestore.test.tsx +86 -86
- package/src/mdi/MdiTab.tsx +30 -30
- package/src/mdi/controller.test.ts +382 -382
- package/src/mdi/controller.ts +656 -656
- package/src/mdi/dockviewHost.ts +132 -132
- package/src/mdi/fakeHost.ts +200 -200
- package/src/mdi/host.ts +44 -44
- package/src/mdi/ids.test.ts +20 -20
- package/src/mdi/ids.ts +18 -18
- package/src/mdi/index.ts +31 -31
- package/src/mdi/layoutRestore.test.ts +156 -156
- package/src/mdi/layoutRestore.ts +311 -311
- package/src/mdi/layoutSpec.test.ts +143 -143
- package/src/mdi/layoutSpec.ts +214 -214
- package/src/mdi/layoutStore.test.ts +93 -93
- package/src/mdi/layoutStore.ts +99 -99
- package/src/mdi/memorySettingsStore.ts +21 -21
- package/src/mdi/registry.ts +34 -34
- package/src/mdi/testTypes.ts +37 -37
- package/src/mdi/theme.ts +22 -22
- package/src/mdi/types.ts +214 -214
- package/src/page/Page.css +53 -53
- package/src/page/PageBlock.css +64 -64
- package/src/page/PageBlock.tsx +92 -92
- package/src/page/PageHeader.css +88 -88
- package/src/page/PageHeader.tsx +115 -115
- package/src/page/PageTitle.css +5 -5
- package/src/page/PageTitle.tsx +21 -21
- package/src/page/index.ts +4 -4
- package/src/paper/Paper.tsx +52 -52
- package/src/progress/LinearProgress.css +93 -93
- package/src/progress/LinearProgress.tsx +104 -104
- package/src/progress/index.ts +1 -1
- package/src/report-downloader/ReportDownloader.css +67 -67
- package/src/report-downloader/components/StatusItem.tsx +87 -87
- package/src/report-downloader/components/StatusList.tsx +28 -28
- package/src/report-downloader/index.ts +41 -41
- package/src/report-downloader/status.tsx +92 -92
- package/src/sortable/DropIndicator.css +51 -51
- package/src/sortable/DropIndicator.tsx +27 -27
- package/src/sortable/SortableItemList.css +21 -21
- package/src/sortable/SortableItemList.tsx +264 -264
- package/src/sortable/index.ts +8 -8
- package/src/sortable/reorderSortOrder.ts +126 -126
- package/src/sortable/sortOrder.ts +101 -101
- package/src/sortable/types.ts +9 -9
- package/src/sortable/useSortableContainer.ts +53 -53
- package/src/sortable/useSortableItem.ts +95 -95
- package/src/sortable/useSortableList.ts +117 -117
- package/src/test/happy-dom-document-class.ts +24 -24
- package/src/test/setup.ts +12 -12
- package/src/theme/useDsColorScheme.ts +53 -53
- package/tsconfig.build.json +9 -9
- package/tsconfig.json +8 -8
- package/vitest.config.ts +10 -10
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import "./PageContainer.css";
|
|
2
|
-
|
|
3
|
-
import clsx from "clsx";
|
|
4
|
-
import type React from "react";
|
|
5
|
-
|
|
6
|
-
export type PageContainerMaxWidth = "xs" | "sm" | "md" | "lg" | "xl" | false;
|
|
7
|
-
|
|
8
|
-
export type PageContainerProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
9
|
-
fullHeight?: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Predefined max-width of the content, on the MUI `Container` scale (`xs`/`sm` 36rem,
|
|
12
|
-
* `md` 48rem, `lg` 64rem, `xl` 80rem, plus the gutters). The content stays against the
|
|
13
|
-
* leading edge, as the MUI-era `PageContainer` did; `Page.Block`/`Container` centre it.
|
|
14
|
-
* @default max-width: 100%
|
|
15
|
-
*/
|
|
16
|
-
maxWidth?: PageContainerMaxWidth;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const maxWidthClassName: Record<Exclude<PageContainerMaxWidth, false>, string> = {
|
|
20
|
-
xs: "ObPageContainer-text",
|
|
21
|
-
sm: "ObPageContainer-text",
|
|
22
|
-
md: "ObPageContainer-md",
|
|
23
|
-
lg: "ObPageContainer-lg",
|
|
24
|
-
xl: "ObPageContainer-xl",
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @deprecated Use `Page.Block` instead. `maxWidth` mapping: `xs`/`sm` →
|
|
29
|
-
* `width="text"`, `md` → `"md"`, `lg` → `"lg"`, `xl` → `"xl"`, `false` → omit
|
|
30
|
-
* `width`. Replace `fullHeight` with `<Page layout="app">` and
|
|
31
|
-
* `<Page.Block grow overflow="auto">`.
|
|
32
|
-
*/
|
|
33
|
-
export function PageContainer({ children, className, fullHeight, maxWidth, ...props }: PageContainerProps) {
|
|
34
|
-
return (
|
|
35
|
-
<div className={clsx("ObPageContainer-root", fullHeight && "ObPageContainer-fullHeight")}>
|
|
36
|
-
<div className={clsx("ObPageContainer-inner", maxWidth && maxWidthClassName[maxWidth], className)} {...props}>
|
|
37
|
-
{children}
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
}
|
|
1
|
+
import "./PageContainer.css";
|
|
2
|
+
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import type React from "react";
|
|
5
|
+
|
|
6
|
+
export type PageContainerMaxWidth = "xs" | "sm" | "md" | "lg" | "xl" | false;
|
|
7
|
+
|
|
8
|
+
export type PageContainerProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
9
|
+
fullHeight?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Predefined max-width of the content, on the MUI `Container` scale (`xs`/`sm` 36rem,
|
|
12
|
+
* `md` 48rem, `lg` 64rem, `xl` 80rem, plus the gutters). The content stays against the
|
|
13
|
+
* leading edge, as the MUI-era `PageContainer` did; `Page.Block`/`Container` centre it.
|
|
14
|
+
* @default max-width: 100%
|
|
15
|
+
*/
|
|
16
|
+
maxWidth?: PageContainerMaxWidth;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const maxWidthClassName: Record<Exclude<PageContainerMaxWidth, false>, string> = {
|
|
20
|
+
xs: "ObPageContainer-text",
|
|
21
|
+
sm: "ObPageContainer-text",
|
|
22
|
+
md: "ObPageContainer-md",
|
|
23
|
+
lg: "ObPageContainer-lg",
|
|
24
|
+
xl: "ObPageContainer-xl",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Use `Page.Block` instead. `maxWidth` mapping: `xs`/`sm` →
|
|
29
|
+
* `width="text"`, `md` → `"md"`, `lg` → `"lg"`, `xl` → `"xl"`, `false` → omit
|
|
30
|
+
* `width`. Replace `fullHeight` with `<Page layout="app">` and
|
|
31
|
+
* `<Page.Block grow overflow="auto">`.
|
|
32
|
+
*/
|
|
33
|
+
export function PageContainer({ children, className, fullHeight, maxWidth, ...props }: PageContainerProps) {
|
|
34
|
+
return (
|
|
35
|
+
<div className={clsx("ObPageContainer-root", fullHeight && "ObPageContainer-fullHeight")}>
|
|
36
|
+
<div className={clsx("ObPageContainer-inner", maxWidth && maxWidthClassName[maxWidth], className)} {...props}>
|
|
37
|
+
{children}
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Width-limited on large screens, full-screen below the next MUI breakpoint up:
|
|
3
|
-
* xs (444px) fills below 600px, sm (600px) below 900px, md (900px) below 1200px,
|
|
4
|
-
* lg (1200px) below 1536px, xl (1536px) below 1920px, none always.
|
|
5
|
-
*/
|
|
6
|
-
@layer ds {
|
|
7
|
-
.ObResponsiveDialog-root {
|
|
8
|
-
width: 100%;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.ObResponsiveDialog-root[data-max-width="xs"] {
|
|
12
|
-
max-width: 444px;
|
|
13
|
-
}
|
|
14
|
-
.ObResponsiveDialog-root[data-max-width="sm"] {
|
|
15
|
-
max-width: 600px;
|
|
16
|
-
}
|
|
17
|
-
.ObResponsiveDialog-root[data-max-width="md"] {
|
|
18
|
-
max-width: 900px;
|
|
19
|
-
}
|
|
20
|
-
.ObResponsiveDialog-root[data-max-width="lg"] {
|
|
21
|
-
max-width: 1200px;
|
|
22
|
-
}
|
|
23
|
-
.ObResponsiveDialog-root[data-max-width="xl"] {
|
|
24
|
-
max-width: 1536px;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.ObResponsiveDialog-root[data-max-width="none"] {
|
|
28
|
-
max-width: none;
|
|
29
|
-
width: 100vw;
|
|
30
|
-
height: 100dvh;
|
|
31
|
-
max-height: none;
|
|
32
|
-
margin: 0;
|
|
33
|
-
border-radius: 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@media (max-width: 599.98px) {
|
|
37
|
-
.ObResponsiveDialog-root[data-max-width="xs"] {
|
|
38
|
-
max-width: none;
|
|
39
|
-
width: 100vw;
|
|
40
|
-
height: 100dvh;
|
|
41
|
-
max-height: none;
|
|
42
|
-
margin: 0;
|
|
43
|
-
border-radius: 0;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
@media (max-width: 899.98px) {
|
|
47
|
-
.ObResponsiveDialog-root[data-max-width="sm"] {
|
|
48
|
-
max-width: none;
|
|
49
|
-
width: 100vw;
|
|
50
|
-
height: 100dvh;
|
|
51
|
-
max-height: none;
|
|
52
|
-
margin: 0;
|
|
53
|
-
border-radius: 0;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
@media (max-width: 1199.98px) {
|
|
57
|
-
.ObResponsiveDialog-root[data-max-width="md"] {
|
|
58
|
-
max-width: none;
|
|
59
|
-
width: 100vw;
|
|
60
|
-
height: 100dvh;
|
|
61
|
-
max-height: none;
|
|
62
|
-
margin: 0;
|
|
63
|
-
border-radius: 0;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
@media (max-width: 1535.98px) {
|
|
67
|
-
.ObResponsiveDialog-root[data-max-width="lg"] {
|
|
68
|
-
max-width: none;
|
|
69
|
-
width: 100vw;
|
|
70
|
-
height: 100dvh;
|
|
71
|
-
max-height: none;
|
|
72
|
-
margin: 0;
|
|
73
|
-
border-radius: 0;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
@media (max-width: 1919.98px) {
|
|
77
|
-
.ObResponsiveDialog-root[data-max-width="xl"] {
|
|
78
|
-
max-width: none;
|
|
79
|
-
width: 100vw;
|
|
80
|
-
height: 100dvh;
|
|
81
|
-
max-height: none;
|
|
82
|
-
margin: 0;
|
|
83
|
-
border-radius: 0;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Width-limited on large screens, full-screen below the next MUI breakpoint up:
|
|
3
|
+
* xs (444px) fills below 600px, sm (600px) below 900px, md (900px) below 1200px,
|
|
4
|
+
* lg (1200px) below 1536px, xl (1536px) below 1920px, none always.
|
|
5
|
+
*/
|
|
6
|
+
@layer ds {
|
|
7
|
+
.ObResponsiveDialog-root {
|
|
8
|
+
width: 100%;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.ObResponsiveDialog-root[data-max-width="xs"] {
|
|
12
|
+
max-width: 444px;
|
|
13
|
+
}
|
|
14
|
+
.ObResponsiveDialog-root[data-max-width="sm"] {
|
|
15
|
+
max-width: 600px;
|
|
16
|
+
}
|
|
17
|
+
.ObResponsiveDialog-root[data-max-width="md"] {
|
|
18
|
+
max-width: 900px;
|
|
19
|
+
}
|
|
20
|
+
.ObResponsiveDialog-root[data-max-width="lg"] {
|
|
21
|
+
max-width: 1200px;
|
|
22
|
+
}
|
|
23
|
+
.ObResponsiveDialog-root[data-max-width="xl"] {
|
|
24
|
+
max-width: 1536px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.ObResponsiveDialog-root[data-max-width="none"] {
|
|
28
|
+
max-width: none;
|
|
29
|
+
width: 100vw;
|
|
30
|
+
height: 100dvh;
|
|
31
|
+
max-height: none;
|
|
32
|
+
margin: 0;
|
|
33
|
+
border-radius: 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (max-width: 599.98px) {
|
|
37
|
+
.ObResponsiveDialog-root[data-max-width="xs"] {
|
|
38
|
+
max-width: none;
|
|
39
|
+
width: 100vw;
|
|
40
|
+
height: 100dvh;
|
|
41
|
+
max-height: none;
|
|
42
|
+
margin: 0;
|
|
43
|
+
border-radius: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
@media (max-width: 899.98px) {
|
|
47
|
+
.ObResponsiveDialog-root[data-max-width="sm"] {
|
|
48
|
+
max-width: none;
|
|
49
|
+
width: 100vw;
|
|
50
|
+
height: 100dvh;
|
|
51
|
+
max-height: none;
|
|
52
|
+
margin: 0;
|
|
53
|
+
border-radius: 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
@media (max-width: 1199.98px) {
|
|
57
|
+
.ObResponsiveDialog-root[data-max-width="md"] {
|
|
58
|
+
max-width: none;
|
|
59
|
+
width: 100vw;
|
|
60
|
+
height: 100dvh;
|
|
61
|
+
max-height: none;
|
|
62
|
+
margin: 0;
|
|
63
|
+
border-radius: 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
@media (max-width: 1535.98px) {
|
|
67
|
+
.ObResponsiveDialog-root[data-max-width="lg"] {
|
|
68
|
+
max-width: none;
|
|
69
|
+
width: 100vw;
|
|
70
|
+
height: 100dvh;
|
|
71
|
+
max-height: none;
|
|
72
|
+
margin: 0;
|
|
73
|
+
border-radius: 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
@media (max-width: 1919.98px) {
|
|
77
|
+
.ObResponsiveDialog-root[data-max-width="xl"] {
|
|
78
|
+
max-width: none;
|
|
79
|
+
width: 100vw;
|
|
80
|
+
height: 100dvh;
|
|
81
|
+
max-height: none;
|
|
82
|
+
margin: 0;
|
|
83
|
+
border-radius: 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import "./ResponsiveDialog.css";
|
|
2
|
-
|
|
3
|
-
import { Dialog, type DialogProps, Heading } from "@digdir/designsystemet-react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
|
|
6
|
-
export type ResponsiveDialogMaxWidth = "xs" | "sm" | "md" | "lg" | "xl" | false;
|
|
7
|
-
|
|
8
|
-
export type ResponsiveDialogProps = Omit<DialogProps, "title" | "open" | "onClose"> & {
|
|
9
|
-
open: boolean;
|
|
10
|
-
onClose?: () => void;
|
|
11
|
-
title?: React.ReactNode;
|
|
12
|
-
/**
|
|
13
|
-
* Width of the dialog on screens wide enough for it, in MUI's breakpoint names (`sm` is
|
|
14
|
-
* 600px, `md` 900px, `lg` 1200px, `xl` 1536px). Below the next breakpoint up the dialog
|
|
15
|
-
* fills the screen. `false` fills the screen always.
|
|
16
|
-
*/
|
|
17
|
-
maxWidth?: ResponsiveDialogMaxWidth;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* A Designsystemet `Dialog` that is a centred, width-limited dialog on large screens and
|
|
22
|
-
* full-screen on small ones - the MUI `Dialog fullScreen` behaviour, decided by CSS media
|
|
23
|
-
* queries rather than a hook. The title goes in the first `Dialog.Block` with the dialog's own
|
|
24
|
-
* close button; put the content and actions in further `Dialog.Block`s.
|
|
25
|
-
*
|
|
26
|
-
* Equivalent of `ResponsiveDialog` in `@olenbetong/appframe-mui`. `onClose` takes no
|
|
27
|
-
* arguments: the dialog closes on the close button, the backdrop and Escape alike.
|
|
28
|
-
*/
|
|
29
|
-
export function ResponsiveDialog({
|
|
30
|
-
children,
|
|
31
|
-
className,
|
|
32
|
-
maxWidth = "sm",
|
|
33
|
-
onClose,
|
|
34
|
-
open,
|
|
35
|
-
title,
|
|
36
|
-
...props
|
|
37
|
-
}: ResponsiveDialogProps) {
|
|
38
|
-
return (
|
|
39
|
-
<Dialog
|
|
40
|
-
closedby="any"
|
|
41
|
-
{...props}
|
|
42
|
-
open={open}
|
|
43
|
-
onClose={onClose}
|
|
44
|
-
className={clsx("ObResponsiveDialog-root", className)}
|
|
45
|
-
data-max-width={maxWidth === false ? "none" : maxWidth}
|
|
46
|
-
>
|
|
47
|
-
{title && (
|
|
48
|
-
<Dialog.Block>
|
|
49
|
-
<Heading data-size="xs">{title}</Heading>
|
|
50
|
-
</Dialog.Block>
|
|
51
|
-
)}
|
|
52
|
-
{children}
|
|
53
|
-
</Dialog>
|
|
54
|
-
);
|
|
55
|
-
}
|
|
1
|
+
import "./ResponsiveDialog.css";
|
|
2
|
+
|
|
3
|
+
import { Dialog, type DialogProps, Heading } from "@digdir/designsystemet-react";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
|
|
6
|
+
export type ResponsiveDialogMaxWidth = "xs" | "sm" | "md" | "lg" | "xl" | false;
|
|
7
|
+
|
|
8
|
+
export type ResponsiveDialogProps = Omit<DialogProps, "title" | "open" | "onClose"> & {
|
|
9
|
+
open: boolean;
|
|
10
|
+
onClose?: () => void;
|
|
11
|
+
title?: React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* Width of the dialog on screens wide enough for it, in MUI's breakpoint names (`sm` is
|
|
14
|
+
* 600px, `md` 900px, `lg` 1200px, `xl` 1536px). Below the next breakpoint up the dialog
|
|
15
|
+
* fills the screen. `false` fills the screen always.
|
|
16
|
+
*/
|
|
17
|
+
maxWidth?: ResponsiveDialogMaxWidth;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A Designsystemet `Dialog` that is a centred, width-limited dialog on large screens and
|
|
22
|
+
* full-screen on small ones - the MUI `Dialog fullScreen` behaviour, decided by CSS media
|
|
23
|
+
* queries rather than a hook. The title goes in the first `Dialog.Block` with the dialog's own
|
|
24
|
+
* close button; put the content and actions in further `Dialog.Block`s.
|
|
25
|
+
*
|
|
26
|
+
* Equivalent of `ResponsiveDialog` in `@olenbetong/appframe-mui`. `onClose` takes no
|
|
27
|
+
* arguments: the dialog closes on the close button, the backdrop and Escape alike.
|
|
28
|
+
*/
|
|
29
|
+
export function ResponsiveDialog({
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
maxWidth = "sm",
|
|
33
|
+
onClose,
|
|
34
|
+
open,
|
|
35
|
+
title,
|
|
36
|
+
...props
|
|
37
|
+
}: ResponsiveDialogProps) {
|
|
38
|
+
return (
|
|
39
|
+
<Dialog
|
|
40
|
+
closedby="any"
|
|
41
|
+
{...props}
|
|
42
|
+
open={open}
|
|
43
|
+
onClose={onClose}
|
|
44
|
+
className={clsx("ObResponsiveDialog-root", className)}
|
|
45
|
+
data-max-width={maxWidth === false ? "none" : maxWidth}
|
|
46
|
+
>
|
|
47
|
+
{title && (
|
|
48
|
+
<Dialog.Block>
|
|
49
|
+
<Heading data-size="xs">{title}</Heading>
|
|
50
|
+
</Dialog.Block>
|
|
51
|
+
)}
|
|
52
|
+
{children}
|
|
53
|
+
</Dialog>
|
|
54
|
+
);
|
|
55
|
+
}
|
package/src/layout/index.tsx
CHANGED
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
import "./index.css";
|
|
2
|
-
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
-
import type React from "react";
|
|
5
|
-
|
|
6
|
-
import { AppLayoutDesktop } from "./AppLayoutDesktop.js";
|
|
7
|
-
import { AppLayoutMobile } from "./AppLayoutMobile.js";
|
|
8
|
-
import type { AppMenuProps } from "./AppMenu.js";
|
|
9
|
-
|
|
10
|
-
export type AppLayoutProps = {
|
|
11
|
-
AppMenuProps?: AppMenuProps;
|
|
12
|
-
children: React.ReactNode | React.ReactNode[];
|
|
13
|
-
menu?: React.ReactNode | React.ReactNode[];
|
|
14
|
-
/**
|
|
15
|
-
* @deprecated The toolbar is now server-rendered. This prop has no effect.
|
|
16
|
-
*/
|
|
17
|
-
toolbar?: React.ReactNode | React.ReactNode[];
|
|
18
|
-
/**
|
|
19
|
-
* @deprecated The title is now rendered in the server-rendered toolbar. This prop has no effect.
|
|
20
|
-
*/
|
|
21
|
-
title?: React.ReactNode;
|
|
22
|
-
/**
|
|
23
|
-
* @deprecated The toolbar is now server-rendered. This prop has no effect.
|
|
24
|
-
*/
|
|
25
|
-
enableMenuToggle?: boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Enable partner mode (for partner.olenbetong.no applications).
|
|
28
|
-
* Adds a toggle button to the existing partner header instead of the app bar.
|
|
29
|
-
*/
|
|
30
|
-
partner?: boolean;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
function useIsMobile() {
|
|
34
|
-
let [isMobile, setIsMobile] = useState(() => {
|
|
35
|
-
if (typeof window === "undefined") return false;
|
|
36
|
-
return window.matchMedia("(max-width: 1199px)").matches;
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
let mq = window.matchMedia("(max-width: 1199px)");
|
|
41
|
-
let handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);
|
|
42
|
-
mq.addEventListener("change", handler);
|
|
43
|
-
return () => mq.removeEventListener("change", handler);
|
|
44
|
-
}, []);
|
|
45
|
-
|
|
46
|
-
return isMobile;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export * from "./AppMenu.js";
|
|
50
|
-
export * from "./AppMenuDrawer.js";
|
|
51
|
-
export * from "./AppMenuItem.js";
|
|
52
|
-
export * from "./AppMenuSubheader.js";
|
|
53
|
-
export * from "./constants.js";
|
|
54
|
-
export * from "./ErrorBoundary.js";
|
|
55
|
-
export * from "./PageContainer.js";
|
|
56
|
-
export * from "./ResponsiveDialog.js";
|
|
57
|
-
export * from "./PartnerToggle.js";
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @deprecated Use the `Page` primitives instead (`Page`, `Page.Header`,
|
|
61
|
-
* `Page.Block`). `<AppLayout menu={...} title={...}>` becomes
|
|
62
|
-
* `<Page layout="app"><Page.Header title={...} menu={...} />...</Page>`.
|
|
63
|
-
*/
|
|
64
|
-
export function AppLayout(props: AppLayoutProps) {
|
|
65
|
-
let isSmall = useIsMobile();
|
|
66
|
-
let Component = isSmall ? AppLayoutMobile : AppLayoutDesktop;
|
|
67
|
-
|
|
68
|
-
return <Component {...props} />;
|
|
69
|
-
}
|
|
1
|
+
import "./index.css";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import type React from "react";
|
|
5
|
+
|
|
6
|
+
import { AppLayoutDesktop } from "./AppLayoutDesktop.js";
|
|
7
|
+
import { AppLayoutMobile } from "./AppLayoutMobile.js";
|
|
8
|
+
import type { AppMenuProps } from "./AppMenu.js";
|
|
9
|
+
|
|
10
|
+
export type AppLayoutProps = {
|
|
11
|
+
AppMenuProps?: AppMenuProps;
|
|
12
|
+
children: React.ReactNode | React.ReactNode[];
|
|
13
|
+
menu?: React.ReactNode | React.ReactNode[];
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated The toolbar is now server-rendered. This prop has no effect.
|
|
16
|
+
*/
|
|
17
|
+
toolbar?: React.ReactNode | React.ReactNode[];
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated The title is now rendered in the server-rendered toolbar. This prop has no effect.
|
|
20
|
+
*/
|
|
21
|
+
title?: React.ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated The toolbar is now server-rendered. This prop has no effect.
|
|
24
|
+
*/
|
|
25
|
+
enableMenuToggle?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Enable partner mode (for partner.olenbetong.no applications).
|
|
28
|
+
* Adds a toggle button to the existing partner header instead of the app bar.
|
|
29
|
+
*/
|
|
30
|
+
partner?: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
function useIsMobile() {
|
|
34
|
+
let [isMobile, setIsMobile] = useState(() => {
|
|
35
|
+
if (typeof window === "undefined") return false;
|
|
36
|
+
return window.matchMedia("(max-width: 1199px)").matches;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
let mq = window.matchMedia("(max-width: 1199px)");
|
|
41
|
+
let handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);
|
|
42
|
+
mq.addEventListener("change", handler);
|
|
43
|
+
return () => mq.removeEventListener("change", handler);
|
|
44
|
+
}, []);
|
|
45
|
+
|
|
46
|
+
return isMobile;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export * from "./AppMenu.js";
|
|
50
|
+
export * from "./AppMenuDrawer.js";
|
|
51
|
+
export * from "./AppMenuItem.js";
|
|
52
|
+
export * from "./AppMenuSubheader.js";
|
|
53
|
+
export * from "./constants.js";
|
|
54
|
+
export * from "./ErrorBoundary.js";
|
|
55
|
+
export * from "./PageContainer.js";
|
|
56
|
+
export * from "./ResponsiveDialog.js";
|
|
57
|
+
export * from "./PartnerToggle.js";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @deprecated Use the `Page` primitives instead (`Page`, `Page.Header`,
|
|
61
|
+
* `Page.Block`). `<AppLayout menu={...} title={...}>` becomes
|
|
62
|
+
* `<Page layout="app"><Page.Header title={...} menu={...} />...</Page>`.
|
|
63
|
+
*/
|
|
64
|
+
export function AppLayout(props: AppLayoutProps) {
|
|
65
|
+
let isSmall = useIsMobile();
|
|
66
|
+
let Component = isSmall ? AppLayoutMobile : AppLayoutDesktop;
|
|
67
|
+
|
|
68
|
+
return <Component {...props} />;
|
|
69
|
+
}
|
package/src/link/Link.tsx
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { Link as DsLink, type LinkProps as DsLinkProps } from "@digdir/designsystemet-react";
|
|
2
|
-
import { forwardRef } from "react";
|
|
3
|
-
import { Link as RouterLink, type LinkProps as RouterLinkProps } from "react-router";
|
|
4
|
-
|
|
5
|
-
export type LinkProps = Omit<DsLinkProps, "href" | "asChild"> &
|
|
6
|
-
Omit<RouterLinkProps, "to" | "children"> & {
|
|
7
|
-
/** The in-app path, resolved by react-router. */
|
|
8
|
-
href: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A Designsystemet `Link` that navigates with react-router: `href` is the route, the
|
|
13
|
-
* navigation is a view transition. Equivalent of `Link` in `@olenbetong/appframe-mui`.
|
|
14
|
-
*/
|
|
15
|
-
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link({ href, children, ...props }, ref) {
|
|
16
|
-
return (
|
|
17
|
-
<DsLink asChild>
|
|
18
|
-
<RouterLink viewTransition to={href} {...props} ref={ref}>
|
|
19
|
-
{children}
|
|
20
|
-
</RouterLink>
|
|
21
|
-
</DsLink>
|
|
22
|
-
);
|
|
23
|
-
});
|
|
1
|
+
import { Link as DsLink, type LinkProps as DsLinkProps } from "@digdir/designsystemet-react";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import { Link as RouterLink, type LinkProps as RouterLinkProps } from "react-router";
|
|
4
|
+
|
|
5
|
+
export type LinkProps = Omit<DsLinkProps, "href" | "asChild"> &
|
|
6
|
+
Omit<RouterLinkProps, "to" | "children"> & {
|
|
7
|
+
/** The in-app path, resolved by react-router. */
|
|
8
|
+
href: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A Designsystemet `Link` that navigates with react-router: `href` is the route, the
|
|
13
|
+
* navigation is a view transition. Equivalent of `Link` in `@olenbetong/appframe-mui`.
|
|
14
|
+
*/
|
|
15
|
+
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link({ href, children, ...props }, ref) {
|
|
16
|
+
return (
|
|
17
|
+
<DsLink asChild>
|
|
18
|
+
<RouterLink viewTransition to={href} {...props} ref={ref}>
|
|
19
|
+
{children}
|
|
20
|
+
</RouterLink>
|
|
21
|
+
</DsLink>
|
|
22
|
+
);
|
|
23
|
+
});
|
package/src/link/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./Link.js";
|
|
1
|
+
export * from "./Link.js";
|