@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
|
@@ -8,7 +8,9 @@ import type { NmDropdownItem } from '../nm-dropdown/nm-dropdown-item.ts';
|
|
|
8
8
|
const InGroup = createContext(false);
|
|
9
9
|
|
|
10
10
|
/** Base UI Menu, in the shadcn dropdown-menu composition, styled by NIF tokens. */
|
|
11
|
-
export
|
|
11
|
+
export type NmDropdownMenuProps = MenuPrimitive.Root.Props;
|
|
12
|
+
|
|
13
|
+
export function NmDropdownMenu(props: NmDropdownMenuProps) {
|
|
12
14
|
return <MenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -150,7 +152,7 @@ function itemBody(item: NmDropdownItem) {
|
|
|
150
152
|
);
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
/** A list of NmDropdownItem as animated menu rows: branches become submenus, `checked` rows keep a mark. */
|
|
155
|
+
/** 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. */
|
|
154
156
|
export function NmDropdownMenuItems({
|
|
155
157
|
items,
|
|
156
158
|
selected,
|
|
@@ -178,7 +180,15 @@ export function NmDropdownMenuItems({
|
|
|
178
180
|
</NmDropdownMenuSub>
|
|
179
181
|
);
|
|
180
182
|
}
|
|
181
|
-
const
|
|
183
|
+
const current = item.current === true || (selected != null && item.id === selected);
|
|
184
|
+
if (current) {
|
|
185
|
+
return (
|
|
186
|
+
<NmDropdownMenuItem key={item.id} data-current="" aria-current="true" disabled={item.disabled} onClick={() => onSelect?.(item.id)}>
|
|
187
|
+
{itemBody(item)}
|
|
188
|
+
</NmDropdownMenuItem>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
const checked = item.checked;
|
|
182
192
|
if (checked !== undefined) {
|
|
183
193
|
return (
|
|
184
194
|
<NmDropdownMenuCheckboxItem key={item.id} checked={checked} disabled={item.disabled} onClick={() => onSelect?.(item.id)}>
|
|
@@ -432,6 +432,41 @@
|
|
|
432
432
|
.nm-sidebar__menu-item:has(> .nm-sidebar__menu-action) > .nm-sidebar__menu-button {
|
|
433
433
|
padding-inline-end: var(--nm-icon-control);
|
|
434
434
|
}
|
|
435
|
+
.nm-sidebar__menu-item:has(> .nm-sidebar__menu-actions) > .nm-sidebar__menu-button {
|
|
436
|
+
padding-inline-end: calc(var(--nm-icon-control) * 2);
|
|
437
|
+
}
|
|
438
|
+
/* A group of actions at the end of a row. Its actions sit in flow inside it; the group takes the row's end. */
|
|
439
|
+
.nm-sidebar__menu-actions {
|
|
440
|
+
position: absolute;
|
|
441
|
+
inset-inline-end: var(--nm-space-4);
|
|
442
|
+
top: calc(50% - (var(--nm-icon-button) + var(--nm-space-6) * 2) / 2);
|
|
443
|
+
display: flex;
|
|
444
|
+
align-items: center;
|
|
445
|
+
gap: var(--nm-space-2);
|
|
446
|
+
transition: opacity var(--reveal) var(--ease);
|
|
447
|
+
}
|
|
448
|
+
.nm-sidebar__menu-actions > .nm-sidebar__menu-action,
|
|
449
|
+
.nm-sidebar__menu-actions .nm-dropdown {
|
|
450
|
+
position: static;
|
|
451
|
+
}
|
|
452
|
+
.nm-sidebar__menu-actions[data-show-on-hover] {
|
|
453
|
+
opacity: 0;
|
|
454
|
+
}
|
|
455
|
+
.nm-sidebar__menu-item:hover > .nm-sidebar__menu-actions[data-show-on-hover],
|
|
456
|
+
.nm-sidebar__menu-item:focus-within > .nm-sidebar__menu-actions[data-show-on-hover],
|
|
457
|
+
.nm-sidebar__menu-item:has(> [data-active]) > .nm-sidebar__menu-actions[data-show-on-hover],
|
|
458
|
+
.nm-sidebar__menu-actions[data-show-on-hover]:has([data-popup-open]),
|
|
459
|
+
.nm-sidebar__menu-actions[data-show-on-hover]:has([aria-expanded='true']) {
|
|
460
|
+
opacity: 1;
|
|
461
|
+
}
|
|
462
|
+
/* A bar in the header or footer: its controls spread to the ends. */
|
|
463
|
+
.nm-sidebar__bar {
|
|
464
|
+
display: flex;
|
|
465
|
+
align-items: center;
|
|
466
|
+
justify-content: space-between;
|
|
467
|
+
gap: var(--nm-space-8);
|
|
468
|
+
padding: var(--nm-space-4);
|
|
469
|
+
}
|
|
435
470
|
|
|
436
471
|
/* The chevron of a row that opens. It points right when closed and down when open. */
|
|
437
472
|
.nm-sidebar__chevron {
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
} from '../../config/nm-sidebar.ts';
|
|
27
27
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
28
28
|
import { NmChip } from '../nm-chip/nm-chip.tsx';
|
|
29
|
+
import { NmDropdownMenu, type NmDropdownMenuProps } from '../nm-dropdown-menu/nm-dropdown-menu.tsx';
|
|
29
30
|
import { NmDrawer, NmDrawerContent } from '../nm-drawer/nm-drawer.tsx';
|
|
30
31
|
import { NmIcon } from '../nm-icon/nm-icon.tsx';
|
|
31
32
|
import { NmInput } from '../nm-input/nm-input.tsx';
|
|
@@ -63,6 +64,11 @@ const SidebarContext = createContext<SidebarContextValue | null>(null);
|
|
|
63
64
|
const PEEK_KEEPS = '[data-slot="sidebar"], [data-slot="sidebar-trigger"], [data-slot="tooltip-content"], [role="menu"], [role="dialog"]';
|
|
64
65
|
|
|
65
66
|
/** The sidebar's state: expanded or collapsed, peeking, on a desktop or a phone, and the function that toggles it. */
|
|
67
|
+
/** Whether the sidebar is in view: open or peeking on a desktop, the drawer open on a phone. */
|
|
68
|
+
export function useSidebarVisible(): boolean {
|
|
69
|
+
const { open, peek, isMobile, openMobile } = useSidebar();
|
|
70
|
+
return isMobile ? openMobile : open || peek;
|
|
71
|
+
}
|
|
66
72
|
/** The sidebar context when there is one. For a part that lives in a bar shared by pages with and without a sidebar. */
|
|
67
73
|
export function useOptionalSidebar(): SidebarContextValue | null {
|
|
68
74
|
return useContext(SidebarContext);
|
|
@@ -477,6 +483,14 @@ export function NmSidebarMenuAction({ className, showOnHover = false, ...props }
|
|
|
477
483
|
);
|
|
478
484
|
}
|
|
479
485
|
|
|
486
|
+
/** Several actions at the end of a row, such as new and more. They reveal together when `showOnHover`. */
|
|
487
|
+
export function NmSidebarMenuActions({ className, showOnHover = false, ...props }: ComponentProps<'div'> & { showOnHover?: boolean }): ReactNode {
|
|
488
|
+
return <div data-slot="sidebar-menu-actions" data-show-on-hover={showOnHover ? '' : undefined} className={nmClass('nm-sidebar__menu-actions', className)} {...props} />;
|
|
489
|
+
}
|
|
490
|
+
/** A row of controls in the header or footer, such as a primary button and an icon button, spaced apart. */
|
|
491
|
+
export function NmSidebarBar({ className, ...props }: ComponentProps<'div'>): ReactNode {
|
|
492
|
+
return <div data-slot="sidebar-bar" className={nmClass('nm-sidebar__bar', className)} {...props} />;
|
|
493
|
+
}
|
|
480
494
|
/** A count or a short word at the end of a row. The NIF Chip, small. */
|
|
481
495
|
export function NmSidebarMenuBadge({ className, ...props }: ComponentProps<typeof NmChip>): ReactNode {
|
|
482
496
|
return <NmChip data-slot="sidebar-menu-badge" size="sm" className={nmClass('nm-sidebar__menu-badge', className)} {...props} />;
|
|
@@ -549,3 +563,27 @@ export function NmSidebarMenuSubButton({
|
|
|
549
563
|
export function NmSidebarChevron({ className, menu = false, ...props }: Omit<ComponentProps<typeof NmIcon>, 'id'> & { menu?: boolean }): ReactNode {
|
|
550
564
|
return <NmIcon id="chevron" data-menu={menu ? '' : undefined} className={nmClass('nm-sidebar__chevron', className)} {...props} />;
|
|
551
565
|
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* A dropdown menu opened from the sidebar. It closes the moment the sidebar goes out of view
|
|
569
|
+
* (collapsed, a peek that ended, the drawer closed), so no menu outlives the panel it came from.
|
|
570
|
+
* While it is open the pointer may rest on it without ending a peek.
|
|
571
|
+
*/
|
|
572
|
+
export function NmSidebarDropdownMenu({ open: openProp, onOpenChange, ...props }: NmDropdownMenuProps) {
|
|
573
|
+
const visible = useSidebarVisible();
|
|
574
|
+
const [openState, setOpenState] = useState(false);
|
|
575
|
+
const open = (openProp ?? openState) && visible;
|
|
576
|
+
const handleOpenChange = useCallback<NonNullable<NmDropdownMenuProps['onOpenChange']>>(
|
|
577
|
+
(next, details) => {
|
|
578
|
+
setOpenState(next);
|
|
579
|
+
onOpenChange?.(next, details);
|
|
580
|
+
},
|
|
581
|
+
[onOpenChange],
|
|
582
|
+
);
|
|
583
|
+
useEffect(() => {
|
|
584
|
+
if (!visible) {
|
|
585
|
+
setOpenState(false);
|
|
586
|
+
}
|
|
587
|
+
}, [visible]);
|
|
588
|
+
return <NmDropdownMenu open={open} onOpenChange={handleOpenChange} {...props} />;
|
|
589
|
+
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from '../../config/nm-small-icon-button.ts';
|
|
7
7
|
import { NM_ICON_BUTTON_TONES, type NmIconButtonTone } from '../../config/nm-icon-button.ts';
|
|
8
8
|
import { NordmanIconButton } from '../nordman-icon-button/nordman-icon-button.tsx';
|
|
9
|
+
import type { NmControlShape } from '../../config/nm-shape.ts';
|
|
9
10
|
import { createLogger } from '../../kit-logger.ts';
|
|
10
11
|
|
|
11
12
|
const logger = createLogger('interface-nm-small-icon-button');
|
|
@@ -19,6 +20,8 @@ export type NmSmallIconButtonProps = {
|
|
|
19
20
|
label: string;
|
|
20
21
|
icon: NmIconId;
|
|
21
22
|
tone?: NmSmallIconButtonTone;
|
|
23
|
+
/** Soft follows the themed radius; round is a full circle. */
|
|
24
|
+
shape?: NmControlShape;
|
|
22
25
|
active?: boolean;
|
|
23
26
|
iconContent?: ReactNode;
|
|
24
27
|
testId?: string;
|
|
@@ -31,6 +34,7 @@ export const NmSmallIconButton = forwardRef<HTMLButtonElement, NmSmallIconButton
|
|
|
31
34
|
label,
|
|
32
35
|
icon,
|
|
33
36
|
tone = NM_SMALL_ICON_BUTTON_TONES.solid,
|
|
37
|
+
shape,
|
|
34
38
|
active = false,
|
|
35
39
|
iconContent,
|
|
36
40
|
testId,
|
|
@@ -47,6 +51,7 @@ export const NmSmallIconButton = forwardRef<HTMLButtonElement, NmSmallIconButton
|
|
|
47
51
|
glyph={icon}
|
|
48
52
|
label={label}
|
|
49
53
|
tone={SMALL_ICON_BUTTON_TONE[tone]}
|
|
54
|
+
shape={shape}
|
|
50
55
|
active={active}
|
|
51
56
|
disabled={disabled}
|
|
52
57
|
testId={testId}
|
|
@@ -93,6 +93,9 @@
|
|
|
93
93
|
cursor: pointer;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
.nm-icon-button--round {
|
|
97
|
+
border-radius: var(--nm-radius-round);
|
|
98
|
+
}
|
|
96
99
|
.nm-icon-button--invert.nm-chatbox__send:not(:disabled),
|
|
97
100
|
.nm-icon-button--invert.nm-chatbox__send:not(:disabled):hover,
|
|
98
101
|
.nm-icon-button--invert.nm-chatbox__send:not(:disabled):focus-visible {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
2
|
import type { NmIconId } from '../../config/nm-icons.ts';
|
|
3
|
+
import { NM_CONTROL_SHAPES, type NmControlShape } from '../../config/nm-shape.ts';
|
|
3
4
|
import {
|
|
4
5
|
NM_ICON_BUTTON_CLASSES,
|
|
5
6
|
NM_ICON_BUTTON_TONES,
|
|
@@ -24,6 +25,8 @@ type NordmanIconButtonProps = {
|
|
|
24
25
|
label: string;
|
|
25
26
|
href?: string;
|
|
26
27
|
tone?: NmIconButtonTone;
|
|
28
|
+
/** Soft follows the themed radius; round is a full circle. */
|
|
29
|
+
shape?: NmControlShape;
|
|
27
30
|
variant?: NordmanIconButtonVariant;
|
|
28
31
|
testId?: string;
|
|
29
32
|
imageSrc?: string;
|
|
@@ -55,12 +58,14 @@ function iconButtonTone(
|
|
|
55
58
|
|
|
56
59
|
function iconButtonClass(
|
|
57
60
|
tone: NmIconButtonTone,
|
|
61
|
+
shape: NmControlShape | undefined,
|
|
58
62
|
active: boolean,
|
|
59
63
|
className: string | undefined,
|
|
60
64
|
): string {
|
|
61
65
|
return [
|
|
62
66
|
NM_ICON_BUTTON_CLASSES.root,
|
|
63
67
|
tone === NM_ICON_BUTTON_TONES.line ? '' : NM_ICON_BUTTON_CLASSES[tone],
|
|
68
|
+
shape === NM_CONTROL_SHAPES.round ? NM_ICON_BUTTON_CLASSES.round : '',
|
|
64
69
|
active ? NM_ICON_BUTTON_CLASSES.active : '',
|
|
65
70
|
className ?? '',
|
|
66
71
|
]
|
|
@@ -127,6 +132,7 @@ export const NordmanIconButton = forwardRef<HTMLButtonElement, NordmanIconButton
|
|
|
127
132
|
label,
|
|
128
133
|
href,
|
|
129
134
|
tone,
|
|
135
|
+
shape,
|
|
130
136
|
variant,
|
|
131
137
|
active = false,
|
|
132
138
|
pressed,
|
|
@@ -142,7 +148,7 @@ export const NordmanIconButton = forwardRef<HTMLButtonElement, NordmanIconButton
|
|
|
142
148
|
...rest
|
|
143
149
|
} = props;
|
|
144
150
|
const resolvedTone = iconButtonTone(tone, variant);
|
|
145
|
-
const buttonClass = iconButtonClass(resolvedTone, active, className);
|
|
151
|
+
const buttonClass = iconButtonClass(resolvedTone, shape, active, className);
|
|
146
152
|
const marked = pressed ?? checked ?? (active ? true : undefined);
|
|
147
153
|
logger.debug('render', glyph ?? icon ?? label, { href: Boolean(href), tone: resolvedTone });
|
|
148
154
|
const face = (
|
|
@@ -36,6 +36,7 @@ export const NM_BUTTON_CLASSES = {
|
|
|
36
36
|
large: 'nm-button--large',
|
|
37
37
|
block: 'nm-button--block',
|
|
38
38
|
icon: 'nm-button--icon',
|
|
39
|
+
round: 'nm-button--round',
|
|
39
40
|
} as const;
|
|
40
41
|
|
|
41
42
|
/** The button's class names, for triggers that must stay a Base UI part, such as a menu or popover trigger. */
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Composer: the message box. Built from the Nordman AI design:
|
|
3
3
|
* one framed box, the text on top, actions in a row beneath. Add on the left, dictate and voice on the right.
|
|
4
4
|
*/
|
|
5
|
+
import { NM_SHAPE_ATTRIBUTE } from './nm-shape.ts';
|
|
5
6
|
export const NM_COMPOSER_COPY = {
|
|
6
7
|
placeholder: 'Ask Nordman',
|
|
7
8
|
attach: 'Add',
|
|
@@ -44,6 +45,8 @@ export const NM_COMPOSER_CLASSES = {
|
|
|
44
45
|
primary: 'nm-composer__button--primary',
|
|
45
46
|
stopMark: 'nm-composer__stop-mark',
|
|
46
47
|
} as const;
|
|
48
|
+
/** Set on the root with a shape value; every button in the bar, own or hosted, takes that shape. */
|
|
49
|
+
export const NM_COMPOSER_SHAPE_ATTRIBUTE = NM_SHAPE_ATTRIBUTE;
|
|
47
50
|
|
|
48
51
|
export type NmComposerAttachment = { id: string; name: string };
|
|
49
52
|
|
|
@@ -51,6 +51,13 @@ export const NM_DROPDOWN_ALIGN = {
|
|
|
51
51
|
row: 'row',
|
|
52
52
|
} as const;
|
|
53
53
|
|
|
54
|
+
/** Which side of the trigger the menu opens on. `right` for a menu that must not cover a side panel's rows. */
|
|
55
|
+
export const NM_DROPDOWN_SIDE = {
|
|
56
|
+
bottom: 'bottom',
|
|
57
|
+
top: 'top',
|
|
58
|
+
right: 'right',
|
|
59
|
+
left: 'left',
|
|
60
|
+
} as const;
|
|
54
61
|
/** Icon menus stay hidden until the host row or field is hovered or focused. */
|
|
55
62
|
export const NM_DROPDOWN_REVEAL = {
|
|
56
63
|
hover: 'hover',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { NM_CONTROL_SHAPES, type NmControlShape } from './nm-shape.ts';
|
|
1
2
|
export const NM_ICON_BUTTON_TONES = {
|
|
2
3
|
line: 'line',
|
|
3
4
|
raised: 'raised',
|
|
@@ -19,15 +20,20 @@ export const NM_ICON_BUTTON_CLASSES = {
|
|
|
19
20
|
solid: 'nm-icon-button--solid',
|
|
20
21
|
panel: 'nm-icon-button--panel',
|
|
21
22
|
invert: 'nm-icon-button--invert',
|
|
23
|
+
round: 'nm-icon-button--round',
|
|
22
24
|
} as const;
|
|
23
25
|
|
|
24
26
|
/** Shared geometry hook for send / stop / during-run primary composer actions. */
|
|
25
27
|
export const NM_CHATBOX_ACTION_CLASS = 'nm-chatbox__send';
|
|
26
28
|
|
|
27
|
-
export function nmIconButtonClassName(
|
|
28
|
-
|
|
29
|
+
export function nmIconButtonClassName(
|
|
30
|
+
tone: NmIconButtonTone = NM_ICON_BUTTON_TONES.quiet,
|
|
31
|
+
shape?: NmControlShape,
|
|
32
|
+
): string {
|
|
33
|
+
const base = `${NM_ICON_BUTTON_CLASSES.root} ${NM_ICON_BUTTON_CLASSES[tone]}`;
|
|
34
|
+
return shape === NM_CONTROL_SHAPES.round ? `${base} ${NM_ICON_BUTTON_CLASSES.round}` : base;
|
|
29
35
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return `${
|
|
36
|
+
export function nmChatboxActionButtonClassName(shape?: NmControlShape): string {
|
|
37
|
+
const base = `${NM_ICON_BUTTON_CLASSES.root} ${NM_ICON_BUTTON_CLASSES.invert} ${NM_CHATBOX_ACTION_CLASS}`;
|
|
38
|
+
return shape === NM_CONTROL_SHAPES.round ? `${base} ${NM_ICON_BUTTON_CLASSES.round}` : base;
|
|
33
39
|
}
|
|
@@ -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 const NM_CONTROL_SHAPES = {
|
|
6
|
+
soft: 'soft',
|
|
7
|
+
round: 'round',
|
|
8
|
+
} as const;
|
|
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 const NM_SHAPE_ATTRIBUTE = 'data-button-shape';
|
|
@@ -93,6 +93,8 @@
|
|
|
93
93
|
--nm-radius-sm: calc(4px * var(--nm-radius-scale));
|
|
94
94
|
--nm-radius-md: calc(8px * var(--nm-radius-scale));
|
|
95
95
|
--nm-radius-lg: calc(12px * var(--nm-radius-scale));
|
|
96
|
+
/* A full circle or pill. Not scaled: a circle has no corner. */
|
|
97
|
+
--nm-radius-round: 9999px;
|
|
96
98
|
/* 100% by default. The Space setting scales every spacing token. */
|
|
97
99
|
--nm-space-scale: 1;
|
|
98
100
|
--nm-space-2: calc(0.125rem * var(--nm-space-scale));
|