@sentropic/design-system-svelte 0.34.49 → 0.34.51
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/README.md +62 -0
- package/dist/AnomalySwimLaneChart.svelte +10 -1
- package/dist/AnomalySwimLaneChart.svelte.d.ts +2 -0
- package/dist/AnomalySwimLaneChart.svelte.d.ts.map +1 -1
- package/dist/AppShell.svelte +284 -28
- package/dist/AppShell.svelte.d.ts +23 -3
- package/dist/AppShell.svelte.d.ts.map +1 -1
- package/dist/CalendarHeatmapChart.svelte +11 -1
- package/dist/CalendarHeatmapChart.svelte.d.ts +2 -0
- package/dist/CalendarHeatmapChart.svelte.d.ts.map +1 -1
- package/dist/Combobox.svelte +5 -1
- package/dist/Combobox.svelte.d.ts.map +1 -1
- package/dist/ContextPanel.svelte +86 -0
- package/dist/ContextPanel.svelte.d.ts +14 -0
- package/dist/ContextPanel.svelte.d.ts.map +1 -0
- package/dist/ContourChart.svelte +76 -13
- package/dist/ContourChart.svelte.d.ts +3 -1
- package/dist/ContourChart.svelte.d.ts.map +1 -1
- package/dist/Dashboard.svelte +155 -0
- package/dist/Dashboard.svelte.d.ts +21 -0
- package/dist/Dashboard.svelte.d.ts.map +1 -0
- package/dist/DashboardGrid.svelte +237 -0
- package/dist/DashboardGrid.svelte.d.ts +24 -0
- package/dist/DashboardGrid.svelte.d.ts.map +1 -0
- package/dist/DataTable.svelte +3 -1
- package/dist/DataTable.svelte.d.ts +1 -0
- package/dist/DataTable.svelte.d.ts.map +1 -1
- package/dist/DatePicker.svelte +33 -28
- package/dist/DatePicker.svelte.d.ts.map +1 -1
- package/dist/Density2DChart.svelte +10 -1
- package/dist/Density2DChart.svelte.d.ts +2 -0
- package/dist/Density2DChart.svelte.d.ts.map +1 -1
- package/dist/Dropdown.svelte +33 -9
- package/dist/Dropdown.svelte.d.ts.map +1 -1
- package/dist/EventFeedPanel.svelte +3 -3
- package/dist/EventFeedPanel.svelte.d.ts +1 -1
- package/dist/EventFeedPanel.svelte.d.ts.map +1 -1
- package/dist/FileUploader.svelte +7 -3
- package/dist/Footer.svelte +75 -11
- package/dist/Footer.svelte.d.ts +16 -6
- package/dist/Footer.svelte.d.ts.map +1 -1
- package/dist/ForceGraph.svelte +9 -3
- package/dist/ForceGraph.svelte.d.ts +4 -0
- package/dist/ForceGraph.svelte.d.ts.map +1 -1
- package/dist/HeatmapChart.svelte +39 -3
- package/dist/HeatmapChart.svelte.d.ts +4 -1
- package/dist/HeatmapChart.svelte.d.ts.map +1 -1
- package/dist/KanbanBoard.svelte +144 -0
- package/dist/KanbanBoard.svelte.d.ts +23 -0
- package/dist/KanbanBoard.svelte.d.ts.map +1 -0
- package/dist/ListReportPage.svelte +184 -0
- package/dist/ListReportPage.svelte.d.ts +46 -0
- package/dist/ListReportPage.svelte.d.ts.map +1 -0
- package/dist/MasterDetail.svelte +267 -0
- package/dist/MasterDetail.svelte.d.ts +35 -0
- package/dist/MasterDetail.svelte.d.ts.map +1 -0
- package/dist/NavDrawer.svelte +46 -0
- package/dist/NavDrawer.svelte.d.ts +17 -0
- package/dist/NavDrawer.svelte.d.ts.map +1 -0
- package/dist/NavItem.svelte +3 -5
- package/dist/NavItem.svelte.d.ts.map +1 -1
- package/dist/NavRail.svelte +147 -0
- package/dist/NavRail.svelte.d.ts +23 -0
- package/dist/NavRail.svelte.d.ts.map +1 -0
- package/dist/NavShell.svelte +218 -0
- package/dist/NavShell.svelte.d.ts +38 -0
- package/dist/NavShell.svelte.d.ts.map +1 -0
- package/dist/ObjectPage.svelte +222 -0
- package/dist/ObjectPage.svelte.d.ts +46 -0
- package/dist/ObjectPage.svelte.d.ts.map +1 -0
- package/dist/OrderedList.svelte +7 -12
- package/dist/OrderedList.svelte.d.ts.map +1 -1
- package/dist/PointAndFigureChart.svelte +18 -11
- package/dist/PointAndFigureChart.svelte.d.ts +1 -1
- package/dist/PointAndFigureChart.svelte.d.ts.map +1 -1
- package/dist/RenkoChart.svelte +40 -13
- package/dist/RenkoChart.svelte.d.ts +1 -1
- package/dist/RenkoChart.svelte.d.ts.map +1 -1
- package/dist/SelectableRow.svelte +16 -5
- package/dist/SelectableRow.svelte.d.ts +2 -0
- package/dist/SelectableRow.svelte.d.ts.map +1 -1
- package/dist/UtilityPanel.svelte +89 -0
- package/dist/UtilityPanel.svelte.d.ts +18 -0
- package/dist/UtilityPanel.svelte.d.ts.map +1 -0
- package/dist/VectorFieldChart.svelte +5 -5
- package/dist/VectorFieldChart.svelte.d.ts +1 -1
- package/dist/VectorFieldChart.svelte.d.ts.map +1 -1
- package/dist/WindBarbChart.svelte +5 -5
- package/dist/WindBarbChart.svelte.d.ts +1 -1
- package/dist/WindBarbChart.svelte.d.ts.map +1 -1
- package/dist/Wizard.svelte +125 -0
- package/dist/Wizard.svelte.d.ts +25 -0
- package/dist/Wizard.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +35 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/package.json +5 -5
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
export interface NavRailItem {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
href?: string;
|
|
8
|
+
active?: boolean;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
badge?: string | number;
|
|
11
|
+
icon?: Snippet;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface NavRailProps {
|
|
15
|
+
items?: NavRailItem[];
|
|
16
|
+
label?: string;
|
|
17
|
+
activeItemId?: string;
|
|
18
|
+
onItemSelect?: (id: string) => void;
|
|
19
|
+
footer?: Snippet;
|
|
20
|
+
children?: Snippet;
|
|
21
|
+
class?: string;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<script lang="ts">
|
|
26
|
+
let {
|
|
27
|
+
items = [],
|
|
28
|
+
label = "Primary navigation",
|
|
29
|
+
activeItemId,
|
|
30
|
+
onItemSelect,
|
|
31
|
+
footer,
|
|
32
|
+
children,
|
|
33
|
+
class: className
|
|
34
|
+
}: NavRailProps = $props();
|
|
35
|
+
|
|
36
|
+
const classes = $derived(["st-navRail", className].filter(Boolean).join(" "));
|
|
37
|
+
|
|
38
|
+
function isActive(item: NavRailItem) {
|
|
39
|
+
return item.active === true || item.id === activeItemId;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function selectItem(item: NavRailItem) {
|
|
43
|
+
if (!item.disabled) onItemSelect?.(item.id);
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<nav class={classes} aria-label={label}>
|
|
48
|
+
<div class="st-navRail__items">
|
|
49
|
+
{#each items as item (item.id)}
|
|
50
|
+
{#if item.href && !item.disabled}
|
|
51
|
+
<a class="st-navRail__item" class:st-navRail__item--active={isActive(item)} href={item.href} aria-current={isActive(item) ? "page" : undefined} title={item.label} onclick={() => selectItem(item)}>
|
|
52
|
+
{#if item.icon}<span class="st-navRail__icon">{@render item.icon()}</span>{/if}
|
|
53
|
+
<span class="st-navRail__label">{item.label}</span>
|
|
54
|
+
{#if item.badge != null}<span class="st-navRail__badge">{item.badge}</span>{/if}
|
|
55
|
+
</a>
|
|
56
|
+
{:else}
|
|
57
|
+
<button class="st-navRail__item" class:st-navRail__item--active={isActive(item)} type="button" disabled={item.disabled} aria-current={isActive(item) ? "page" : undefined} title={item.label} onclick={() => selectItem(item)}>
|
|
58
|
+
{#if item.icon}<span class="st-navRail__icon">{@render item.icon()}</span>{/if}
|
|
59
|
+
<span class="st-navRail__label">{item.label}</span>
|
|
60
|
+
{#if item.badge != null}<span class="st-navRail__badge">{item.badge}</span>{/if}
|
|
61
|
+
</button>
|
|
62
|
+
{/if}
|
|
63
|
+
{/each}
|
|
64
|
+
{@render children?.()}
|
|
65
|
+
</div>
|
|
66
|
+
{#if footer}
|
|
67
|
+
<footer class="st-navRail__footer">{@render footer()}</footer>
|
|
68
|
+
{/if}
|
|
69
|
+
</nav>
|
|
70
|
+
|
|
71
|
+
<style>
|
|
72
|
+
.st-navRail {
|
|
73
|
+
align-items: stretch;
|
|
74
|
+
background: var(--st-component-navRail-surface, var(--st-semantic-surface-raised));
|
|
75
|
+
color: var(--st-semantic-text-primary);
|
|
76
|
+
display: grid;
|
|
77
|
+
grid-template-rows: 1fr auto;
|
|
78
|
+
block-size: 100%;
|
|
79
|
+
inline-size: var(--st-component-navRail-width, 4.5rem);
|
|
80
|
+
padding: var(--st-spacing-2, 0.5rem);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.st-navRail__items,
|
|
84
|
+
.st-navRail__footer {
|
|
85
|
+
align-items: center;
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: column;
|
|
88
|
+
gap: var(--st-spacing-2, 0.5rem);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.st-navRail__items {
|
|
92
|
+
min-block-size: 0;
|
|
93
|
+
overflow-y: auto;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.st-navRail__item {
|
|
97
|
+
align-items: center;
|
|
98
|
+
background: transparent;
|
|
99
|
+
border: 1px solid transparent;
|
|
100
|
+
border-radius: var(--st-radius-md, 0.375rem);
|
|
101
|
+
color: var(--st-semantic-text-secondary);
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
display: inline-flex;
|
|
104
|
+
flex-direction: column;
|
|
105
|
+
font: inherit;
|
|
106
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
107
|
+
inline-size: 100%;
|
|
108
|
+
min-block-size: 3.25rem;
|
|
109
|
+
padding: var(--st-spacing-2, 0.5rem);
|
|
110
|
+
position: relative;
|
|
111
|
+
text-align: center;
|
|
112
|
+
text-decoration: none;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.st-navRail__item:hover,
|
|
116
|
+
.st-navRail__item--active {
|
|
117
|
+
background: var(--st-component-navRail-activeBackground, var(--st-semantic-surface-subtle));
|
|
118
|
+
color: var(--st-semantic-text-primary);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.st-navRail__item--active {
|
|
122
|
+
border-color: var(--st-component-navRail-activeBorder, var(--st-semantic-border-strong));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.st-navRail__item:disabled {
|
|
126
|
+
cursor: not-allowed;
|
|
127
|
+
opacity: 0.5;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.st-navRail__label {
|
|
131
|
+
font-size: 0.6875rem;
|
|
132
|
+
font-weight: 650;
|
|
133
|
+
line-height: 1.1;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.st-navRail__badge {
|
|
137
|
+
background: var(--st-component-navRail-badgeBackground, var(--st-semantic-surface-inverse));
|
|
138
|
+
border-radius: 999px;
|
|
139
|
+
color: var(--st-semantic-text-inverse);
|
|
140
|
+
font-size: 0.625rem;
|
|
141
|
+
line-height: 1;
|
|
142
|
+
padding: 0.125rem 0.3rem;
|
|
143
|
+
position: absolute;
|
|
144
|
+
right: 0.25rem;
|
|
145
|
+
top: 0.25rem;
|
|
146
|
+
}
|
|
147
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
export interface NavRailItem {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
badge?: string | number;
|
|
9
|
+
icon?: Snippet;
|
|
10
|
+
}
|
|
11
|
+
export interface NavRailProps {
|
|
12
|
+
items?: NavRailItem[];
|
|
13
|
+
label?: string;
|
|
14
|
+
activeItemId?: string;
|
|
15
|
+
onItemSelect?: (id: string) => void;
|
|
16
|
+
footer?: Snippet;
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
class?: string;
|
|
19
|
+
}
|
|
20
|
+
declare const NavRail: import("svelte").Component<NavRailProps, {}, "">;
|
|
21
|
+
type NavRail = ReturnType<typeof NavRail>;
|
|
22
|
+
export default NavRail;
|
|
23
|
+
//# sourceMappingURL=NavRail.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavRail.svelte.d.ts","sourceRoot":"","sources":["../src/lib/NavRail.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAsDH,QAAA,MAAM,OAAO,kDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/** Variante de chrome du panneau de navigation.
|
|
3
|
+
* - `rail` : panneau latéral persistant (`<aside>` complementary) ;
|
|
4
|
+
* - `drawer` : overlay — DÉLÈGUE au composant Drawer (rôle dialog + Escape + backdrop). */
|
|
5
|
+
export type NavShellVariant = "rail" | "drawer";
|
|
6
|
+
|
|
7
|
+
/** Côté d'ancrage quand `variant="drawer"` (transmis tel quel à Drawer). */
|
|
8
|
+
export type NavShellSide = "left" | "right" | "bottom";
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<script lang="ts">
|
|
12
|
+
// NavShell — CHROME d'un rail / drawer de navigation (vague 3 du NavSystem).
|
|
13
|
+
// Régions EXCLUSIVES pour que les produits ne mélangent plus nav + filtre +
|
|
14
|
+
// action + détail dans une bouillie :
|
|
15
|
+
// • header → titre (optionnel), flèche-retour maître→détail, sous-titre ;
|
|
16
|
+
// • search → slot pleine largeur (le consommateur y met un Search fluid) ;
|
|
17
|
+
// • body → corps SCROLLABLE (NavSection / NavList / NavTree) ;
|
|
18
|
+
// • footer → zone d'actions (le consommateur y met un NavActionStack).
|
|
19
|
+
// ZÉRO-ENTROPIE : en mode `drawer`, on ne réimplémente PAS l'overlay — on
|
|
20
|
+
// RÉUTILISE le composant Drawer (open/side/title + dialog/Escape/backdrop) et
|
|
21
|
+
// on lui passe le même header/search/body/footer via ses slots children/footer.
|
|
22
|
+
// En mode `rail`, panneau persistant <aside> role=complementary.
|
|
23
|
+
// Style token-only scopé, AUCUN hex.
|
|
24
|
+
import type { Snippet } from "svelte";
|
|
25
|
+
import Drawer from "./Drawer.svelte";
|
|
26
|
+
|
|
27
|
+
type NavShellProps = {
|
|
28
|
+
/** Chrome : panneau persistant (`rail`) ou overlay délégué à Drawer (`drawer`). */
|
|
29
|
+
variant?: NavShellVariant;
|
|
30
|
+
/** Titre du panneau, rendu dans le `<header>` (rail) ou via Drawer (drawer). */
|
|
31
|
+
title?: string;
|
|
32
|
+
/** Sous-titre muet sous le titre. */
|
|
33
|
+
subtitle?: string;
|
|
34
|
+
/** Affiche une flèche-retour dans l'en-tête (pattern maître→détail). */
|
|
35
|
+
back?: boolean;
|
|
36
|
+
/** Appelé au clic sur la flèche-retour. */
|
|
37
|
+
onBack?: () => void;
|
|
38
|
+
/** Libellé accessible de la flèche-retour. */
|
|
39
|
+
backLabel?: string;
|
|
40
|
+
/** Libellé accessible du panneau (aria-label de l'aside / du dialog). */
|
|
41
|
+
label?: string;
|
|
42
|
+
/** Slot de recherche rendu PLEINE LARGEUR (ex. Search fluid). */
|
|
43
|
+
search?: Snippet;
|
|
44
|
+
/** Zone d'actions en pied (ex. NavActionStack). */
|
|
45
|
+
footer?: Snippet;
|
|
46
|
+
/** Corps scrollable (NavSection / NavList / NavTree). */
|
|
47
|
+
children: Snippet;
|
|
48
|
+
/** Ouverture du tiroir quand `variant="drawer"` (bindable). */
|
|
49
|
+
open?: boolean;
|
|
50
|
+
/** Côté d'ancrage du tiroir quand `variant="drawer"`. */
|
|
51
|
+
side?: NavShellSide;
|
|
52
|
+
class?: string;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
let {
|
|
56
|
+
variant = "rail",
|
|
57
|
+
title,
|
|
58
|
+
subtitle,
|
|
59
|
+
back = false,
|
|
60
|
+
onBack,
|
|
61
|
+
backLabel = "Retour",
|
|
62
|
+
label,
|
|
63
|
+
search,
|
|
64
|
+
footer,
|
|
65
|
+
children,
|
|
66
|
+
open = $bindable(false),
|
|
67
|
+
side = "left",
|
|
68
|
+
class: className
|
|
69
|
+
}: NavShellProps = $props();
|
|
70
|
+
|
|
71
|
+
const rootClasses = $derived(
|
|
72
|
+
["st-navShell", `st-navShell--${variant}`, className].filter(Boolean).join(" ")
|
|
73
|
+
);
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<!-- Contenu commun aux deux variantes : header (back/titre/sous-titre) + search
|
|
77
|
+
pleine largeur. Le corps et le footer diffèrent selon le contenant. -->
|
|
78
|
+
{#snippet head()}
|
|
79
|
+
{#if back || title || subtitle}
|
|
80
|
+
<header class="st-navShell__header">
|
|
81
|
+
{#if back}
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
class="st-navShell__back"
|
|
85
|
+
aria-label={backLabel}
|
|
86
|
+
onclick={() => onBack?.()}
|
|
87
|
+
>
|
|
88
|
+
<span aria-hidden="true">←</span>
|
|
89
|
+
</button>
|
|
90
|
+
{/if}
|
|
91
|
+
{#if title || subtitle}
|
|
92
|
+
<div class="st-navShell__heading">
|
|
93
|
+
{#if title}<p class="st-navShell__title">{title}</p>{/if}
|
|
94
|
+
{#if subtitle}<p class="st-navShell__subtitle">{subtitle}</p>{/if}
|
|
95
|
+
</div>
|
|
96
|
+
{/if}
|
|
97
|
+
</header>
|
|
98
|
+
{/if}
|
|
99
|
+
{#if search}
|
|
100
|
+
<div class="st-navShell__search">{@render search()}</div>
|
|
101
|
+
{/if}
|
|
102
|
+
{/snippet}
|
|
103
|
+
|
|
104
|
+
{#if variant === "drawer"}
|
|
105
|
+
<!-- Overlay : on délègue le chrome (dialog/Escape/backdrop) à Drawer. Drawer
|
|
106
|
+
exige un `title` ; à défaut on retombe sur `label` puis une valeur sûre.
|
|
107
|
+
Le header/search/body passent dans `children`, le footer dans son slot. -->
|
|
108
|
+
<Drawer
|
|
109
|
+
bind:open
|
|
110
|
+
{side}
|
|
111
|
+
title={title ?? label ?? "Navigation"}
|
|
112
|
+
class={rootClasses}
|
|
113
|
+
{footer}
|
|
114
|
+
>
|
|
115
|
+
{@render head()}
|
|
116
|
+
<div class="st-navShell__body">
|
|
117
|
+
{@render children()}
|
|
118
|
+
</div>
|
|
119
|
+
</Drawer>
|
|
120
|
+
{:else}
|
|
121
|
+
<!-- Panneau persistant : région complementary titrée. -->
|
|
122
|
+
<aside class={rootClasses} aria-label={label ?? title}>
|
|
123
|
+
{@render head()}
|
|
124
|
+
<div class="st-navShell__body">
|
|
125
|
+
{@render children()}
|
|
126
|
+
</div>
|
|
127
|
+
{#if footer}
|
|
128
|
+
<footer class="st-navShell__footer">
|
|
129
|
+
{@render footer()}
|
|
130
|
+
</footer>
|
|
131
|
+
{/if}
|
|
132
|
+
</aside>
|
|
133
|
+
{/if}
|
|
134
|
+
|
|
135
|
+
<style>
|
|
136
|
+
/* Token-only scopé. Rail = grille à 3 rangs (header+search auto / body 1fr /
|
|
137
|
+
footer auto) qui plafonne en hauteur pour que SEUL le corps scrolle. */
|
|
138
|
+
.st-navShell--rail {
|
|
139
|
+
background: var(--st-component-navShell-surface, var(--st-semantic-surface-raised));
|
|
140
|
+
border-color: var(--st-component-navShell-border, var(--st-semantic-border-subtle));
|
|
141
|
+
border-right-style: solid;
|
|
142
|
+
border-right-width: 1px;
|
|
143
|
+
color: var(--st-semantic-text-primary);
|
|
144
|
+
display: grid;
|
|
145
|
+
grid-template-rows: auto 1fr auto;
|
|
146
|
+
height: 100%;
|
|
147
|
+
inline-size: var(--st-component-navShell-width, 18rem);
|
|
148
|
+
max-inline-size: 100%;
|
|
149
|
+
padding: var(--st-spacing-4, 1rem);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.st-navShell__header {
|
|
153
|
+
align-items: center;
|
|
154
|
+
display: flex;
|
|
155
|
+
gap: var(--st-spacing-2, 0.5rem);
|
|
156
|
+
padding-block-end: var(--st-spacing-3, 0.75rem);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.st-navShell__back {
|
|
160
|
+
align-items: center;
|
|
161
|
+
background: transparent;
|
|
162
|
+
border: 1px solid var(--st-semantic-border-subtle);
|
|
163
|
+
border-radius: var(--st-radius-small, 0.375rem);
|
|
164
|
+
color: var(--st-semantic-text-primary);
|
|
165
|
+
cursor: pointer;
|
|
166
|
+
display: inline-flex;
|
|
167
|
+
flex: 0 0 auto;
|
|
168
|
+
height: 2rem;
|
|
169
|
+
justify-content: center;
|
|
170
|
+
width: 2rem;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.st-navShell__heading {
|
|
174
|
+
display: flex;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
177
|
+
min-inline-size: 0;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.st-navShell__title {
|
|
181
|
+
font-size: var(--st-component-navShell-titleSize, 1rem);
|
|
182
|
+
font-weight: 600;
|
|
183
|
+
line-height: 1.3;
|
|
184
|
+
margin: 0;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.st-navShell__subtitle {
|
|
188
|
+
color: var(--st-semantic-text-secondary);
|
|
189
|
+
font-size: var(--st-component-navShell-subtitleSize, 0.8125rem);
|
|
190
|
+
line-height: 1.4;
|
|
191
|
+
margin: 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Search pleine largeur du panneau. */
|
|
195
|
+
.st-navShell__search {
|
|
196
|
+
display: block;
|
|
197
|
+
inline-size: 100%;
|
|
198
|
+
padding-block-end: var(--st-spacing-3, 0.75rem);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/* Le corps est la SEULE région scrollable (1fr en rail, overflow en drawer). */
|
|
202
|
+
.st-navShell__body {
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
gap: var(--st-spacing-2, 0.5rem);
|
|
206
|
+
min-block-size: 0;
|
|
207
|
+
overflow-y: auto;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.st-navShell__footer {
|
|
211
|
+
border-color: var(--st-component-navShell-border, var(--st-semantic-border-subtle));
|
|
212
|
+
border-top-style: solid;
|
|
213
|
+
border-top-width: 1px;
|
|
214
|
+
display: block;
|
|
215
|
+
margin-block-start: var(--st-spacing-3, 0.75rem);
|
|
216
|
+
padding-block-start: var(--st-spacing-3, 0.75rem);
|
|
217
|
+
}
|
|
218
|
+
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Variante de chrome du panneau de navigation.
|
|
2
|
+
* - `rail` : panneau latéral persistant (`<aside>` complementary) ;
|
|
3
|
+
* - `drawer` : overlay — DÉLÈGUE au composant Drawer (rôle dialog + Escape + backdrop). */
|
|
4
|
+
export type NavShellVariant = "rail" | "drawer";
|
|
5
|
+
/** Côté d'ancrage quand `variant="drawer"` (transmis tel quel à Drawer). */
|
|
6
|
+
export type NavShellSide = "left" | "right" | "bottom";
|
|
7
|
+
import type { Snippet } from "svelte";
|
|
8
|
+
type NavShellProps = {
|
|
9
|
+
/** Chrome : panneau persistant (`rail`) ou overlay délégué à Drawer (`drawer`). */
|
|
10
|
+
variant?: NavShellVariant;
|
|
11
|
+
/** Titre du panneau, rendu dans le `<header>` (rail) ou via Drawer (drawer). */
|
|
12
|
+
title?: string;
|
|
13
|
+
/** Sous-titre muet sous le titre. */
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
/** Affiche une flèche-retour dans l'en-tête (pattern maître→détail). */
|
|
16
|
+
back?: boolean;
|
|
17
|
+
/** Appelé au clic sur la flèche-retour. */
|
|
18
|
+
onBack?: () => void;
|
|
19
|
+
/** Libellé accessible de la flèche-retour. */
|
|
20
|
+
backLabel?: string;
|
|
21
|
+
/** Libellé accessible du panneau (aria-label de l'aside / du dialog). */
|
|
22
|
+
label?: string;
|
|
23
|
+
/** Slot de recherche rendu PLEINE LARGEUR (ex. Search fluid). */
|
|
24
|
+
search?: Snippet;
|
|
25
|
+
/** Zone d'actions en pied (ex. NavActionStack). */
|
|
26
|
+
footer?: Snippet;
|
|
27
|
+
/** Corps scrollable (NavSection / NavList / NavTree). */
|
|
28
|
+
children: Snippet;
|
|
29
|
+
/** Ouverture du tiroir quand `variant="drawer"` (bindable). */
|
|
30
|
+
open?: boolean;
|
|
31
|
+
/** Côté d'ancrage du tiroir quand `variant="drawer"`. */
|
|
32
|
+
side?: NavShellSide;
|
|
33
|
+
class?: string;
|
|
34
|
+
};
|
|
35
|
+
declare const NavShell: import("svelte").Component<NavShellProps, {}, "open">;
|
|
36
|
+
type NavShell = ReturnType<typeof NavShell>;
|
|
37
|
+
export default NavShell;
|
|
38
|
+
//# sourceMappingURL=NavShell.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavShell.svelte.d.ts","sourceRoot":"","sources":["../src/lib/NavShell.svelte.ts"],"names":[],"mappings":"AAGE;;2FAE2F;AAC3F,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEhD,4EAA4E;AAC5E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAezD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAIpC,KAAK,aAAa,GAAG;IACnB,mFAAmF;IACnF,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yDAAyD;IACzD,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA0FJ,QAAA,MAAM,QAAQ,uDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export interface ObjectPageBreadcrumbItem {
|
|
3
|
+
label: string;
|
|
4
|
+
href?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ObjectPageKpi {
|
|
8
|
+
label: string;
|
|
9
|
+
value: string;
|
|
10
|
+
unit?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ObjectPageField {
|
|
14
|
+
key: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ObjectPageColumn {
|
|
19
|
+
key: string;
|
|
20
|
+
label: string;
|
|
21
|
+
sortable?: boolean;
|
|
22
|
+
align?: "start" | "center" | "end";
|
|
23
|
+
width?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ObjectPageRow {
|
|
27
|
+
id: string;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type ObjectPageProps = {
|
|
32
|
+
breadcrumb?: ObjectPageBreadcrumbItem[];
|
|
33
|
+
entityTitle: string;
|
|
34
|
+
entityStatus?: { label: string; tone: "neutral" | "info" | "success" | "warning" | "error" };
|
|
35
|
+
primaryAction?: string;
|
|
36
|
+
secondaryAction?: string;
|
|
37
|
+
kpis?: ObjectPageKpi[];
|
|
38
|
+
fieldsTitle?: string;
|
|
39
|
+
fields?: ObjectPageField[];
|
|
40
|
+
relatedTitle?: string;
|
|
41
|
+
relatedColumns?: ObjectPageColumn[];
|
|
42
|
+
relatedRows?: ObjectPageRow[];
|
|
43
|
+
onprimaryaction?: () => void;
|
|
44
|
+
onsecondaryaction?: () => void;
|
|
45
|
+
};
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<script lang="ts">
|
|
49
|
+
import Badge from "./Badge.svelte";
|
|
50
|
+
import Button from "./Button.svelte";
|
|
51
|
+
import DataTable from "./DataTable.svelte";
|
|
52
|
+
import Breadcrumb from "./Breadcrumb.svelte";
|
|
53
|
+
|
|
54
|
+
let {
|
|
55
|
+
breadcrumb = [],
|
|
56
|
+
entityTitle,
|
|
57
|
+
entityStatus,
|
|
58
|
+
primaryAction,
|
|
59
|
+
secondaryAction,
|
|
60
|
+
kpis = [],
|
|
61
|
+
fieldsTitle,
|
|
62
|
+
fields = [],
|
|
63
|
+
relatedTitle,
|
|
64
|
+
relatedColumns = [],
|
|
65
|
+
relatedRows = [],
|
|
66
|
+
onprimaryaction,
|
|
67
|
+
onsecondaryaction,
|
|
68
|
+
}: ObjectPageProps = $props();
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<div class="st-op">
|
|
72
|
+
{#if breadcrumb.length > 0}
|
|
73
|
+
<Breadcrumb items={breadcrumb} />
|
|
74
|
+
{/if}
|
|
75
|
+
|
|
76
|
+
<div class="st-op__header">
|
|
77
|
+
<div class="st-op__titleRow">
|
|
78
|
+
<h1 class="st-op__title">{entityTitle}</h1>
|
|
79
|
+
{#if entityStatus}
|
|
80
|
+
<Badge tone={entityStatus.tone}>{entityStatus.label}</Badge>
|
|
81
|
+
{/if}
|
|
82
|
+
</div>
|
|
83
|
+
<div class="st-op__actions">
|
|
84
|
+
{#if secondaryAction}
|
|
85
|
+
<Button variant="secondary" onclick={onsecondaryaction}>{secondaryAction}</Button>
|
|
86
|
+
{/if}
|
|
87
|
+
{#if primaryAction}
|
|
88
|
+
<Button variant="primary" onclick={onprimaryaction}>{primaryAction}</Button>
|
|
89
|
+
{/if}
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
{#if kpis.length > 0}
|
|
94
|
+
<div class="st-op__kpi-row">
|
|
95
|
+
{#each kpis as kpi}
|
|
96
|
+
<div class="st-op__kpi">
|
|
97
|
+
<span class="st-op__kpiLabel">{kpi.label}</span>
|
|
98
|
+
<span class="st-op__kpiValue">{kpi.value}{#if kpi.unit}<span class="st-op__kpiUnit"> {kpi.unit}</span>{/if}</span>
|
|
99
|
+
</div>
|
|
100
|
+
{/each}
|
|
101
|
+
</div>
|
|
102
|
+
{/if}
|
|
103
|
+
|
|
104
|
+
{#if fields.length > 0}
|
|
105
|
+
<div class="st-op__fields">
|
|
106
|
+
{#if fieldsTitle}
|
|
107
|
+
<h2 class="st-op__sectionTitle">{fieldsTitle}</h2>
|
|
108
|
+
{/if}
|
|
109
|
+
<dl class="st-op__dl">
|
|
110
|
+
{#each fields as field}
|
|
111
|
+
<div class="st-op__dlRow">
|
|
112
|
+
<dt class="st-op__dt">{field.key}</dt>
|
|
113
|
+
<dd class="st-op__dd">{field.value}</dd>
|
|
114
|
+
</div>
|
|
115
|
+
{/each}
|
|
116
|
+
</dl>
|
|
117
|
+
</div>
|
|
118
|
+
{/if}
|
|
119
|
+
|
|
120
|
+
{#if relatedColumns.length > 0}
|
|
121
|
+
<div class="st-op__related">
|
|
122
|
+
{#if relatedTitle}
|
|
123
|
+
<h2 class="st-op__sectionTitle">{relatedTitle}</h2>
|
|
124
|
+
{/if}
|
|
125
|
+
<DataTable columns={relatedColumns} rows={relatedRows} />
|
|
126
|
+
</div>
|
|
127
|
+
{/if}
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<style>
|
|
131
|
+
.st-op {
|
|
132
|
+
display: flex;
|
|
133
|
+
flex-direction: column;
|
|
134
|
+
gap: var(--st-spacing-6, 1.5rem);
|
|
135
|
+
padding: var(--st-spacing-6, 1.5rem);
|
|
136
|
+
background: var(--st-semantic-surface-default);
|
|
137
|
+
color: var(--st-semantic-text-primary);
|
|
138
|
+
min-block-size: 100%;
|
|
139
|
+
}
|
|
140
|
+
.st-op__header {
|
|
141
|
+
display: flex;
|
|
142
|
+
align-items: flex-start;
|
|
143
|
+
justify-content: space-between;
|
|
144
|
+
gap: var(--st-spacing-4, 1rem);
|
|
145
|
+
flex-wrap: wrap;
|
|
146
|
+
}
|
|
147
|
+
.st-op__titleRow {
|
|
148
|
+
display: flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
gap: var(--st-spacing-3, 0.75rem);
|
|
151
|
+
flex-wrap: wrap;
|
|
152
|
+
}
|
|
153
|
+
.st-op__title {
|
|
154
|
+
font-size: 1.75rem;
|
|
155
|
+
font-weight: 700;
|
|
156
|
+
margin: 0;
|
|
157
|
+
}
|
|
158
|
+
.st-op__actions {
|
|
159
|
+
display: flex;
|
|
160
|
+
gap: var(--st-spacing-2, 0.5rem);
|
|
161
|
+
flex-shrink: 0;
|
|
162
|
+
}
|
|
163
|
+
.st-op__kpi-row {
|
|
164
|
+
display: flex;
|
|
165
|
+
gap: var(--st-spacing-4, 1rem);
|
|
166
|
+
flex-wrap: wrap;
|
|
167
|
+
}
|
|
168
|
+
.st-op__kpi {
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
172
|
+
padding: var(--st-spacing-4, 1rem);
|
|
173
|
+
background: var(--st-semantic-surface-raised);
|
|
174
|
+
border: 1px solid var(--st-semantic-border-subtle);
|
|
175
|
+
border-radius: var(--st-radius-md, 0.5rem);
|
|
176
|
+
min-inline-size: 10rem;
|
|
177
|
+
}
|
|
178
|
+
.st-op__kpiLabel {
|
|
179
|
+
font-size: 0.75rem;
|
|
180
|
+
color: var(--st-semantic-text-secondary);
|
|
181
|
+
}
|
|
182
|
+
.st-op__kpiValue {
|
|
183
|
+
font-size: 1.5rem;
|
|
184
|
+
font-weight: 700;
|
|
185
|
+
}
|
|
186
|
+
.st-op__kpiUnit {
|
|
187
|
+
font-size: 0.875rem;
|
|
188
|
+
font-weight: 400;
|
|
189
|
+
color: var(--st-semantic-text-secondary);
|
|
190
|
+
}
|
|
191
|
+
.st-op__sectionTitle {
|
|
192
|
+
font-size: 1rem;
|
|
193
|
+
font-weight: 650;
|
|
194
|
+
margin: 0 0 var(--st-spacing-3, 0.75rem);
|
|
195
|
+
}
|
|
196
|
+
.st-op__dl {
|
|
197
|
+
margin: 0;
|
|
198
|
+
display: grid;
|
|
199
|
+
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
|
200
|
+
gap: var(--st-spacing-3, 0.75rem) var(--st-spacing-6, 1.5rem);
|
|
201
|
+
}
|
|
202
|
+
.st-op__dlRow {
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
gap: 0.2rem;
|
|
206
|
+
}
|
|
207
|
+
.st-op__dt {
|
|
208
|
+
font-size: 0.75rem;
|
|
209
|
+
color: var(--st-semantic-text-secondary);
|
|
210
|
+
font-weight: 500;
|
|
211
|
+
}
|
|
212
|
+
.st-op__dd {
|
|
213
|
+
margin: 0;
|
|
214
|
+
font-size: 0.875rem;
|
|
215
|
+
color: var(--st-semantic-text-primary);
|
|
216
|
+
}
|
|
217
|
+
.st-op__fields,
|
|
218
|
+
.st-op__related {
|
|
219
|
+
display: flex;
|
|
220
|
+
flex-direction: column;
|
|
221
|
+
}
|
|
222
|
+
</style>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface ObjectPageBreadcrumbItem {
|
|
2
|
+
label: string;
|
|
3
|
+
href?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ObjectPageKpi {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
unit?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ObjectPageField {
|
|
11
|
+
key: string;
|
|
12
|
+
value: string;
|
|
13
|
+
}
|
|
14
|
+
export interface ObjectPageColumn {
|
|
15
|
+
key: string;
|
|
16
|
+
label: string;
|
|
17
|
+
sortable?: boolean;
|
|
18
|
+
align?: "start" | "center" | "end";
|
|
19
|
+
width?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ObjectPageRow {
|
|
22
|
+
id: string;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export type ObjectPageProps = {
|
|
26
|
+
breadcrumb?: ObjectPageBreadcrumbItem[];
|
|
27
|
+
entityTitle: string;
|
|
28
|
+
entityStatus?: {
|
|
29
|
+
label: string;
|
|
30
|
+
tone: "neutral" | "info" | "success" | "warning" | "error";
|
|
31
|
+
};
|
|
32
|
+
primaryAction?: string;
|
|
33
|
+
secondaryAction?: string;
|
|
34
|
+
kpis?: ObjectPageKpi[];
|
|
35
|
+
fieldsTitle?: string;
|
|
36
|
+
fields?: ObjectPageField[];
|
|
37
|
+
relatedTitle?: string;
|
|
38
|
+
relatedColumns?: ObjectPageColumn[];
|
|
39
|
+
relatedRows?: ObjectPageRow[];
|
|
40
|
+
onprimaryaction?: () => void;
|
|
41
|
+
onsecondaryaction?: () => void;
|
|
42
|
+
};
|
|
43
|
+
declare const ObjectPage: import("svelte").Component<ObjectPageProps, {}, "">;
|
|
44
|
+
type ObjectPage = ReturnType<typeof ObjectPage>;
|
|
45
|
+
export default ObjectPage;
|
|
46
|
+
//# sourceMappingURL=ObjectPage.svelte.d.ts.map
|