@nordmanai/nif 0.2.12 → 0.2.14
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 +1 -0
- package/dist/index.js +2768 -2710
- package/dist/styles.css +1 -1
- package/dist/ui/components/nm-button/nm-button.d.ts +3 -0
- package/dist/ui/components/nm-composer/nm-composer.d.ts +3 -0
- package/dist/ui/components/nm-dropdown/nm-dropdown-item.d.ts +2 -0
- package/dist/ui/components/nm-dropdown/nm-dropdown.d.ts +4 -1
- package/dist/ui/components/nm-dropdown-menu/nm-dropdown-menu.d.ts +3 -2
- package/dist/ui/components/nm-sidebar/nm-sidebar.d.ts +15 -0
- package/dist/ui/components/nm-small-icon-button/nm-small-icon-button.d.ts +5 -0
- package/dist/ui/components/nordman-icon-button/nordman-icon-button.d.ts +3 -0
- package/dist/ui/config/nm-button.d.ts +1 -0
- package/dist/ui/config/nm-composer.d.ts +2 -4
- package/dist/ui/config/nm-dropdown.d.ts +7 -0
- package/dist/ui/config/nm-icon-button.d.ts +4 -2
- package/dist/ui/config/nm-shape.d.ts +11 -0
- package/package.json +1 -1
- package/registry/index.json +34 -1
- package/registry/ui/components/nm-button/nm-button.css +3 -0
- package/registry/ui/components/nm-button/nm-button.tsx +5 -1
- package/registry/ui/components/nm-composer/nm-composer.css +9 -2
- package/registry/ui/components/nm-composer/nm-composer.tsx +6 -1
- package/registry/ui/components/nm-dropdown/nm-dropdown-item.ts +2 -0
- package/registry/ui/components/nm-dropdown/nm-dropdown.tsx +6 -2
- package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.css +11 -0
- package/registry/ui/components/nm-dropdown-menu/nm-dropdown-menu.tsx +13 -3
- package/registry/ui/components/nm-sidebar/nm-sidebar.css +35 -0
- package/registry/ui/components/nm-sidebar/nm-sidebar.tsx +38 -0
- package/registry/ui/components/nm-small-icon-button/nm-small-icon-button.tsx +5 -0
- package/registry/ui/components/nordman-icon-button/nordman-icon-button.css +3 -0
- package/registry/ui/components/nordman-icon-button/nordman-icon-button.tsx +7 -1
- package/registry/ui/config/nm-button.ts +1 -0
- package/registry/ui/config/nm-composer.ts +3 -0
- package/registry/ui/config/nm-dropdown.ts +7 -0
- package/registry/ui/config/nm-icon-button.ts +11 -5
- package/registry/ui/config/nm-shape.ts +11 -0
- package/registry/ui/styles/tokens.css +2 -0
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';
|
|
2
2
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
3
3
|
import { NM_BUTTON_SIZES, NM_BUTTON_TONES, type NmButtonSize, type NmButtonTone } from '../../config/nm-button.ts';
|
|
4
|
+
import { type NmControlShape } from '../../config/nm-shape.ts';
|
|
4
5
|
export type NmButtonProps = {
|
|
5
6
|
label: string;
|
|
6
7
|
/** Content of the button in place of the icon and label, for a button that holds more than text. The label is still its accessible name when icon only. */
|
|
7
8
|
children?: ReactNode;
|
|
8
9
|
tone: NmButtonTone;
|
|
9
10
|
size?: NmButtonSize;
|
|
11
|
+
/** Soft follows the themed radius; round is a pill. */
|
|
12
|
+
shape?: NmControlShape;
|
|
10
13
|
block?: boolean;
|
|
11
14
|
type?: 'button' | 'submit';
|
|
12
15
|
disabled?: boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode, type Ref, type TextareaHTMLAttributes } from 'react';
|
|
2
2
|
import { type NmComposerAttachment, type NmComposerQueued } from '../../config/nm-composer.ts';
|
|
3
|
+
import type { NmControlShape } from '../../config/nm-shape.ts';
|
|
3
4
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
4
5
|
import type { OrbAdapter } from 'orb-ui';
|
|
5
6
|
import type { NmVoiceOrbAgentState } from '../../config/nm-voice-orb.ts';
|
|
@@ -72,5 +73,7 @@ export type NmComposerProps = {
|
|
|
72
73
|
formless?: boolean;
|
|
73
74
|
/** The host owns the text: the field is not controlled by `value`, and `value` only says whether there is any. */
|
|
74
75
|
uncontrolled?: boolean;
|
|
76
|
+
/** Shape of every button in the bar, own and hosted. Round makes them circles. */
|
|
77
|
+
buttonShape?: NmControlShape;
|
|
75
78
|
};
|
|
76
79
|
export declare function NmComposer(props: NmComposerProps): ReactNode;
|
|
@@ -13,6 +13,8 @@ export type NmDropdownItem = {
|
|
|
13
13
|
danger?: boolean;
|
|
14
14
|
disabled?: boolean;
|
|
15
15
|
checked?: boolean;
|
|
16
|
+
/** The row that is the current choice in a list of alternatives. Shown by fill, not by a mark; for a toggle use `checked`. */
|
|
17
|
+
current?: boolean;
|
|
16
18
|
/** Publish row state. The row stays inactive while busy or live. */
|
|
17
19
|
mark?: 'idle' | 'busy' | 'live';
|
|
18
20
|
children?: readonly NmDropdownItem[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ReactNode, type Ref } from 'react';
|
|
2
2
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
3
|
-
import { NM_DROPDOWN_ALIGN, NM_DROPDOWN_REVEAL, NM_DROPDOWN_TONE, NM_DROPDOWN_TRIGGER } from '../../config/nm-dropdown.ts';
|
|
3
|
+
import { NM_DROPDOWN_ALIGN, NM_DROPDOWN_REVEAL, NM_DROPDOWN_SIDE, NM_DROPDOWN_TONE, NM_DROPDOWN_TRIGGER } from '../../config/nm-dropdown.ts';
|
|
4
4
|
import type { NmDropdownItem } from './nm-dropdown-item';
|
|
5
5
|
export type { NmDropdownItem };
|
|
6
6
|
export type NmDropdownProps = {
|
|
@@ -11,6 +11,7 @@ export type NmDropdownProps = {
|
|
|
11
11
|
trigger?: (typeof NM_DROPDOWN_TRIGGER)[keyof typeof NM_DROPDOWN_TRIGGER];
|
|
12
12
|
tone?: (typeof NM_DROPDOWN_TONE)[keyof typeof NM_DROPDOWN_TONE];
|
|
13
13
|
align?: (typeof NM_DROPDOWN_ALIGN)[keyof typeof NM_DROPDOWN_ALIGN];
|
|
14
|
+
side?: (typeof NM_DROPDOWN_SIDE)[keyof typeof NM_DROPDOWN_SIDE];
|
|
14
15
|
icon?: NmIconId;
|
|
15
16
|
imageSrc?: string;
|
|
16
17
|
displayLabel?: string;
|
|
@@ -22,6 +23,8 @@ export type NmDropdownProps = {
|
|
|
22
23
|
/** `hover` hides the trigger until the host with `data-nm-menu` is hovered or focused. */
|
|
23
24
|
reveal?: (typeof NM_DROPDOWN_REVEAL)[keyof typeof NM_DROPDOWN_REVEAL];
|
|
24
25
|
open?: boolean;
|
|
26
|
+
/** Opens when the trigger is hovered, as well as on click. */
|
|
27
|
+
openOnHover?: boolean;
|
|
25
28
|
triggerClassName?: string;
|
|
26
29
|
triggerRef?: Ref<HTMLButtonElement>;
|
|
27
30
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -2,7 +2,8 @@ import { type ComponentProps } from 'react';
|
|
|
2
2
|
import { Menu as MenuPrimitive } from '../../lib/nm-motion.ts';
|
|
3
3
|
import type { NmDropdownItem } from '../nm-dropdown/nm-dropdown-item.ts';
|
|
4
4
|
/** Base UI Menu, in the shadcn dropdown-menu composition, styled by NIF tokens. */
|
|
5
|
-
export
|
|
5
|
+
export type NmDropdownMenuProps = MenuPrimitive.Root.Props;
|
|
6
|
+
export declare function NmDropdownMenu(props: NmDropdownMenuProps): import("react").JSX.Element;
|
|
6
7
|
export declare function NmDropdownMenuTrigger(props: MenuPrimitive.Trigger.Props): import("react").JSX.Element;
|
|
7
8
|
type PositionProps = Pick<MenuPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>;
|
|
8
9
|
export declare function NmDropdownMenuContent({ align, alignOffset, side, sideOffset, className, ...props }: MenuPrimitive.Popup.Props & PositionProps): import("react").JSX.Element;
|
|
@@ -29,7 +30,7 @@ export declare function NmDropdownMenuText({ title, description }: {
|
|
|
29
30
|
export declare function NmDropdownMenuDot({ status }: {
|
|
30
31
|
status?: 'ok' | 'error';
|
|
31
32
|
}): import("react").JSX.Element;
|
|
32
|
-
/** A list of NmDropdownItem as animated menu rows: branches become submenus, `checked` rows keep a mark. */
|
|
33
|
+
/** A list of NmDropdownItem as animated menu rows: branches become submenus, `checked` rows keep a mark, the `current` row (or the `selected` id) is filled. */
|
|
33
34
|
export declare function NmDropdownMenuItems({ items, selected, onSelect, onBranchExpand, }: {
|
|
34
35
|
items: readonly NmDropdownItem[];
|
|
35
36
|
selected?: string | null;
|
|
@@ -2,6 +2,7 @@ import { type ComponentProps, type ReactElement, type ReactNode } from 'react';
|
|
|
2
2
|
import { type NmSidebarButtonSize, type NmSidebarButtonVariant, type NmSidebarCollapsible, type NmSidebarSide, type NmSidebarState, type NmSidebarVariant } from '../../config/nm-sidebar.ts';
|
|
3
3
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
4
4
|
import { NmChip } from '../nm-chip/nm-chip.tsx';
|
|
5
|
+
import { type NmDropdownMenuProps } from '../nm-dropdown-menu/nm-dropdown-menu.tsx';
|
|
5
6
|
import { NmIcon } from '../nm-icon/nm-icon.tsx';
|
|
6
7
|
import { NmInput } from '../nm-input/nm-input.tsx';
|
|
7
8
|
import { NmSeparator } from '../nm-separator/nm-separator.tsx';
|
|
@@ -30,6 +31,8 @@ type SidebarContextValue = {
|
|
|
30
31
|
setCollapsible: (mode: NmSidebarCollapsible) => void;
|
|
31
32
|
};
|
|
32
33
|
/** The sidebar's state: expanded or collapsed, peeking, on a desktop or a phone, and the function that toggles it. */
|
|
34
|
+
/** Whether the sidebar is in view: open or peeking on a desktop, the drawer open on a phone. */
|
|
35
|
+
export declare function useSidebarVisible(): boolean;
|
|
33
36
|
/** The sidebar context when there is one. For a part that lives in a bar shared by pages with and without a sidebar. */
|
|
34
37
|
export declare function useOptionalSidebar(): SidebarContextValue | null;
|
|
35
38
|
export declare function useSidebar(): SidebarContextValue;
|
|
@@ -112,6 +115,12 @@ export declare function NmSidebarMenuButton({ render, isActive, variant, size, t
|
|
|
112
115
|
export declare function NmSidebarMenuAction({ className, showOnHover, ...props }: ComponentProps<typeof NmSmallIconButton> & {
|
|
113
116
|
showOnHover?: boolean;
|
|
114
117
|
}): ReactNode;
|
|
118
|
+
/** Several actions at the end of a row, such as new and more. They reveal together when `showOnHover`. */
|
|
119
|
+
export declare function NmSidebarMenuActions({ className, showOnHover, ...props }: ComponentProps<'div'> & {
|
|
120
|
+
showOnHover?: boolean;
|
|
121
|
+
}): ReactNode;
|
|
122
|
+
/** A row of controls in the header or footer, such as a primary button and an icon button, spaced apart. */
|
|
123
|
+
export declare function NmSidebarBar({ className, ...props }: ComponentProps<'div'>): ReactNode;
|
|
115
124
|
/** A count or a short word at the end of a row. The NIF Chip, small. */
|
|
116
125
|
export declare function NmSidebarMenuBadge({ className, ...props }: ComponentProps<typeof NmChip>): ReactNode;
|
|
117
126
|
/** Two lines in a row, such as a name and a plan in the footer. For a large menu button. */
|
|
@@ -137,4 +146,10 @@ export declare function NmSidebarMenuSubButton({ render, size, isActive, disable
|
|
|
137
146
|
export declare function NmSidebarChevron({ className, menu, ...props }: Omit<ComponentProps<typeof NmIcon>, 'id'> & {
|
|
138
147
|
menu?: boolean;
|
|
139
148
|
}): ReactNode;
|
|
149
|
+
/**
|
|
150
|
+
* A dropdown menu opened from the sidebar. It closes the moment the sidebar goes out of view
|
|
151
|
+
* (collapsed, a peek that ended, the drawer closed), so no menu outlives the panel it came from.
|
|
152
|
+
* While it is open the pointer may rest on it without ending a peek.
|
|
153
|
+
*/
|
|
154
|
+
export declare function NmSidebarDropdownMenu({ open: openProp, onOpenChange, ...props }: NmDropdownMenuProps): import("react").JSX.Element;
|
|
140
155
|
export {};
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { type ButtonHTMLAttributes, type MouseEvent, type ReactNode } from 'react';
|
|
2
2
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
3
3
|
import { type NmSmallIconButtonTone } from '../../config/nm-small-icon-button.ts';
|
|
4
|
+
import type { NmControlShape } from '../../config/nm-shape.ts';
|
|
4
5
|
export type NmSmallIconButtonProps = {
|
|
5
6
|
label: string;
|
|
6
7
|
icon: NmIconId;
|
|
7
8
|
tone?: NmSmallIconButtonTone;
|
|
9
|
+
/** Soft follows the themed radius; round is a full circle. */
|
|
10
|
+
shape?: NmControlShape;
|
|
8
11
|
active?: boolean;
|
|
9
12
|
iconContent?: ReactNode;
|
|
10
13
|
testId?: string;
|
|
@@ -14,6 +17,8 @@ export declare const NmSmallIconButton: import("react").ForwardRefExoticComponen
|
|
|
14
17
|
label: string;
|
|
15
18
|
icon: NmIconId;
|
|
16
19
|
tone?: NmSmallIconButtonTone;
|
|
20
|
+
/** Soft follows the themed radius; round is a full circle. */
|
|
21
|
+
shape?: NmControlShape;
|
|
17
22
|
active?: boolean;
|
|
18
23
|
iconContent?: ReactNode;
|
|
19
24
|
testId?: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
3
|
+
import { type NmControlShape } from '../../config/nm-shape.ts';
|
|
3
4
|
import { NM_ICON_BUTTON_TONES, type NmIconButtonTone } from '../../config/nm-icon-button.ts';
|
|
4
5
|
import { type NordmanChromeIconId } from '../../config/nordman-chrome.ts';
|
|
5
6
|
export declare const NORDMAN_ICON_BUTTON_VARIANTS: {
|
|
@@ -11,6 +12,8 @@ export declare const NordmanIconButton: import("react").ForwardRefExoticComponen
|
|
|
11
12
|
label: string;
|
|
12
13
|
href?: string;
|
|
13
14
|
tone?: NmIconButtonTone;
|
|
15
|
+
/** Soft follows the themed radius; round is a full circle. */
|
|
16
|
+
shape?: NmControlShape;
|
|
14
17
|
variant?: NordmanIconButtonVariant;
|
|
15
18
|
testId?: string;
|
|
16
19
|
imageSrc?: string;
|
|
@@ -32,6 +32,7 @@ export declare const NM_BUTTON_CLASSES: {
|
|
|
32
32
|
readonly large: 'nm-button--large';
|
|
33
33
|
readonly block: 'nm-button--block';
|
|
34
34
|
readonly icon: 'nm-button--icon';
|
|
35
|
+
readonly round: 'nm-button--round';
|
|
35
36
|
};
|
|
36
37
|
/** The button's class names, for triggers that must stay a Base UI part, such as a menu or popover trigger. */
|
|
37
38
|
export declare function nmButtonClassName(tone: NmButtonTone, size?: NmButtonSize, iconOnly?: boolean): string;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composer: the message box. Built from the Nordman AI design:
|
|
3
|
-
* one framed box, the text on top, actions in a row beneath. Add on the left, dictate and voice on the right.
|
|
4
|
-
*/
|
|
5
1
|
export declare const NM_COMPOSER_COPY: {
|
|
6
2
|
readonly placeholder: 'Ask Nordman';
|
|
7
3
|
readonly attach: 'Add';
|
|
@@ -42,6 +38,8 @@ export declare const NM_COMPOSER_CLASSES: {
|
|
|
42
38
|
readonly primary: 'nm-composer__button--primary';
|
|
43
39
|
readonly stopMark: 'nm-composer__stop-mark';
|
|
44
40
|
};
|
|
41
|
+
/** Set on the root with a shape value; every button in the bar, own or hosted, takes that shape. */
|
|
42
|
+
export declare const NM_COMPOSER_SHAPE_ATTRIBUTE = "data-button-shape";
|
|
45
43
|
export type NmComposerAttachment = {
|
|
46
44
|
id: string;
|
|
47
45
|
name: string;
|
|
@@ -47,6 +47,13 @@ export declare const NM_DROPDOWN_ALIGN: {
|
|
|
47
47
|
/** Match the hosting `.nm-rail__row` pill width and left edge. */
|
|
48
48
|
readonly row: 'row';
|
|
49
49
|
};
|
|
50
|
+
/** Which side of the trigger the menu opens on. `right` for a menu that must not cover a side panel's rows. */
|
|
51
|
+
export declare const NM_DROPDOWN_SIDE: {
|
|
52
|
+
readonly bottom: 'bottom';
|
|
53
|
+
readonly top: 'top';
|
|
54
|
+
readonly right: 'right';
|
|
55
|
+
readonly left: 'left';
|
|
56
|
+
};
|
|
50
57
|
/** Icon menus stay hidden until the host row or field is hovered or focused. */
|
|
51
58
|
export declare const NM_DROPDOWN_REVEAL: {
|
|
52
59
|
readonly hover: 'hover';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type NmControlShape } from './nm-shape.ts';
|
|
1
2
|
export declare const NM_ICON_BUTTON_TONES: {
|
|
2
3
|
readonly line: 'line';
|
|
3
4
|
readonly raised: 'raised';
|
|
@@ -17,8 +18,9 @@ export declare const NM_ICON_BUTTON_CLASSES: {
|
|
|
17
18
|
readonly solid: 'nm-icon-button--solid';
|
|
18
19
|
readonly panel: 'nm-icon-button--panel';
|
|
19
20
|
readonly invert: 'nm-icon-button--invert';
|
|
21
|
+
readonly round: 'nm-icon-button--round';
|
|
20
22
|
};
|
|
21
23
|
/** Shared geometry hook for send / stop / during-run primary composer actions. */
|
|
22
24
|
export declare const NM_CHATBOX_ACTION_CLASS = "nm-chatbox__send";
|
|
23
|
-
export declare function nmIconButtonClassName(tone?: NmIconButtonTone): string;
|
|
24
|
-
export declare function nmChatboxActionButtonClassName(): string;
|
|
25
|
+
export declare function nmIconButtonClassName(tone?: NmIconButtonTone, shape?: NmControlShape): string;
|
|
26
|
+
export declare function nmChatboxActionButtonClassName(shape?: NmControlShape): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control shape. Soft is the kit default: corners follow the themed radius scale.
|
|
3
|
+
* Round is a full circle (or pill): it ignores the radius scale, a circle has no corner to scale.
|
|
4
|
+
*/
|
|
5
|
+
export declare const NM_CONTROL_SHAPES: {
|
|
6
|
+
readonly soft: 'soft';
|
|
7
|
+
readonly round: 'round';
|
|
8
|
+
};
|
|
9
|
+
export type NmControlShape = (typeof NM_CONTROL_SHAPES)[keyof typeof NM_CONTROL_SHAPES];
|
|
10
|
+
/** The data attribute a container sets to round every control inside it. */
|
|
11
|
+
export declare const NM_SHAPE_ATTRIBUTE = "data-button-shape";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nordmanai/nif",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.14",
|
|
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.13",
|
|
3
3
|
"versions": {
|
|
4
4
|
"@animate-ui/react": "^2.4.2",
|
|
5
5
|
"@base-ui/react": "^1.9.0",
|
|
@@ -268,6 +268,7 @@
|
|
|
268
268
|
"config/nm-icons-extended.ts",
|
|
269
269
|
"config/nm-icons.ts",
|
|
270
270
|
"config/nm-message.ts",
|
|
271
|
+
"config/nm-shape.ts",
|
|
271
272
|
"config/nordman-chrome.ts",
|
|
272
273
|
"kit-logger.ts",
|
|
273
274
|
"lib/logger.ts",
|
|
@@ -494,6 +495,7 @@
|
|
|
494
495
|
"config/nm-icon-button.ts",
|
|
495
496
|
"config/nm-icons-extended.ts",
|
|
496
497
|
"config/nm-icons.ts",
|
|
498
|
+
"config/nm-shape.ts",
|
|
497
499
|
"config/nordman-chrome.ts",
|
|
498
500
|
"kit-logger.ts",
|
|
499
501
|
"lib/bar-overflow.ts",
|
|
@@ -810,6 +812,7 @@
|
|
|
810
812
|
"config/nm-button.ts",
|
|
811
813
|
"config/nm-icons-extended.ts",
|
|
812
814
|
"config/nm-icons.ts",
|
|
815
|
+
"config/nm-shape.ts",
|
|
813
816
|
"kit-logger.ts",
|
|
814
817
|
"lib/logger.ts",
|
|
815
818
|
"lib/nm-motion.ts"
|
|
@@ -1137,6 +1140,7 @@
|
|
|
1137
1140
|
"config/nm-icon-button.ts",
|
|
1138
1141
|
"config/nm-icons-extended.ts",
|
|
1139
1142
|
"config/nm-icons.ts",
|
|
1143
|
+
"config/nm-shape.ts",
|
|
1140
1144
|
"kit-logger.ts",
|
|
1141
1145
|
"lib/logger.ts"
|
|
1142
1146
|
],
|
|
@@ -1590,6 +1594,7 @@
|
|
|
1590
1594
|
"config/nm-icon-button.ts",
|
|
1591
1595
|
"config/nm-icons-extended.ts",
|
|
1592
1596
|
"config/nm-icons.ts",
|
|
1597
|
+
"config/nm-shape.ts",
|
|
1593
1598
|
"config/nordman-chrome.ts",
|
|
1594
1599
|
"kit-logger.ts",
|
|
1595
1600
|
"lib/logger.ts",
|
|
@@ -1803,6 +1808,7 @@
|
|
|
1803
1808
|
"config/nm-icon-button.ts",
|
|
1804
1809
|
"config/nm-icons-extended.ts",
|
|
1805
1810
|
"config/nm-icons.ts",
|
|
1811
|
+
"config/nm-shape.ts",
|
|
1806
1812
|
"config/nm-side-panel.ts",
|
|
1807
1813
|
"config/nm-small-icon-button.ts",
|
|
1808
1814
|
"config/nordman-chrome.ts",
|
|
@@ -2311,6 +2317,7 @@
|
|
|
2311
2317
|
"config/nm-composer.ts",
|
|
2312
2318
|
"config/nm-icons-extended.ts",
|
|
2313
2319
|
"config/nm-icons.ts",
|
|
2320
|
+
"config/nm-shape.ts",
|
|
2314
2321
|
"config/nm-site-palette.ts",
|
|
2315
2322
|
"config/nm-voice-orb.ts",
|
|
2316
2323
|
"kit-logger.ts",
|
|
@@ -2677,6 +2684,7 @@
|
|
|
2677
2684
|
"config/nm-icon-button.ts",
|
|
2678
2685
|
"config/nm-icons-extended.ts",
|
|
2679
2686
|
"config/nm-icons.ts",
|
|
2687
|
+
"config/nm-shape.ts",
|
|
2680
2688
|
"config/nordman-chrome.ts",
|
|
2681
2689
|
"kit-logger.ts",
|
|
2682
2690
|
"lib/logger.ts",
|
|
@@ -3020,6 +3028,7 @@
|
|
|
3020
3028
|
"config/nm-icon-button.ts",
|
|
3021
3029
|
"config/nm-icons-extended.ts",
|
|
3022
3030
|
"config/nm-icons.ts",
|
|
3031
|
+
"config/nm-shape.ts",
|
|
3023
3032
|
"config/nm-side-panel.ts",
|
|
3024
3033
|
"config/nordman-chrome.ts",
|
|
3025
3034
|
"kit-logger.ts",
|
|
@@ -3371,6 +3380,7 @@
|
|
|
3371
3380
|
"config/nm-icon-button.ts",
|
|
3372
3381
|
"config/nm-icons-extended.ts",
|
|
3373
3382
|
"config/nm-icons.ts",
|
|
3383
|
+
"config/nm-shape.ts",
|
|
3374
3384
|
"config/nordman-chrome.ts",
|
|
3375
3385
|
"kit-logger.ts",
|
|
3376
3386
|
"lib/logger.ts",
|
|
@@ -3579,6 +3589,7 @@
|
|
|
3579
3589
|
"config/nm-icons-extended.ts",
|
|
3580
3590
|
"config/nm-icons.ts",
|
|
3581
3591
|
"config/nm-list-item.ts",
|
|
3592
|
+
"config/nm-shape.ts",
|
|
3582
3593
|
"config/nordman-chrome.ts",
|
|
3583
3594
|
"kit-logger.ts",
|
|
3584
3595
|
"lib/logger.ts",
|
|
@@ -3770,6 +3781,7 @@
|
|
|
3770
3781
|
"config/nm-icons-extended.ts",
|
|
3771
3782
|
"config/nm-icons.ts",
|
|
3772
3783
|
"config/nm-modal.ts",
|
|
3784
|
+
"config/nm-shape.ts",
|
|
3773
3785
|
"config/nordman-chrome.ts",
|
|
3774
3786
|
"content/nm-modal.ts",
|
|
3775
3787
|
"kit-logger.ts",
|
|
@@ -4086,6 +4098,7 @@
|
|
|
4086
4098
|
"config/nm-icons.ts",
|
|
4087
4099
|
"config/nm-panel-bar.ts",
|
|
4088
4100
|
"config/nm-segmented.ts",
|
|
4101
|
+
"config/nm-shape.ts",
|
|
4089
4102
|
"kit-logger.ts",
|
|
4090
4103
|
"lib/logger.ts"
|
|
4091
4104
|
],
|
|
@@ -4313,6 +4326,7 @@
|
|
|
4313
4326
|
"config/nm-icons-extended.ts",
|
|
4314
4327
|
"config/nm-icons.ts",
|
|
4315
4328
|
"config/nm-questionnaire.ts",
|
|
4329
|
+
"config/nm-shape.ts",
|
|
4316
4330
|
"config/nm-side-panel.ts",
|
|
4317
4331
|
"config/nordman-chrome.ts",
|
|
4318
4332
|
"kit-logger.ts",
|
|
@@ -4657,6 +4671,7 @@
|
|
|
4657
4671
|
"config/nm-icons-extended.ts",
|
|
4658
4672
|
"config/nm-icons.ts",
|
|
4659
4673
|
"config/nm-segmented.ts",
|
|
4674
|
+
"config/nm-shape.ts",
|
|
4660
4675
|
"kit-logger.ts",
|
|
4661
4676
|
"lib/logger.ts"
|
|
4662
4677
|
],
|
|
@@ -4972,6 +4987,7 @@
|
|
|
4972
4987
|
"config/nm-icon-button.ts",
|
|
4973
4988
|
"config/nm-icons-extended.ts",
|
|
4974
4989
|
"config/nm-icons.ts",
|
|
4990
|
+
"config/nm-shape.ts",
|
|
4975
4991
|
"config/nm-side-panel.ts",
|
|
4976
4992
|
"kit-logger.ts",
|
|
4977
4993
|
"lib/logger.ts",
|
|
@@ -4997,6 +5013,10 @@
|
|
|
4997
5013
|
"components/nm-chip/nm-chip.tsx",
|
|
4998
5014
|
"components/nm-drawer/nm-drawer.css",
|
|
4999
5015
|
"components/nm-drawer/nm-drawer.tsx",
|
|
5016
|
+
"components/nm-dropdown-menu/nm-dropdown-menu.css",
|
|
5017
|
+
"components/nm-dropdown-menu/nm-dropdown-menu.tsx",
|
|
5018
|
+
"components/nm-dropdown/nm-dropdown-item.ts",
|
|
5019
|
+
"components/nm-dropdown/nm-dropdown.css",
|
|
5000
5020
|
"components/nm-icon/animated/activity.tsx",
|
|
5001
5021
|
"components/nm-icon/animated/archive.tsx",
|
|
5002
5022
|
"components/nm-icon/animated/arrow-down.tsx",
|
|
@@ -5144,6 +5164,7 @@
|
|
|
5144
5164
|
"config/nm-icon-button.ts",
|
|
5145
5165
|
"config/nm-icons-extended.ts",
|
|
5146
5166
|
"config/nm-icons.ts",
|
|
5167
|
+
"config/nm-shape.ts",
|
|
5147
5168
|
"config/nm-sidebar.ts",
|
|
5148
5169
|
"config/nm-small-icon-button.ts",
|
|
5149
5170
|
"config/nordman-chrome.ts",
|
|
@@ -5161,6 +5182,8 @@
|
|
|
5161
5182
|
"uses": [
|
|
5162
5183
|
"chip",
|
|
5163
5184
|
"drawer",
|
|
5185
|
+
"dropdown",
|
|
5186
|
+
"dropdown-menu",
|
|
5164
5187
|
"icon",
|
|
5165
5188
|
"input",
|
|
5166
5189
|
"kbd",
|
|
@@ -5332,6 +5355,7 @@
|
|
|
5332
5355
|
"config/nm-icon-button.ts",
|
|
5333
5356
|
"config/nm-icons-extended.ts",
|
|
5334
5357
|
"config/nm-icons.ts",
|
|
5358
|
+
"config/nm-shape.ts",
|
|
5335
5359
|
"config/nm-small-icon-button.ts",
|
|
5336
5360
|
"config/nordman-chrome.ts",
|
|
5337
5361
|
"kit-logger.ts",
|
|
@@ -5693,6 +5717,7 @@
|
|
|
5693
5717
|
"config/nm-icon-button.ts",
|
|
5694
5718
|
"config/nm-icons-extended.ts",
|
|
5695
5719
|
"config/nm-icons.ts",
|
|
5720
|
+
"config/nm-shape.ts",
|
|
5696
5721
|
"config/nm-side-panel.ts",
|
|
5697
5722
|
"kit-logger.ts",
|
|
5698
5723
|
"lib/logger.ts",
|
|
@@ -5864,6 +5889,7 @@
|
|
|
5864
5889
|
"config/nm-icon-button.ts",
|
|
5865
5890
|
"config/nm-icons-extended.ts",
|
|
5866
5891
|
"config/nm-icons.ts",
|
|
5892
|
+
"config/nm-shape.ts",
|
|
5867
5893
|
"kit-logger.ts",
|
|
5868
5894
|
"lib/logger.ts",
|
|
5869
5895
|
"lib/nm-class.ts",
|
|
@@ -6041,6 +6067,7 @@
|
|
|
6041
6067
|
"config/nm-icon-button.ts",
|
|
6042
6068
|
"config/nm-icons-extended.ts",
|
|
6043
6069
|
"config/nm-icons.ts",
|
|
6070
|
+
"config/nm-shape.ts",
|
|
6044
6071
|
"config/nordman-chrome.ts",
|
|
6045
6072
|
"kit-logger.ts",
|
|
6046
6073
|
"lib/logger.ts",
|
|
@@ -6202,6 +6229,7 @@
|
|
|
6202
6229
|
"config/nm-button.ts",
|
|
6203
6230
|
"config/nm-icons-extended.ts",
|
|
6204
6231
|
"config/nm-icons.ts",
|
|
6232
|
+
"config/nm-shape.ts",
|
|
6205
6233
|
"config/nordman-login.ts",
|
|
6206
6234
|
"content/nordman-login.ts",
|
|
6207
6235
|
"kit-logger.ts",
|
|
@@ -6383,6 +6411,7 @@
|
|
|
6383
6411
|
"config/nm-button.ts",
|
|
6384
6412
|
"config/nm-icons-extended.ts",
|
|
6385
6413
|
"config/nm-icons.ts",
|
|
6414
|
+
"config/nm-shape.ts",
|
|
6386
6415
|
"config/nordman-login.ts",
|
|
6387
6416
|
"content/nordman-login.ts",
|
|
6388
6417
|
"kit-logger.ts",
|
|
@@ -6540,6 +6569,7 @@
|
|
|
6540
6569
|
"config/nm-button.ts",
|
|
6541
6570
|
"config/nm-icons-extended.ts",
|
|
6542
6571
|
"config/nm-icons.ts",
|
|
6572
|
+
"config/nm-shape.ts",
|
|
6543
6573
|
"content/nordman-login.ts",
|
|
6544
6574
|
"kit-logger.ts",
|
|
6545
6575
|
"lib/logger.ts",
|
|
@@ -6704,6 +6734,7 @@
|
|
|
6704
6734
|
"config/nm-button.ts",
|
|
6705
6735
|
"config/nm-icons-extended.ts",
|
|
6706
6736
|
"config/nm-icons.ts",
|
|
6737
|
+
"config/nm-shape.ts",
|
|
6707
6738
|
"config/nordman-login.ts",
|
|
6708
6739
|
"content/nordman-login.ts",
|
|
6709
6740
|
"kit-logger.ts",
|
|
@@ -6863,6 +6894,7 @@
|
|
|
6863
6894
|
"config/nm-button.ts",
|
|
6864
6895
|
"config/nm-icons-extended.ts",
|
|
6865
6896
|
"config/nm-icons.ts",
|
|
6897
|
+
"config/nm-shape.ts",
|
|
6866
6898
|
"config/nordman-login.ts",
|
|
6867
6899
|
"content/nordman-login.ts",
|
|
6868
6900
|
"kit-logger.ts",
|
|
@@ -7035,6 +7067,7 @@
|
|
|
7035
7067
|
"config/nm-button.ts",
|
|
7036
7068
|
"config/nm-icons-extended.ts",
|
|
7037
7069
|
"config/nm-icons.ts",
|
|
7070
|
+
"config/nm-shape.ts",
|
|
7038
7071
|
"config/nordman-login.ts",
|
|
7039
7072
|
"content/nordman-login.ts",
|
|
7040
7073
|
"kit-logger.ts",
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type NmButtonSize,
|
|
8
8
|
type NmButtonTone,
|
|
9
9
|
} from '../../config/nm-button.ts';
|
|
10
|
+
import { NM_CONTROL_SHAPES, type NmControlShape } from '../../config/nm-shape.ts';
|
|
10
11
|
import { createLogger } from '../../kit-logger.ts';
|
|
11
12
|
import { AnimateIcon, Button as MotionButton } from '../../lib/nm-motion.ts';
|
|
12
13
|
import { NmIcon } from '../nm-icon/nm-icon.tsx';
|
|
@@ -19,6 +20,8 @@ export type NmButtonProps = {
|
|
|
19
20
|
children?: ReactNode;
|
|
20
21
|
tone: NmButtonTone;
|
|
21
22
|
size?: NmButtonSize;
|
|
23
|
+
/** Soft follows the themed radius; round is a pill. */
|
|
24
|
+
shape?: NmControlShape;
|
|
22
25
|
block?: boolean;
|
|
23
26
|
type?: 'button' | 'submit';
|
|
24
27
|
disabled?: boolean;
|
|
@@ -34,12 +37,13 @@ export type NmButtonProps = {
|
|
|
34
37
|
type NmButtonNativeProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, keyof NmButtonProps | 'children' | 'aria-pressed'>;
|
|
35
38
|
|
|
36
39
|
export const NmButton = forwardRef<HTMLButtonElement, NmButtonProps & NmButtonNativeProps>(function NmButton(props, ref): ReactNode {
|
|
37
|
-
const { label, children, tone, size: sizeProp, block, type, disabled, pressed, icon, iconOnly, testId, onClick, className: extra, ...rest } = props;
|
|
40
|
+
const { label, children, tone, size: sizeProp, shape, block, type, disabled, pressed, icon, iconOnly, testId, onClick, className: extra, ...rest } = props;
|
|
38
41
|
const size = sizeProp ?? NM_BUTTON_SIZES.default;
|
|
39
42
|
const className = [
|
|
40
43
|
NM_BUTTON_CLASSES.root,
|
|
41
44
|
NM_BUTTON_CLASSES[tone],
|
|
42
45
|
NM_BUTTON_CLASSES[size],
|
|
46
|
+
shape === NM_CONTROL_SHAPES.round ? NM_BUTTON_CLASSES.round : null,
|
|
43
47
|
block ? NM_BUTTON_CLASSES.block : null,
|
|
44
48
|
iconOnly ? NM_BUTTON_CLASSES.icon : null,
|
|
45
49
|
extra,
|
|
@@ -185,18 +185,25 @@
|
|
|
185
185
|
outline: none;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
/* Send, Stop, Done and the voice button are the primary action: they take the theme accent. */
|
|
188
189
|
.nm-composer__button--primary {
|
|
189
|
-
background: var(--nm-
|
|
190
|
+
background: var(--nm-accent);
|
|
190
191
|
color: var(--nm-canvas);
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
.nm-composer__button--primary:hover:not(:disabled),
|
|
194
195
|
.nm-composer__button--primary:focus-visible {
|
|
195
|
-
background: var(--nm-
|
|
196
|
+
background: var(--nm-accent);
|
|
196
197
|
color: var(--nm-canvas);
|
|
197
198
|
opacity: 0.88;
|
|
198
199
|
}
|
|
199
200
|
|
|
201
|
+
/* Round shape: every button in the bar, the composer's own and any hosted icon button, is a circle. */
|
|
202
|
+
.nm-composer[data-button-shape='round'] .nm-composer__button,
|
|
203
|
+
.nm-composer[data-button-shape='round'] .nm-icon-button {
|
|
204
|
+
border-radius: var(--nm-radius-round);
|
|
205
|
+
}
|
|
206
|
+
|
|
200
207
|
.nm-composer__button:disabled {
|
|
201
208
|
cursor: default;
|
|
202
209
|
opacity: 0.4;
|
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
NM_COMPOSER_INLINE_MARK as MARK,
|
|
7
7
|
type NmComposerAttachment,
|
|
8
8
|
type NmComposerQueued,
|
|
9
|
+
NM_COMPOSER_SHAPE_ATTRIBUTE,
|
|
9
10
|
} from '../../config/nm-composer.ts';
|
|
11
|
+
import type { NmControlShape } from '../../config/nm-shape.ts';
|
|
10
12
|
import { NmIcon } from '../nm-icon/nm-icon.tsx';
|
|
11
13
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
12
14
|
import { NmVoiceOrb } from '../nm-voice-orb/nm-voice-orb.tsx';
|
|
@@ -78,6 +80,8 @@ export type NmComposerProps = {
|
|
|
78
80
|
formless?: boolean;
|
|
79
81
|
/** The host owns the text: the field is not controlled by `value`, and `value` only says whether there is any. */
|
|
80
82
|
uncontrolled?: boolean;
|
|
83
|
+
/** Shape of every button in the bar, own and hosted. Round makes them circles. */
|
|
84
|
+
buttonShape?: NmControlShape;
|
|
81
85
|
};
|
|
82
86
|
|
|
83
87
|
type InlinePart = { kind: 'text'; value: string } | { kind: 'chip'; label: string; occurrence: number };
|
|
@@ -337,7 +341,7 @@ export function NmComposer(props: NmComposerProps): ReactNode {
|
|
|
337
341
|
);
|
|
338
342
|
} else {
|
|
339
343
|
action = (
|
|
340
|
-
<button type="button" className={C.button} aria-label={COPY.voice} data-testid="voice-button" disabled={props.disabled} onClick={props.onVoice}>
|
|
344
|
+
<button type="button" className={`${C.button} ${C.primary}`} aria-label={COPY.voice} data-testid="voice-button" disabled={props.disabled} onClick={props.onVoice}>
|
|
341
345
|
<NmIcon id="audio-lines" />
|
|
342
346
|
</button>
|
|
343
347
|
);
|
|
@@ -348,6 +352,7 @@ export function NmComposer(props: NmComposerProps): ReactNode {
|
|
|
348
352
|
<Root
|
|
349
353
|
ref={rootRef as never}
|
|
350
354
|
className={C.root}
|
|
355
|
+
{...{ [NM_COMPOSER_SHAPE_ATTRIBUTE]: props.buttonShape }}
|
|
351
356
|
data-disabled={props.disabled ? 'true' : undefined}
|
|
352
357
|
data-testid={props.testId}
|
|
353
358
|
{...(props.formless
|
|
@@ -14,6 +14,8 @@ export type NmDropdownItem = {
|
|
|
14
14
|
danger?: boolean;
|
|
15
15
|
disabled?: boolean;
|
|
16
16
|
checked?: boolean;
|
|
17
|
+
/** The row that is the current choice in a list of alternatives. Shown by fill, not by a mark; for a toggle use `checked`. */
|
|
18
|
+
current?: boolean;
|
|
17
19
|
/** Publish row state. The row stays inactive while busy or live. */
|
|
18
20
|
mark?: 'idle' | 'busy' | 'live';
|
|
19
21
|
children?: readonly NmDropdownItem[];
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
NM_DROPDOWN_ALIGN,
|
|
5
5
|
NM_DROPDOWN_CLASSES,
|
|
6
6
|
NM_DROPDOWN_REVEAL,
|
|
7
|
+
NM_DROPDOWN_SIDE,
|
|
7
8
|
NM_DROPDOWN_TONE,
|
|
8
9
|
NM_DROPDOWN_TRIGGER,
|
|
9
10
|
} from '../../config/nm-dropdown.ts';
|
|
@@ -46,6 +47,7 @@ export type NmDropdownProps = {
|
|
|
46
47
|
trigger?: (typeof NM_DROPDOWN_TRIGGER)[keyof typeof NM_DROPDOWN_TRIGGER];
|
|
47
48
|
tone?: (typeof NM_DROPDOWN_TONE)[keyof typeof NM_DROPDOWN_TONE];
|
|
48
49
|
align?: (typeof NM_DROPDOWN_ALIGN)[keyof typeof NM_DROPDOWN_ALIGN];
|
|
50
|
+
side?: (typeof NM_DROPDOWN_SIDE)[keyof typeof NM_DROPDOWN_SIDE];
|
|
49
51
|
icon?: NmIconId;
|
|
50
52
|
imageSrc?: string;
|
|
51
53
|
displayLabel?: string;
|
|
@@ -57,6 +59,8 @@ export type NmDropdownProps = {
|
|
|
57
59
|
/** `hover` hides the trigger until the host with `data-nm-menu` is hovered or focused. */
|
|
58
60
|
reveal?: (typeof NM_DROPDOWN_REVEAL)[keyof typeof NM_DROPDOWN_REVEAL];
|
|
59
61
|
open?: boolean;
|
|
62
|
+
/** Opens when the trigger is hovered, as well as on click. */
|
|
63
|
+
openOnHover?: boolean;
|
|
60
64
|
triggerClassName?: string;
|
|
61
65
|
triggerRef?: Ref<HTMLButtonElement>;
|
|
62
66
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -173,8 +177,8 @@ export function NmDropdown(props: NmDropdownProps): ReactNode {
|
|
|
173
177
|
data-reveal={props.reveal}
|
|
174
178
|
>
|
|
175
179
|
<NmDropdownMenu open={open} onOpenChange={setOpen}>
|
|
176
|
-
<NmDropdownMenuTrigger render={triggerElement} />
|
|
177
|
-
<NmDropdownMenuContent align={props.align === NM_DROPDOWN_ALIGN.end ? 'end' : 'start'}>
|
|
180
|
+
<NmDropdownMenuTrigger render={triggerElement} openOnHover={props.openOnHover} />
|
|
181
|
+
<NmDropdownMenuContent align={props.align === NM_DROPDOWN_ALIGN.end ? 'end' : 'start'} side={props.side}>
|
|
178
182
|
<NmDropdownMenuItems
|
|
179
183
|
items={items}
|
|
180
184
|
selected={props.selected}
|
|
@@ -70,6 +70,17 @@
|
|
|
70
70
|
background: var(--nm-line);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
.nm-menu__item[data-current] {
|
|
74
|
+
background: var(--nm-line);
|
|
75
|
+
color: var(--nm-fg);
|
|
76
|
+
}
|
|
77
|
+
.nm-menu__item[data-current] .nm-icon {
|
|
78
|
+
color: var(--nm-fg);
|
|
79
|
+
}
|
|
80
|
+
.nm-menu__item[data-current]:hover,
|
|
81
|
+
.nm-menu__item[data-current][data-highlighted] {
|
|
82
|
+
background: var(--nm-raised);
|
|
83
|
+
}
|
|
73
84
|
.nm-menu__item[data-disabled] {
|
|
74
85
|
pointer-events: none;
|
|
75
86
|
opacity: 0.5;
|