@nordmanai/nif 0.2.5 → 0.2.8
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/index.d.ts +5 -0
- package/dist/index.js +6899 -6375
- package/dist/styles.css +1 -1
- package/dist/ui/components/nm-alert-dialog/nm-alert-dialog.d.ts +17 -0
- package/dist/ui/components/nm-dialog/nm-dialog.d.ts +4 -0
- package/dist/ui/components/nm-drawer/nm-drawer.d.ts +18 -0
- package/dist/ui/components/nm-sidebar/nm-sidebar.d.ts +134 -0
- package/dist/ui/config/nm-drawer.d.ts +3 -0
- package/dist/ui/config/nm-sidebar.d.ts +29 -0
- package/package.json +1 -1
- package/registry/index.json +212 -1
- package/registry/ui/components/nm-alert-dialog/nm-alert-dialog.css +4 -0
- package/registry/ui/components/nm-alert-dialog/nm-alert-dialog.tsx +43 -0
- package/registry/ui/components/nm-dialog/nm-dialog.css +15 -0
- package/registry/ui/components/nm-dialog/nm-dialog.tsx +8 -0
- package/registry/ui/components/nm-drawer/nm-drawer.css +70 -0
- package/registry/ui/components/nm-drawer/nm-drawer.tsx +41 -0
- package/registry/ui/components/nm-sidebar/nm-sidebar.css +647 -0
- package/registry/ui/components/nm-sidebar/nm-sidebar.tsx +532 -0
- package/registry/ui/config/nm-drawer.ts +3 -0
- package/registry/ui/config/nm-sidebar.ts +37 -0
- package/registry/ui/styles/tokens.css +10 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog';
|
|
3
|
+
/**
|
|
4
|
+
* Base UI Alert Dialog, in the shadcn composition, styled by NIF tokens.
|
|
5
|
+
* A dialog that asks before something that cannot be undone. It does not close on a click outside, only from its actions or Escape.
|
|
6
|
+
*/
|
|
7
|
+
export declare function NmAlertDialog(props: AlertDialogPrimitive.Root.Props): import("react").JSX.Element;
|
|
8
|
+
export declare function NmAlertDialogTrigger(props: AlertDialogPrimitive.Trigger.Props): import("react").JSX.Element;
|
|
9
|
+
export declare function NmAlertDialogContent({ className, children, ...props }: AlertDialogPrimitive.Popup.Props): import("react").JSX.Element;
|
|
10
|
+
export declare function NmAlertDialogHeader({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
11
|
+
export declare function NmAlertDialogFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
12
|
+
export declare function NmAlertDialogTitle({ className, ...props }: AlertDialogPrimitive.Title.Props): import("react").JSX.Element;
|
|
13
|
+
export declare function NmAlertDialogDescription({ className, ...props }: AlertDialogPrimitive.Description.Props): import("react").JSX.Element;
|
|
14
|
+
/** The action that confirms. Give it a NIF Button with `render`; `tone="danger"` when it destroys. */
|
|
15
|
+
export declare function NmAlertDialogAction(props: AlertDialogPrimitive.Close.Props): import("react").JSX.Element;
|
|
16
|
+
/** The action that cancels. Give it a NIF Button with `render`. */
|
|
17
|
+
export declare function NmAlertDialogCancel(props: AlertDialogPrimitive.Close.Props): import("react").JSX.Element;
|
|
@@ -9,5 +9,9 @@ export declare function NmDialogContent({ className, children, size, ...props }:
|
|
|
9
9
|
size?: 'default' | 'full';
|
|
10
10
|
}): import("react").JSX.Element;
|
|
11
11
|
export declare function NmDialogHeader({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
12
|
+
/** The content between the header and the footer. It scrolls when the dialog is full. */
|
|
13
|
+
export declare function NmDialogBody({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
14
|
+
/** The actions at the end, right-aligned. */
|
|
15
|
+
export declare function NmDialogFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
12
16
|
export declare function NmDialogTitle({ className, ...props }: DialogPrimitive.Title.Props): import("react").JSX.Element;
|
|
13
17
|
export declare function NmDialogDescription({ className, ...props }: DialogPrimitive.Description.Props): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import { Dialog as DialogPrimitive } from '../../lib/nm-motion.ts';
|
|
3
|
+
import type { NmDrawerSide } from '../../config/nm-drawer.ts';
|
|
4
|
+
/**
|
|
5
|
+
* A panel that slides in from an edge, over the page, with a scrim behind it. The shadcn Sheet, on the Base UI
|
|
6
|
+
* Dialog, styled by NIF tokens. For navigation on a phone, filters, or a form that should not leave the page.
|
|
7
|
+
*/
|
|
8
|
+
export declare function NmDrawer(props: DialogPrimitive.Root.Props): import("react").JSX.Element;
|
|
9
|
+
export declare function NmDrawerTrigger(props: DialogPrimitive.Trigger.Props): import("react").JSX.Element;
|
|
10
|
+
export declare function NmDrawerClose(props: DialogPrimitive.Close.Props): import("react").JSX.Element;
|
|
11
|
+
/** The panel. `side` is the edge it comes from. Its width is the --nm-width-drawer token. */
|
|
12
|
+
export declare function NmDrawerContent({ className, children, side, ...props }: DialogPrimitive.Popup.Props & {
|
|
13
|
+
side?: NmDrawerSide;
|
|
14
|
+
}): import("react").JSX.Element;
|
|
15
|
+
export declare function NmDrawerHeader({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
16
|
+
export declare function NmDrawerFooter({ className, ...props }: ComponentProps<'div'>): import("react").JSX.Element;
|
|
17
|
+
export declare function NmDrawerTitle({ className, ...props }: DialogPrimitive.Title.Props): import("react").JSX.Element;
|
|
18
|
+
export declare function NmDrawerDescription({ className, ...props }: DialogPrimitive.Description.Props): import("react").JSX.Element;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactElement, type ReactNode } from 'react';
|
|
2
|
+
import { type NmSidebarButtonSize, type NmSidebarButtonVariant, type NmSidebarCollapsible, type NmSidebarSide, type NmSidebarState, type NmSidebarVariant } from '../../config/nm-sidebar.ts';
|
|
3
|
+
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
4
|
+
import { NmChip } from '../nm-chip/nm-chip.tsx';
|
|
5
|
+
import { NmIcon } from '../nm-icon/nm-icon.tsx';
|
|
6
|
+
import { NmInput } from '../nm-input/nm-input.tsx';
|
|
7
|
+
import { NmSeparator } from '../nm-separator/nm-separator.tsx';
|
|
8
|
+
import { NmSmallIconButton } from '../nm-small-icon-button/nm-small-icon-button.tsx';
|
|
9
|
+
import { NmTooltipContent } from '../nm-tooltip/nm-tooltip.tsx';
|
|
10
|
+
/** Replace the element a part renders, as Base UI does: give it an `<a>` and the part is a link. */
|
|
11
|
+
type RenderProp = ReactElement | undefined;
|
|
12
|
+
type SidebarContextValue = {
|
|
13
|
+
state: NmSidebarState;
|
|
14
|
+
open: boolean;
|
|
15
|
+
setOpen: (open: boolean) => void;
|
|
16
|
+
openMobile: boolean;
|
|
17
|
+
setOpenMobile: (open: boolean) => void;
|
|
18
|
+
isMobile: boolean;
|
|
19
|
+
toggleSidebar: () => void;
|
|
20
|
+
/** The collapsed sidebar shown in full over the page while the pointer is on it or on the toggle. */
|
|
21
|
+
peek: boolean;
|
|
22
|
+
/** Starts a peek. Nothing happens when the sidebar is open, on a phone, or when peeking is off. */
|
|
23
|
+
peekIn: (event?: {
|
|
24
|
+
clientX: number;
|
|
25
|
+
clientY: number;
|
|
26
|
+
}) => void;
|
|
27
|
+
/** Ends a peek after a short grace, so the pointer can travel from the toggle into the sidebar. */
|
|
28
|
+
peekOut: () => void;
|
|
29
|
+
collapsible: NmSidebarCollapsible;
|
|
30
|
+
setCollapsible: (mode: NmSidebarCollapsible) => void;
|
|
31
|
+
};
|
|
32
|
+
/** The sidebar's state: expanded or collapsed, peeking, on a desktop or a phone, and the function that toggles it. */
|
|
33
|
+
export declare function useSidebar(): SidebarContextValue;
|
|
34
|
+
export type NmSidebarProviderProps = ComponentProps<'div'> & {
|
|
35
|
+
defaultOpen?: boolean;
|
|
36
|
+
open?: boolean;
|
|
37
|
+
onOpenChange?: (open: boolean) => void;
|
|
38
|
+
/** ⌘B / Ctrl+B toggles the sidebar. Off when several sidebars share a page. */
|
|
39
|
+
shortcut?: boolean;
|
|
40
|
+
/** On by default: resting the pointer on the toggle or on the collapsed sidebar shows it in full, over the page, until the pointer leaves. */
|
|
41
|
+
peek?: boolean;
|
|
42
|
+
/** `fill` takes the room it is given. `sm` and `lg` are fixed heights, for a sidebar shown inside a page. */
|
|
43
|
+
height?: 'fill' | 'sm' | 'lg';
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Holds the open state and hands it to every part inside. Wrap the sidebar and the main area in it.
|
|
47
|
+
* The shadcn Sidebar composition, built from NIF primitives and styled by NIF tokens.
|
|
48
|
+
*/
|
|
49
|
+
export declare function NmSidebarProvider({ defaultOpen, open: openProp, onOpenChange, shortcut, peek: peekEnabled, height, className, style, children, ...props }: NmSidebarProviderProps): ReactNode;
|
|
50
|
+
export type NmSidebarProps = ComponentProps<'div'> & {
|
|
51
|
+
side?: NmSidebarSide;
|
|
52
|
+
variant?: NmSidebarVariant;
|
|
53
|
+
collapsible?: NmSidebarCollapsible;
|
|
54
|
+
/** The accessible name of the sidebar on a phone, where it opens over the page. */
|
|
55
|
+
label?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The sidebar itself. Beside the main area on a desktop, where it slides out of view, collapses to a column
|
|
59
|
+
* of icons, or collapses to its toggle alone. Over the page on a phone, in a drawer.
|
|
60
|
+
*/
|
|
61
|
+
export declare function NmSidebar({ side, variant, collapsible, label, className, children, ...props }: NmSidebarProps): ReactNode;
|
|
62
|
+
export type NmSidebarTriggerProps = Omit<ComponentProps<'button'>, 'aria-label'> & {
|
|
63
|
+
/** The accessible name. The tooltip says Open or Close by state. */
|
|
64
|
+
label?: string;
|
|
65
|
+
icon?: NmIconId;
|
|
66
|
+
/** On by default: a tooltip with the name and the ⌘B shortcut. */
|
|
67
|
+
tooltip?: boolean;
|
|
68
|
+
};
|
|
69
|
+
/** The button that opens and closes the sidebar. In the main area's bar, or in the sidebar's own header. Resting on it peeks the sidebar. */
|
|
70
|
+
export declare function NmSidebarTrigger({ className, label, icon, tooltip, onClick, onPointerEnter, onPointerLeave, ...props }: NmSidebarTriggerProps): ReactNode;
|
|
71
|
+
/** A thin strip on the sidebar's edge. Clicking it toggles the sidebar. */
|
|
72
|
+
export declare function NmSidebarRail({ className, label, ...props }: ComponentProps<'button'> & {
|
|
73
|
+
label?: string;
|
|
74
|
+
}): ReactNode;
|
|
75
|
+
/** The main area beside the sidebar. With the inset variant it is the raised card. */
|
|
76
|
+
export declare function NmSidebarInset({ className, ...props }: ComponentProps<'main'>): ReactNode;
|
|
77
|
+
/** A search field in the sidebar. The NIF Input. */
|
|
78
|
+
export declare function NmSidebarInput({ className, ...props }: ComponentProps<typeof NmInput>): ReactNode;
|
|
79
|
+
/** Sticky at the top: a brand, a title or a workspace switcher, and the toggle when the sidebar collapses to it. */
|
|
80
|
+
export declare function NmSidebarHeader({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
81
|
+
/** Sticky at the bottom: the person, settings or actions. */
|
|
82
|
+
export declare function NmSidebarFooter({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
83
|
+
/** The NIF Separator, fitted to the sidebar's padding. */
|
|
84
|
+
export declare function NmSidebarSeparator({ className, ...props }: ComponentProps<typeof NmSeparator>): ReactNode;
|
|
85
|
+
/** The region between the header and the footer. It scrolls. */
|
|
86
|
+
export declare function NmSidebarContent({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
87
|
+
/** Related navigation, with a label, an action and content. */
|
|
88
|
+
export declare function NmSidebarGroup({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
89
|
+
export declare function NmSidebarGroupLabel({ className, render, ref, ...props }: ComponentProps<'div'> & {
|
|
90
|
+
render?: RenderProp;
|
|
91
|
+
}): ReactNode;
|
|
92
|
+
/** An icon button at the end of a group label, such as add. The NIF small icon button, quiet. */
|
|
93
|
+
export declare function NmSidebarGroupAction({ className, ...props }: ComponentProps<typeof NmSmallIconButton>): ReactNode;
|
|
94
|
+
export declare function NmSidebarGroupContent({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
95
|
+
export declare function NmSidebarMenu({ className, ...props }: ComponentProps<'ul'>): ReactNode;
|
|
96
|
+
export declare function NmSidebarMenuItem({ className, ...props }: ComponentProps<'li'>): ReactNode;
|
|
97
|
+
export type NmSidebarMenuButtonProps = ComponentProps<'button'> & {
|
|
98
|
+
render?: RenderProp;
|
|
99
|
+
isActive?: boolean;
|
|
100
|
+
variant?: NmSidebarButtonVariant;
|
|
101
|
+
size?: NmSidebarButtonSize;
|
|
102
|
+
/** Shown beside the icon when the sidebar is collapsed to icons. A string, or the props of the tooltip content. */
|
|
103
|
+
tooltip?: string | ComponentProps<typeof NmTooltipContent>;
|
|
104
|
+
};
|
|
105
|
+
/** A row in the menu: an icon and a label, as a button or a link. Active, disabled, three sizes and two variants. */
|
|
106
|
+
export declare function NmSidebarMenuButton({ render, isActive, variant, size, tooltip, className, ref, ...props }: NmSidebarMenuButtonProps): ReactNode;
|
|
107
|
+
/** An icon button at the end of a row, such as more. The NIF small icon button, quiet. `showOnHover` keeps it hidden until the row is hovered or focused. */
|
|
108
|
+
export declare function NmSidebarMenuAction({ className, showOnHover, ...props }: ComponentProps<typeof NmSmallIconButton> & {
|
|
109
|
+
showOnHover?: boolean;
|
|
110
|
+
}): ReactNode;
|
|
111
|
+
/** A count or a short word at the end of a row. The NIF Chip, small. */
|
|
112
|
+
export declare function NmSidebarMenuBadge({ className, ...props }: ComponentProps<typeof NmChip>): ReactNode;
|
|
113
|
+
/** Two lines in a row, such as a name and a plan in the footer. For a large menu button. */
|
|
114
|
+
export declare function NmSidebarMenuText({ title, description, className, ...props }: ComponentProps<'span'> & {
|
|
115
|
+
title: string;
|
|
116
|
+
description?: string;
|
|
117
|
+
}): ReactNode;
|
|
118
|
+
/** A row's shape while its content loads. The icon and the text are random widths, so a list of them reads as a list. */
|
|
119
|
+
export declare function NmSidebarMenuSkeleton({ className, showIcon, ...props }: ComponentProps<'div'> & {
|
|
120
|
+
showIcon?: boolean;
|
|
121
|
+
}): ReactNode;
|
|
122
|
+
/** Rows under a row, indented by a line. */
|
|
123
|
+
export declare function NmSidebarMenuSub({ className, ...props }: ComponentProps<'ul'>): ReactNode;
|
|
124
|
+
export declare function NmSidebarMenuSubItem({ className, ...props }: ComponentProps<'li'>): ReactNode;
|
|
125
|
+
export declare function NmSidebarMenuSubButton({ render, size, isActive, className, ref, ...props }: ComponentProps<'a'> & {
|
|
126
|
+
render?: RenderProp;
|
|
127
|
+
size?: Exclude<NmSidebarButtonSize, 'lg'>;
|
|
128
|
+
isActive?: boolean;
|
|
129
|
+
}): ReactNode;
|
|
130
|
+
/** A chevron at the end of a row. In a collapsible row it points right and turns down when the row is open. With `menu` it points down, for a row that opens a menu. */
|
|
131
|
+
export declare function NmSidebarChevron({ className, menu, ...props }: Omit<ComponentProps<typeof NmIcon>, 'id'> & {
|
|
132
|
+
menu?: boolean;
|
|
133
|
+
}): ReactNode;
|
|
134
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Which edge of the view the sidebar sits on. */
|
|
2
|
+
export declare const NM_SIDEBAR_SIDES: readonly ['left', 'right'];
|
|
3
|
+
export type NmSidebarSide = (typeof NM_SIDEBAR_SIDES)[number];
|
|
4
|
+
/** `sidebar` is flush with the edge. `floating` is a raised card inside a margin. `inset` sits in a margin and the main area is the raised card. */
|
|
5
|
+
export declare const NM_SIDEBAR_VARIANTS: readonly ['sidebar', 'floating', 'inset'];
|
|
6
|
+
export type NmSidebarVariant = (typeof NM_SIDEBAR_VARIANTS)[number];
|
|
7
|
+
/**
|
|
8
|
+
* How the sidebar collapses.
|
|
9
|
+
* `offcanvas` slides out of view; the trigger lives in the main area.
|
|
10
|
+
* `icon` keeps a column of icons, one per row.
|
|
11
|
+
* `toggle` keeps only the toggle button, in the sidebar's own header.
|
|
12
|
+
* `none` never collapses.
|
|
13
|
+
*/
|
|
14
|
+
export declare const NM_SIDEBAR_COLLAPSIBLE: readonly ['offcanvas', 'icon', 'toggle', 'none'];
|
|
15
|
+
export type NmSidebarCollapsible = (typeof NM_SIDEBAR_COLLAPSIBLE)[number];
|
|
16
|
+
export declare const NM_SIDEBAR_STATES: readonly ['expanded', 'collapsed'];
|
|
17
|
+
export type NmSidebarState = (typeof NM_SIDEBAR_STATES)[number];
|
|
18
|
+
/** Row heights of a menu button: the small, default and large control heights. */
|
|
19
|
+
export declare const NM_SIDEBAR_BUTTON_SIZES: readonly ['sm', 'default', 'lg'];
|
|
20
|
+
export type NmSidebarButtonSize = (typeof NM_SIDEBAR_BUTTON_SIZES)[number];
|
|
21
|
+
/** `default` is a quiet row that fills on hover. `outline` draws the row's line and raises it. */
|
|
22
|
+
export declare const NM_SIDEBAR_BUTTON_VARIANTS: readonly ['default', 'outline'];
|
|
23
|
+
export type NmSidebarButtonVariant = (typeof NM_SIDEBAR_BUTTON_VARIANTS)[number];
|
|
24
|
+
/** The key that toggles the sidebar with the platform modifier: ⌘B on Mac, Ctrl+B elsewhere. */
|
|
25
|
+
export declare const NM_SIDEBAR_SHORTCUT = "b";
|
|
26
|
+
/** How long the pointer may be between the toggle and the peeked sidebar before the peek closes, in ms. */
|
|
27
|
+
export declare const NM_SIDEBAR_PEEK_LEAVE_MS = 200;
|
|
28
|
+
/** Below this width the sidebar opens over the page instead of beside it. The same breakpoint as the tokens' phone step. */
|
|
29
|
+
export declare const NM_SIDEBAR_MOBILE_QUERY = "(max-width: 48rem)";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nordmanai/nif",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Nordman Interface Framework: the one UI and UX system for every Nordman product. Base UI, in the shadcn composition, styled by NIF tokens.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
package/registry/index.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.2.
|
|
2
|
+
"version": "0.2.8",
|
|
3
3
|
"versions": {
|
|
4
4
|
"@animate-ui/react": "^2.4.2",
|
|
5
5
|
"@base-ui/react": "^1.9.0",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"input-group",
|
|
77
77
|
"form-field",
|
|
78
78
|
"dialog",
|
|
79
|
+
"alert-dialog",
|
|
79
80
|
"command",
|
|
80
81
|
"calendar",
|
|
81
82
|
"date-picker",
|
|
@@ -91,6 +92,8 @@
|
|
|
91
92
|
"breadcrumb",
|
|
92
93
|
"status-bar",
|
|
93
94
|
"side-panel",
|
|
95
|
+
"sidebar",
|
|
96
|
+
"drawer",
|
|
94
97
|
"prose",
|
|
95
98
|
"gallery",
|
|
96
99
|
"resize-handle",
|
|
@@ -302,6 +305,18 @@
|
|
|
302
305
|
"libs": [],
|
|
303
306
|
"uses": []
|
|
304
307
|
},
|
|
308
|
+
"alert-dialog": {
|
|
309
|
+
"dir": "nm-alert-dialog",
|
|
310
|
+
"files": [
|
|
311
|
+
"components/nm-alert-dialog/nm-alert-dialog.css",
|
|
312
|
+
"components/nm-alert-dialog/nm-alert-dialog.tsx",
|
|
313
|
+
"lib/nm-class.ts"
|
|
314
|
+
],
|
|
315
|
+
"libs": [
|
|
316
|
+
"@base-ui/react"
|
|
317
|
+
],
|
|
318
|
+
"uses": []
|
|
319
|
+
},
|
|
305
320
|
"app-panel": {
|
|
306
321
|
"dir": "nm-app-panel",
|
|
307
322
|
"files": [
|
|
@@ -2502,6 +2517,21 @@
|
|
|
2502
2517
|
],
|
|
2503
2518
|
"uses": []
|
|
2504
2519
|
},
|
|
2520
|
+
"drawer": {
|
|
2521
|
+
"dir": "nm-drawer",
|
|
2522
|
+
"files": [
|
|
2523
|
+
"components/nm-drawer/nm-drawer.css",
|
|
2524
|
+
"components/nm-drawer/nm-drawer.tsx",
|
|
2525
|
+
"config/nm-drawer.ts",
|
|
2526
|
+
"lib/nm-class.ts",
|
|
2527
|
+
"lib/nm-motion.ts"
|
|
2528
|
+
],
|
|
2529
|
+
"libs": [
|
|
2530
|
+
"@animate-ui/react",
|
|
2531
|
+
"@base-ui/react"
|
|
2532
|
+
],
|
|
2533
|
+
"uses": []
|
|
2534
|
+
},
|
|
2505
2535
|
"dropdown": {
|
|
2506
2536
|
"dir": "nm-dropdown",
|
|
2507
2537
|
"files": [
|
|
@@ -4960,6 +4990,187 @@
|
|
|
4960
4990
|
"toolbar"
|
|
4961
4991
|
]
|
|
4962
4992
|
},
|
|
4993
|
+
"sidebar": {
|
|
4994
|
+
"dir": "nm-sidebar",
|
|
4995
|
+
"files": [
|
|
4996
|
+
"components/nm-chip/nm-chip.css",
|
|
4997
|
+
"components/nm-chip/nm-chip.tsx",
|
|
4998
|
+
"components/nm-drawer/nm-drawer.css",
|
|
4999
|
+
"components/nm-drawer/nm-drawer.tsx",
|
|
5000
|
+
"components/nm-icon/animated/activity.tsx",
|
|
5001
|
+
"components/nm-icon/animated/archive.tsx",
|
|
5002
|
+
"components/nm-icon/animated/arrow-down.tsx",
|
|
5003
|
+
"components/nm-icon/animated/arrow-left.tsx",
|
|
5004
|
+
"components/nm-icon/animated/arrow-right.tsx",
|
|
5005
|
+
"components/nm-icon/animated/arrow-up-down.tsx",
|
|
5006
|
+
"components/nm-icon/animated/arrow-up.tsx",
|
|
5007
|
+
"components/nm-icon/animated/audio-lines.tsx",
|
|
5008
|
+
"components/nm-icon/animated/bookmark-plus.tsx",
|
|
5009
|
+
"components/nm-icon/animated/bookmark.tsx",
|
|
5010
|
+
"components/nm-icon/animated/bot.tsx",
|
|
5011
|
+
"components/nm-icon/animated/calendar-days.tsx",
|
|
5012
|
+
"components/nm-icon/animated/calendar.tsx",
|
|
5013
|
+
"components/nm-icon/animated/camera.tsx",
|
|
5014
|
+
"components/nm-icon/animated/chart-column-increasing.tsx",
|
|
5015
|
+
"components/nm-icon/animated/chart-column.tsx",
|
|
5016
|
+
"components/nm-icon/animated/chart-line.tsx",
|
|
5017
|
+
"components/nm-icon/animated/check-check.tsx",
|
|
5018
|
+
"components/nm-icon/animated/check.tsx",
|
|
5019
|
+
"components/nm-icon/animated/chevron-down.tsx",
|
|
5020
|
+
"components/nm-icon/animated/chevron-left.tsx",
|
|
5021
|
+
"components/nm-icon/animated/chevron-right.tsx",
|
|
5022
|
+
"components/nm-icon/animated/chevron-up.tsx",
|
|
5023
|
+
"components/nm-icon/animated/circle-alert.tsx",
|
|
5024
|
+
"components/nm-icon/animated/circle-check-big.tsx",
|
|
5025
|
+
"components/nm-icon/animated/circle-check.tsx",
|
|
5026
|
+
"components/nm-icon/animated/circle-plus.tsx",
|
|
5027
|
+
"components/nm-icon/animated/circle-question-mark.tsx",
|
|
5028
|
+
"components/nm-icon/animated/circle-x.tsx",
|
|
5029
|
+
"components/nm-icon/animated/clock-3.tsx",
|
|
5030
|
+
"components/nm-icon/animated/clock-4.tsx",
|
|
5031
|
+
"components/nm-icon/animated/clock.tsx",
|
|
5032
|
+
"components/nm-icon/animated/cloud-sun.tsx",
|
|
5033
|
+
"components/nm-icon/animated/cloud-upload.tsx",
|
|
5034
|
+
"components/nm-icon/animated/copy.tsx",
|
|
5035
|
+
"components/nm-icon/animated/download.tsx",
|
|
5036
|
+
"components/nm-icon/animated/ellipsis.tsx",
|
|
5037
|
+
"components/nm-icon/animated/external-link.tsx",
|
|
5038
|
+
"components/nm-icon/animated/eye-off.tsx",
|
|
5039
|
+
"components/nm-icon/animated/eye.tsx",
|
|
5040
|
+
"components/nm-icon/animated/fast-forward.tsx",
|
|
5041
|
+
"components/nm-icon/animated/file-clock.tsx",
|
|
5042
|
+
"components/nm-icon/animated/file-text.tsx",
|
|
5043
|
+
"components/nm-icon/animated/file.tsx",
|
|
5044
|
+
"components/nm-icon/animated/folder.tsx",
|
|
5045
|
+
"components/nm-icon/animated/gauge.tsx",
|
|
5046
|
+
"components/nm-icon/animated/globe.tsx",
|
|
5047
|
+
"components/nm-icon/animated/graduation-cap.tsx",
|
|
5048
|
+
"components/nm-icon/animated/headphones.tsx",
|
|
5049
|
+
"components/nm-icon/animated/image.tsx",
|
|
5050
|
+
"components/nm-icon/animated/index.ts",
|
|
5051
|
+
"components/nm-icon/animated/info.tsx",
|
|
5052
|
+
"components/nm-icon/animated/key-round.tsx",
|
|
5053
|
+
"components/nm-icon/animated/layers.tsx",
|
|
5054
|
+
"components/nm-icon/animated/layout-dashboard.tsx",
|
|
5055
|
+
"components/nm-icon/animated/library-big.tsx",
|
|
5056
|
+
"components/nm-icon/animated/lightbulb.tsx",
|
|
5057
|
+
"components/nm-icon/animated/link.tsx",
|
|
5058
|
+
"components/nm-icon/animated/list-filter.tsx",
|
|
5059
|
+
"components/nm-icon/animated/list.tsx",
|
|
5060
|
+
"components/nm-icon/animated/loader-circle.tsx",
|
|
5061
|
+
"components/nm-icon/animated/lock.tsx",
|
|
5062
|
+
"components/nm-icon/animated/log-out.tsx",
|
|
5063
|
+
"components/nm-icon/animated/mail.tsx",
|
|
5064
|
+
"components/nm-icon/animated/map-pin.tsx",
|
|
5065
|
+
"components/nm-icon/animated/menu.tsx",
|
|
5066
|
+
"components/nm-icon/animated/message-circle-dashed.tsx",
|
|
5067
|
+
"components/nm-icon/animated/message-circle.tsx",
|
|
5068
|
+
"components/nm-icon/animated/message-square-plus.tsx",
|
|
5069
|
+
"components/nm-icon/animated/message-square-text.tsx",
|
|
5070
|
+
"components/nm-icon/animated/message-square.tsx",
|
|
5071
|
+
"components/nm-icon/animated/mic-off.tsx",
|
|
5072
|
+
"components/nm-icon/animated/mic.tsx",
|
|
5073
|
+
"components/nm-icon/animated/minimize.tsx",
|
|
5074
|
+
"components/nm-icon/animated/minus.tsx",
|
|
5075
|
+
"components/nm-icon/animated/moon.tsx",
|
|
5076
|
+
"components/nm-icon/animated/music.tsx",
|
|
5077
|
+
"components/nm-icon/animated/notebook-pen.tsx",
|
|
5078
|
+
"components/nm-icon/animated/panel-left.tsx",
|
|
5079
|
+
"components/nm-icon/animated/panel-right.tsx",
|
|
5080
|
+
"components/nm-icon/animated/paperclip.tsx",
|
|
5081
|
+
"components/nm-icon/animated/pause.tsx",
|
|
5082
|
+
"components/nm-icon/animated/pencil.tsx",
|
|
5083
|
+
"components/nm-icon/animated/pin-off.tsx",
|
|
5084
|
+
"components/nm-icon/animated/pin.tsx",
|
|
5085
|
+
"components/nm-icon/animated/plane-takeoff.tsx",
|
|
5086
|
+
"components/nm-icon/animated/play.tsx",
|
|
5087
|
+
"components/nm-icon/animated/plug-zap.tsx",
|
|
5088
|
+
"components/nm-icon/animated/plus.tsx",
|
|
5089
|
+
"components/nm-icon/animated/radio.tsx",
|
|
5090
|
+
"components/nm-icon/animated/refresh-cw.tsx",
|
|
5091
|
+
"components/nm-icon/animated/rocket.tsx",
|
|
5092
|
+
"components/nm-icon/animated/rotate-ccw.tsx",
|
|
5093
|
+
"components/nm-icon/animated/rotate-cw.tsx",
|
|
5094
|
+
"components/nm-icon/animated/save.tsx",
|
|
5095
|
+
"components/nm-icon/animated/search.tsx",
|
|
5096
|
+
"components/nm-icon/animated/send.tsx",
|
|
5097
|
+
"components/nm-icon/animated/settings.tsx",
|
|
5098
|
+
"components/nm-icon/animated/share-2.tsx",
|
|
5099
|
+
"components/nm-icon/animated/share.tsx",
|
|
5100
|
+
"components/nm-icon/animated/shield-check.tsx",
|
|
5101
|
+
"components/nm-icon/animated/shopping-bag.tsx",
|
|
5102
|
+
"components/nm-icon/animated/sliders-horizontal.tsx",
|
|
5103
|
+
"components/nm-icon/animated/sparkles.tsx",
|
|
5104
|
+
"components/nm-icon/animated/star.tsx",
|
|
5105
|
+
"components/nm-icon/animated/sun.tsx",
|
|
5106
|
+
"components/nm-icon/animated/terminal.tsx",
|
|
5107
|
+
"components/nm-icon/animated/trash-2.tsx",
|
|
5108
|
+
"components/nm-icon/animated/trash.tsx",
|
|
5109
|
+
"components/nm-icon/animated/trending-up.tsx",
|
|
5110
|
+
"components/nm-icon/animated/triangle-alert.tsx",
|
|
5111
|
+
"components/nm-icon/animated/trophy.tsx",
|
|
5112
|
+
"components/nm-icon/animated/type.tsx",
|
|
5113
|
+
"components/nm-icon/animated/upload.tsx",
|
|
5114
|
+
"components/nm-icon/animated/user-round.tsx",
|
|
5115
|
+
"components/nm-icon/animated/user.tsx",
|
|
5116
|
+
"components/nm-icon/animated/users-round.tsx",
|
|
5117
|
+
"components/nm-icon/animated/users.tsx",
|
|
5118
|
+
"components/nm-icon/animated/volume-2.tsx",
|
|
5119
|
+
"components/nm-icon/animated/wand-sparkles.tsx",
|
|
5120
|
+
"components/nm-icon/animated/x.tsx",
|
|
5121
|
+
"components/nm-icon/animated/zap.tsx",
|
|
5122
|
+
"components/nm-icon/animated/zoom-in.tsx",
|
|
5123
|
+
"components/nm-icon/animated/zoom-out.tsx",
|
|
5124
|
+
"components/nm-icon/nm-icon.css",
|
|
5125
|
+
"components/nm-icon/nm-icon.tsx",
|
|
5126
|
+
"components/nm-icon/nm-lucide-extended.tsx",
|
|
5127
|
+
"components/nm-icon/nm-lucide.tsx",
|
|
5128
|
+
"components/nm-input/nm-input.css",
|
|
5129
|
+
"components/nm-input/nm-input.tsx",
|
|
5130
|
+
"components/nm-kbd/nm-kbd.css",
|
|
5131
|
+
"components/nm-kbd/nm-kbd.tsx",
|
|
5132
|
+
"components/nm-separator/nm-separator.css",
|
|
5133
|
+
"components/nm-separator/nm-separator.tsx",
|
|
5134
|
+
"components/nm-sidebar/nm-sidebar.css",
|
|
5135
|
+
"components/nm-sidebar/nm-sidebar.tsx",
|
|
5136
|
+
"components/nm-skeleton/nm-skeleton.css",
|
|
5137
|
+
"components/nm-skeleton/nm-skeleton.tsx",
|
|
5138
|
+
"components/nm-small-icon-button/nm-small-icon-button.tsx",
|
|
5139
|
+
"components/nm-tooltip/nm-tooltip.css",
|
|
5140
|
+
"components/nm-tooltip/nm-tooltip.tsx",
|
|
5141
|
+
"components/nordman-icon-button/nordman-icon-button.css",
|
|
5142
|
+
"components/nordman-icon-button/nordman-icon-button.tsx",
|
|
5143
|
+
"config/nm-drawer.ts",
|
|
5144
|
+
"config/nm-icon-button.ts",
|
|
5145
|
+
"config/nm-icons-extended.ts",
|
|
5146
|
+
"config/nm-icons.ts",
|
|
5147
|
+
"config/nm-sidebar.ts",
|
|
5148
|
+
"config/nm-small-icon-button.ts",
|
|
5149
|
+
"config/nordman-chrome.ts",
|
|
5150
|
+
"kit-logger.ts",
|
|
5151
|
+
"lib/logger.ts",
|
|
5152
|
+
"lib/nm-class.ts",
|
|
5153
|
+
"lib/nm-motion.ts"
|
|
5154
|
+
],
|
|
5155
|
+
"libs": [
|
|
5156
|
+
"@animate-ui/react",
|
|
5157
|
+
"@base-ui/react",
|
|
5158
|
+
"lucide-react",
|
|
5159
|
+
"motion"
|
|
5160
|
+
],
|
|
5161
|
+
"uses": [
|
|
5162
|
+
"chip",
|
|
5163
|
+
"drawer",
|
|
5164
|
+
"icon",
|
|
5165
|
+
"input",
|
|
5166
|
+
"kbd",
|
|
5167
|
+
"separator",
|
|
5168
|
+
"skeleton",
|
|
5169
|
+
"small-icon-button",
|
|
5170
|
+
"tooltip",
|
|
5171
|
+
"nordman-icon-button"
|
|
5172
|
+
]
|
|
5173
|
+
},
|
|
4963
5174
|
"skeleton": {
|
|
4964
5175
|
"dir": "nm-skeleton",
|
|
4965
5176
|
"files": [
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog';
|
|
3
|
+
import { nmClass } from '../../lib/nm-class.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Base UI Alert Dialog, in the shadcn composition, styled by NIF tokens.
|
|
6
|
+
* A dialog that asks before something that cannot be undone. It does not close on a click outside, only from its actions or Escape.
|
|
7
|
+
*/
|
|
8
|
+
export function NmAlertDialog(props: AlertDialogPrimitive.Root.Props) {
|
|
9
|
+
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
export function NmAlertDialogTrigger(props: AlertDialogPrimitive.Trigger.Props) {
|
|
12
|
+
return <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
export function NmAlertDialogContent({ className, children, ...props }: AlertDialogPrimitive.Popup.Props) {
|
|
15
|
+
return (
|
|
16
|
+
<AlertDialogPrimitive.Portal>
|
|
17
|
+
<AlertDialogPrimitive.Backdrop data-slot="alert-dialog-overlay" className="nm-dialog__backdrop" />
|
|
18
|
+
<AlertDialogPrimitive.Popup data-slot="alert-dialog-content" className={nmClass('nm-dialog nm-alert-dialog', className as string)} {...props}>
|
|
19
|
+
{children}
|
|
20
|
+
</AlertDialogPrimitive.Popup>
|
|
21
|
+
</AlertDialogPrimitive.Portal>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
export function NmAlertDialogHeader({ className, ...props }: ComponentProps<'div'>) {
|
|
25
|
+
return <div data-slot="alert-dialog-header" className={nmClass('nm-dialog__header', className)} {...props} />;
|
|
26
|
+
}
|
|
27
|
+
export function NmAlertDialogFooter({ className, ...props }: ComponentProps<'div'>) {
|
|
28
|
+
return <div data-slot="alert-dialog-footer" className={nmClass('nm-dialog__footer', className)} {...props} />;
|
|
29
|
+
}
|
|
30
|
+
export function NmAlertDialogTitle({ className, ...props }: AlertDialogPrimitive.Title.Props) {
|
|
31
|
+
return <AlertDialogPrimitive.Title data-slot="alert-dialog-title" className={nmClass('nm-dialog__title', className as string)} {...props} />;
|
|
32
|
+
}
|
|
33
|
+
export function NmAlertDialogDescription({ className, ...props }: AlertDialogPrimitive.Description.Props) {
|
|
34
|
+
return <AlertDialogPrimitive.Description data-slot="alert-dialog-description" className={nmClass('nm-dialog__description', className as string)} {...props} />;
|
|
35
|
+
}
|
|
36
|
+
/** The action that confirms. Give it a NIF Button with `render`; `tone="danger"` when it destroys. */
|
|
37
|
+
export function NmAlertDialogAction(props: AlertDialogPrimitive.Close.Props) {
|
|
38
|
+
return <AlertDialogPrimitive.Close data-slot="alert-dialog-action" {...props} />;
|
|
39
|
+
}
|
|
40
|
+
/** The action that cancels. Give it a NIF Button with `render`. */
|
|
41
|
+
export function NmAlertDialogCancel(props: AlertDialogPrimitive.Close.Props) {
|
|
42
|
+
return <AlertDialogPrimitive.Close data-slot="alert-dialog-cancel" {...props} />;
|
|
43
|
+
}
|
|
@@ -56,6 +56,21 @@
|
|
|
56
56
|
color: var(--nm-fg-muted);
|
|
57
57
|
font-size: var(--nm-type-ui-sm);
|
|
58
58
|
}
|
|
59
|
+
.nm-dialog__body {
|
|
60
|
+
display: flex;
|
|
61
|
+
flex-direction: column;
|
|
62
|
+
gap: var(--nm-space-12);
|
|
63
|
+
min-height: 0;
|
|
64
|
+
padding: var(--nm-space-16) var(--nm-space-24) 0;
|
|
65
|
+
overflow: auto;
|
|
66
|
+
}
|
|
67
|
+
.nm-dialog__footer {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-wrap: wrap;
|
|
70
|
+
gap: var(--nm-space-8);
|
|
71
|
+
justify-content: flex-end;
|
|
72
|
+
padding: var(--nm-space-24);
|
|
73
|
+
}
|
|
59
74
|
|
|
60
75
|
.nm-dialog[data-size='full'] {
|
|
61
76
|
inset: 0;
|
|
@@ -31,6 +31,14 @@ export function NmDialogHeader({ className, ...props }: ComponentProps<'div'>) {
|
|
|
31
31
|
return <div data-slot="dialog-header" className={nmClass('nm-dialog__header', className)} {...props} />;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/** The content between the header and the footer. It scrolls when the dialog is full. */
|
|
35
|
+
export function NmDialogBody({ className, ...props }: ComponentProps<'div'>) {
|
|
36
|
+
return <div data-slot="dialog-body" className={nmClass('nm-dialog__body', className)} {...props} />;
|
|
37
|
+
}
|
|
38
|
+
/** The actions at the end, right-aligned. */
|
|
39
|
+
export function NmDialogFooter({ className, ...props }: ComponentProps<'div'>) {
|
|
40
|
+
return <div data-slot="dialog-footer" className={nmClass('nm-dialog__footer', className)} {...props} />;
|
|
41
|
+
}
|
|
34
42
|
export function NmDialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
35
43
|
return <DialogPrimitive.Title data-slot="dialog-title" className={nmClass('nm-dialog__title', className as string)} {...props} />;
|
|
36
44
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
.nm-drawer__backdrop {
|
|
2
|
+
position: fixed;
|
|
3
|
+
z-index: var(--nm-menu-z);
|
|
4
|
+
inset: 0;
|
|
5
|
+
background: rgb(var(--nm-canvas-rgb) / 0.7);
|
|
6
|
+
transition: opacity var(--reveal) var(--ease);
|
|
7
|
+
}
|
|
8
|
+
.nm-drawer__backdrop[data-starting-style],
|
|
9
|
+
.nm-drawer__backdrop[data-ending-style] {
|
|
10
|
+
opacity: 0;
|
|
11
|
+
}
|
|
12
|
+
/* The panel sits on an edge and takes the whole height. It slides in from its own edge. */
|
|
13
|
+
.nm-drawer {
|
|
14
|
+
position: fixed;
|
|
15
|
+
z-index: var(--nm-menu-z);
|
|
16
|
+
inset-block: 0;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
box-sizing: border-box;
|
|
20
|
+
width: var(--nm-width-drawer);
|
|
21
|
+
max-width: 100%;
|
|
22
|
+
background: var(--nm-raised);
|
|
23
|
+
color: var(--nm-fg);
|
|
24
|
+
font-family: var(--nm-font);
|
|
25
|
+
font-size: var(--nm-type-ui);
|
|
26
|
+
outline: none;
|
|
27
|
+
/* The motion popup owns transform: it slides the panel in from its side. */
|
|
28
|
+
transition: opacity var(--reveal) var(--ease);
|
|
29
|
+
}
|
|
30
|
+
.nm-drawer[data-side='left'] {
|
|
31
|
+
inset-inline-start: 0;
|
|
32
|
+
border-inline-end: var(--nm-rule) solid var(--nm-line-strong);
|
|
33
|
+
}
|
|
34
|
+
.nm-drawer[data-side='right'] {
|
|
35
|
+
inset-inline-end: 0;
|
|
36
|
+
border-inline-start: var(--nm-rule) solid var(--nm-line-strong);
|
|
37
|
+
}
|
|
38
|
+
.nm-drawer[data-starting-style],
|
|
39
|
+
.nm-drawer[data-ending-style] {
|
|
40
|
+
opacity: 0;
|
|
41
|
+
}
|
|
42
|
+
.nm-drawer__header {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: column;
|
|
45
|
+
gap: var(--nm-space-4);
|
|
46
|
+
padding: var(--nm-space-16);
|
|
47
|
+
}
|
|
48
|
+
.nm-drawer__footer {
|
|
49
|
+
display: flex;
|
|
50
|
+
gap: var(--nm-space-8);
|
|
51
|
+
justify-content: flex-end;
|
|
52
|
+
margin-top: auto;
|
|
53
|
+
padding: var(--nm-space-16);
|
|
54
|
+
}
|
|
55
|
+
.nm-drawer__title {
|
|
56
|
+
margin: 0;
|
|
57
|
+
font-size: var(--nm-type-body);
|
|
58
|
+
font-weight: var(--nm-weight-medium);
|
|
59
|
+
}
|
|
60
|
+
.nm-drawer__description {
|
|
61
|
+
margin: 0;
|
|
62
|
+
color: var(--nm-fg-muted);
|
|
63
|
+
font-size: var(--nm-type-ui-sm);
|
|
64
|
+
}
|
|
65
|
+
@media (prefers-reduced-motion: reduce) {
|
|
66
|
+
.nm-drawer,
|
|
67
|
+
.nm-drawer__backdrop {
|
|
68
|
+
transition: none;
|
|
69
|
+
}
|
|
70
|
+
}
|