40 lines
2.2 KiB
JavaScript
40 lines
2.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import test from 'node:test';
|
|
import { createElement } from 'react';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
import { Select } from '../packages/ui-react/dist/index.js';
|
|
|
|
test('select action menus use dialog semantics in all variants; ordinary select stays a listbox', () => {
|
|
for (const variant of ['integrated', 'split', 'inline']) {
|
|
for (const withAction of [false, true]) {
|
|
const markup = renderToStaticMarkup(createElement(Select, {
|
|
label: 'Records', variant, value: 'one', onChange: () => {},
|
|
options: [{value: 'one', label: 'One', ...(withAction ? {action: {label: 'Delete One', icon: 'x', onAction: () => {}}} : {})}],
|
|
}));
|
|
assert.match(markup, new RegExp(`aria-haspopup="${withAction ? 'dialog' : 'listbox'}"`));
|
|
}
|
|
}
|
|
});
|
|
|
|
test('row action is independent of selection, closes first and uses canonical IconButton', async () => {
|
|
const source = await readFile(new URL('../packages/ui-react/src/Select.tsx', import.meta.url), 'utf8');
|
|
assert.match(source, /<\/button>\s*\{option\.action \? <IconButton/);
|
|
assert.match(source, /disabled=\{option\.action\.disabled\}/);
|
|
assert.match(source, /close\(\);[\s\S]*triggerButton.current\?\.focus\(\);\s*option\.action\?\.onAction\(\)/);
|
|
assert.match(source, /role=\{withActions \? undefined : "option"\}/);
|
|
});
|
|
|
|
test('row action matches the compact session catalog without a circular backing', async () => {
|
|
const css = await readFile(new URL('../packages/ui-core/styles.css', import.meta.url), 'utf8');
|
|
const rule = css.match(/\.nodedc-select-option-row > \.nodedc-icon-button \{([^}]+)\}/)?.[1];
|
|
assert.match(rule, /width: 2\.35rem/);
|
|
assert.match(rule, /height: auto/);
|
|
assert.match(rule, /border-radius: 0/);
|
|
assert.match(rule, /background: transparent/);
|
|
assert.match(rule, /box-shadow: none/);
|
|
assert.match(rule, /color: var\(--nodedc-text-muted\)/);
|
|
assert.match(css, /\.nodedc-select-option-row > \.nodedc-icon-button > svg \{ width: 15px; height: 15px; transform: none/);
|
|
assert.match(css, /data-tone="danger"\]\:focus-visible \{ color: rgb\(var\(--nodedc-danger-rgb\)\)/);
|
|
});
|