From 517e9450043eb0a3797ff278985cc702c4ad0fab Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Wed, 20 Mar 2024 10:26:33 -0500 Subject: [PATCH 01/18] Create storybook page for link components (#1945) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale There are a number of browser interactions that are expected to work in certain ways for link components that are difficult to test in an automated manner. Therefore, we decided that we should have a storybook page that contains all of nimble's link components next to a native anchor element to facilitate manual testing of link behaviors. ย  This is follow-on work from #1910, specifically [this comment](https://github.com/ni/nimble/pull/1910#discussion_r1518327840). ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation Create storybook page that includes the following elements: - native anchor - nimble-anchor - nimble-anchor-button - nimble-anchor-tabs - nimble-breadcrumb - nimble-anchor-tree-item - nimble-anchor-menu-item - nimble-table-column-anchor - nimble-rich-text-viewer ## ๐Ÿงช Testing Manually verified that the storybook page rendered as expected. ## โœ… Checklist - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Jesse Attas Co-authored-by: Milan Raj --- ...-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json | 7 + .../patterns/anchor/tests/anchor-patterns.mdx | 38 ++++ .../anchor/tests/anchor-patterns.stories.ts | 169 ++++++++++++++++++ specs/templates/custom-component.md | 1 + specs/templates/fast-based-component.md | 1 + 5 files changed, 216 insertions(+) create mode 100644 change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json create mode 100644 packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx create mode 100644 packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.stories.ts diff --git a/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json b/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json new file mode 100644 index 0000000000..0752486737 --- /dev/null +++ b/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Create anchor patterns story", + "packageName": "@ni/nimble-components", + "email": "20542556+mollykreis@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx b/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx new file mode 100644 index 0000000000..9a403b7dfa --- /dev/null +++ b/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx @@ -0,0 +1,38 @@ +import { Controls, Canvas, Meta, Title } from '@storybook/blocks'; +import * as anchorPatternStories from './anchor-patterns.stories'; + + + + +Anchor components in nimble should behave like native anchors in a number of different ways that are difficult to unit test in an automated manner. +Therefore, this story contains a native anchor element along with all of the nimble components that are anchors or contain anchors. +The following behaviors should be true of the nimble components: + +Mouse interactions: + +- Dragging the nimble component should behave like the native anchor + - Known behavior exceptions: + - Chromium - The drag preview contains the href only, not the label of the anchor. See [chromium issue 329489154](https://issues.chromium.org/issues/329489154). + - Firefox - The drag preview does not contain the label, and in most cases, is blank. See [mozilla bug 1589364](https://bugzilla.mozilla.org/show_bug.cgi?id=1589364). + - Safari - The drag preview contains the href only, not the label of the anchor. +- CTRL + CLICK opens in a new tab (โŒ˜ + CLICK on macOS) +- Right clicking should open the link menu +- Hovering over the component should show the URL preview at the bottom of the browser window +- Copying the link through the right-click link menu should result in the expected string to be copied to the clipboard +- The hover state of the component and mouse pointer should match the area of the component that navigates when clicked (i.e. clicking the white space around the control should not navigate) + +Keyboard interactions: + +- Focusing via tab should show the URL preview at the bottom of the browser window + - Known behavior exceptions: + - Firefox on macOS - Links are not focusable via tab by default. [See this stackoverflow page for how to allow tab focus of links](https://stackoverflow.com/questions/11704828/how-to-allow-keyboard-focus-of-links-in-firefox). + - Safari - Focusing via tab does not show the URL preview at the bottom of the browser, which matches the behavior of native anchors. +- Pressing ENTER when focused should activate the link +- Pressing the MENU KEY on the keyboard while the link is focused should open the same link menu as a right click + +Interactions specific to anchors visualized as text: + +- Selecting the link through click and drag and then copying it should result in the expected string being copied to the clipboard + +<Canvas of={anchorPatternStories.anchorPatterns} /> +<Controls of={anchorPatternStories.anchorPatterns} /> diff --git a/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.stories.ts b/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.stories.ts new file mode 100644 index 0000000000..ea0bf6842e --- /dev/null +++ b/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.stories.ts @@ -0,0 +1,169 @@ +import type { Meta, StoryObj } from '@storybook/html'; +import { html, ref } from '@microsoft/fast-element'; +import { createUserSelectedThemeStory } from '../../../utilities/tests/storybook'; +import { + bodyFont, + bodyFontColor, + controlLabelFont, + controlLabelFontColor, + mediumPadding, + standardPadding +} from '../../../theme-provider/design-tokens'; +import { anchorTag } from '../../../anchor'; +import { anchorButtonTag } from '../../../anchor-button'; +import { anchorTabsTag } from '../../../anchor-tabs'; +import { anchorTabTag } from '../../../anchor-tab'; +import { breadcrumbTag } from '../../../breadcrumb'; +import { breadcrumbItemTag } from '../../../breadcrumb-item'; +import { RichTextViewer, richTextViewerTag } from '../../../rich-text/viewer'; +import { anchorTreeItemTag } from '../../../anchor-tree-item'; +import { treeViewTag } from '../../../tree-view'; +import { anchorMenuItemTag } from '../../../anchor-menu-item'; +import { menuTag } from '../../../menu'; +import { Table, tableTag } from '../../../table'; +import { tableColumnAnchorTag } from '../../../table-column/anchor'; + +interface AnchorPatternsArgs { + label: string; + disabled: boolean; + tableRef: Table; + setTableData: (args: AnchorPatternsArgs) => void; + richTextViewerRef: RichTextViewer; + setRichTextViewerData: (args: AnchorPatternsArgs) => void; +} + +const metadata: Meta<AnchorPatternsArgs> = { + title: 'Tests/Anchor Patterns', + parameters: { + actions: {} + }, + // prettier-ignore + render: createUserSelectedThemeStory(html` + <style class='code-hide'> + .control-container { + margin: var(${standardPadding.cssCustomProperty}); + } + + .label { + font: var(${controlLabelFont.cssCustomProperty}); + color: var(${controlLabelFontColor.cssCustomProperty}); + margin-bottom: var(${mediumPadding.cssCustomProperty}); + } + + .text { + font: var(${bodyFont.cssCustomProperty}); + color: var(${bodyFontColor.cssCustomProperty}); + margin-top: var(${mediumPadding.cssCustomProperty}); + } + </style> + <div class="control-container"> + <div class="label">Native anchor</div> + <a href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=native-anchor-1')}">${x => x.label}</a> + <div class="text">Text that contains a <a href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=native-anchor-2')}">native anchor element</a>.</div> + </div> + + <div class="control-container"> + <div class="label">${anchorTag}</div> + <${anchorTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-anchor-1')}">${x => x.label}</${anchorTag}> + <div class="text">Text that contains a <${anchorTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-anchor-2')}">nimble anchor element</${anchorTag}>.</div> + </div> + + <div class="control-container"> + <div class="label">${anchorButtonTag}</div> + <${anchorButtonTag} href="https://nimble.ni.dev?type=nimble-anchor-button" ?disabled="${x => x.disabled}">${x => x.label}</${anchorButtonTag}> + </div> + + <div class="control-container"> + <div class="label">${anchorTabsTag}</div> + <${anchorTabsTag}> + <${anchorTabTag} href="https://nimble.ni.dev?type=nimble-anchor-tab-1" ?disabled="${x => x.disabled}">${x => x.label} - 1</${anchorTabTag}> + <${anchorTabTag} href="https://nimble.ni.dev?type=nimble-anchor-tab-2" ?disabled="${x => x.disabled}">${x => x.label} - 2</${anchorTabTag}> + </${anchorTabsTag}> + </div> + + <div class="control-container"> + <div class="label">${breadcrumbTag}</div> + <${breadcrumbTag}> + <${breadcrumbItemTag} href="${x => (x.disabled ? undefined : 'https://nimble.ni.dev?type=nimble-breadcrumb-item')}">${x => x.label}</${breadcrumbItemTag}> + <${breadcrumbItemTag}>Current page (no link)</${breadcrumbItemTag}> + </${breadcrumbTag}> + </div> + + <div class="control-container"> + <div class="label">${anchorTreeItemTag}</div> + <${treeViewTag}> + <${anchorTreeItemTag} href="https://nimble.ni.dev?type=nimble-anchor-tree-item" ?disabled="${x => x.disabled}">${x => x.label}</${anchorTreeItemTag}> + </${treeViewTag}> + </div> + + <div class="control-container"> + <div class="label">${anchorMenuItemTag}</div> + <${menuTag}> + <${anchorMenuItemTag} href="https://nimble.ni.dev?type=nimble-anchor-menu-item" ?disabled="${x => x.disabled}">${x => x.label}</${anchorMenuItemTag}> + </${menuTag}> + </div> + + <div class="control-container"> + <div class="label">${tableColumnAnchorTag}</div> + <${tableTag} ${ref('tableRef')} data-unused="${x => x.setTableData(x)}" style="height: 100px;"> + <${tableColumnAnchorTag} label-field-name="label" href-field-name="href">Anchor</${tableColumnAnchorTag}> + </${tableTag}> + </div> + + <div class="control-container"> + <div class="label">${richTextViewerTag}</div> + <${richTextViewerTag} ${ref('richTextViewerRef')} + data-unused="${x => x.setRichTextViewerData(x)}" + > + ${x => x.label} + </${richTextViewerTag}> + </div> + `), + argTypes: { + tableRef: { + table: { disable: true } + }, + setTableData: { + table: { disable: true } + }, + richTextViewerRef: { + table: { disable: true } + }, + setRichTextViewerData: { + table: { disable: true } + } + }, + args: { + label: 'link', + disabled: false, + setTableData: x => { + void (async () => { + // Safari workaround: the nimble-table element instance is made at this point + // but doesn't seem to be upgraded to a custom element yet + await customElements.whenDefined('nimble-table'); + const data = [ + { + label: x.label, + href: x.disabled + ? undefined + : 'https://nimble.ni.dev?type=nimble-table-column-anchor' + } + ]; + void x.tableRef.setData(data); + })(); + }, + setRichTextViewerData: x => { + void (async () => { + // Safari workaround: the nimble-rich-text-viewer element instance is made at this point + // but doesn't seem to be upgraded to a custom element yet + await customElements.whenDefined('nimble-rich-text-viewer'); + const data = `Absolute link: <${x.disabled ? '' : 'https://nimble.ni.dev?type=nimble-rich-text-viewer'}>`; + x.richTextViewerRef.markdown = data; + })(); + } + } +}; + +export default metadata; + +export const anchorPatterns: StoryObj<AnchorPatternsArgs> = {}; diff --git a/specs/templates/custom-component.md b/specs/templates/custom-component.md index b4655429d8..dee58d9827 100644 --- a/specs/templates/custom-component.md +++ b/specs/templates/custom-component.md @@ -109,6 +109,7 @@ - *Components which delegate focus require all global ARIA attributes to be enumerated* - *Components should either follow an existing [ARIA Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/) or provide thorough research indicating why a new pattern is appropriate. Research should include sources like [Open UI Community Group](https://github.com/openui/open-ui) and other popular design systems.* - *Behavior with browser configurations like "Prefers reduced motion"* +- *Support for standard link behaviors if the component is an anchor or contains an anchor. These behaviors are enumerated in the [anchor-patterns story](/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx). The story should be updated to include the new component.* ### Mobile diff --git a/specs/templates/fast-based-component.md b/specs/templates/fast-based-component.md index e1acfeba43..3bd79913da 100644 --- a/specs/templates/fast-based-component.md +++ b/specs/templates/fast-based-component.md @@ -57,6 +57,7 @@ - *Documentation: Any requirements besides standard Storybook docs and updating the Example Client App demo?* - *Tooling: Any new tools, updates to tools, code generation, etc?* - *Accessibility: keyboard navigation/focus, form input, use with assistive technology, etc.* + - *Support for standard link behaviors if the component is an anchor or contains an anchor. These behaviors are enumerated in the [anchor-patterns story](/packages/nimble-components/src/patterns/anchor/tests/anchor-patterns.mdx). The story should be updated to include the new component.* - *Mobile: small screens, touch interactions, mobile-specific integrations* - *Globalization: special RTL handling, swapping of icons/visuals, localization, etc.* - *Performance: does the FAST component meet Nimble's performance requirements?* From 55ba7aa29788bdeeb90726f2e6b9b56e568a85ba Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Wed, 20 Mar 2024 15:46:00 +0000 Subject: [PATCH 02/18] applying package updates [skip ci] --- ...ents-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json | 7 ------- packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json diff --git a/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json b/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json deleted file mode 100644 index 0752486737..0000000000 --- a/change/@ni-nimble-components-80f0d7d1-04a3-456f-85b8-c96cf8c59b93.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Create anchor patterns story", - "packageName": "@ni/nimble-components", - "email": "20542556+mollykreis@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index 2f72e34996..c060a73b09 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Wed, 20 Mar 2024 15:46:00 GMT", + "version": "22.1.0", + "tag": "@ni/nimble-components_v22.1.0", + "comments": { + "none": [ + { + "author": "20542556+mollykreis@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "517e9450043eb0a3797ff278985cc702c4ad0fab", + "comment": "Create anchor patterns story" + } + ] + } + }, { "date": "Mon, 18 Mar 2024 18:10:43 GMT", "version": "22.1.0", From 83f7fd9e601eed789e8f6eb61a9d4a87a1d1835b Mon Sep 17 00:00:00 2001 From: Jonathan Meyer <26874831+atmgrifter00@users.noreply.github.com> Date: Wed, 20 Mar 2024 11:26:21 -0500 Subject: [PATCH 03/18] Combobox registerOption reversion to address Angular bug (#1949) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale [AzDO bug 'Nimble combo box | Issue in showing list options'](https://ni.visualstudio.com/DevCentral/_workitems/edit/2687002) ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation Simple reversion of problem code. I've also created a [tech debt item](https://github.com/ni/nimble/issues/1948) to track the work needed to ultimately re-align the `Combobox` and `Select` implementations. ## ๐Ÿงช Testing Just removing the related test. ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --- ...-54ec9080-33bb-47a6-a37d-d926c42de859.json | 7 +++++ .../nimble-components/src/combobox/index.ts | 25 ++-------------- .../src/combobox/tests/combobox.spec.ts | 29 +------------------ 3 files changed, 10 insertions(+), 51 deletions(-) create mode 100644 change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json diff --git a/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json b/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json new file mode 100644 index 0000000000..897eb39604 --- /dev/null +++ b/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Remove ListOptionOwner from Combobox to address issue found in Angular", + "packageName": "@ni/nimble-components", + "email": "26874831+atmgrifter00@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/nimble-components/src/combobox/index.ts b/packages/nimble-components/src/combobox/index.ts index 4f607c5439..e3da226ded 100644 --- a/packages/nimble-components/src/combobox/index.ts +++ b/packages/nimble-components/src/combobox/index.ts @@ -17,14 +17,10 @@ import { iconExclamationMarkTag } from '../icons/exclamation-mark'; import { styles } from './styles'; import type { ErrorPattern } from '../patterns/error/types'; -import type { - DropdownPattern, - ListOptionOwner -} from '../patterns/dropdown/types'; +import type { DropdownPattern } from '../patterns/dropdown/types'; import { DropdownAppearance } from '../patterns/dropdown/types'; import type { AnchoredRegion } from '../anchored-region'; import { template } from './template'; -import type { ListOption } from '../list-option'; declare global { interface HTMLElementTagNameMap { @@ -37,7 +33,7 @@ declare global { */ export class Combobox extends FoundationCombobox - implements DropdownPattern, ErrorPattern, ListOptionOwner { + implements DropdownPattern, ErrorPattern { @attr public appearance: DropdownAppearance = DropdownAppearance.underline; @@ -211,23 +207,6 @@ export class Combobox return returnValue; } - /** - * @internal - */ - public registerOption(option: ListOption): void { - if (this.options.includes(option)) { - return; - } - - // Adding an option to the end, ultimately, isn't the correct - // thing to do, as this will mean the option's index in the options, - // at least temporarily, does not match the DOM order. However, it - // is expected that a successive run of `slottedOptionsChanged` will - // correct this order issue. See 'https://github.com/ni/nimble/issues/1915' - // for more info. - this.options.push(option); - } - protected override focusAndScrollOptionIntoView(): void { if (this.open) { super.focusAndScrollOptionIntoView(); diff --git a/packages/nimble-components/src/combobox/tests/combobox.spec.ts b/packages/nimble-components/src/combobox/tests/combobox.spec.ts index 7b282bd515..15973059fc 100644 --- a/packages/nimble-components/src/combobox/tests/combobox.spec.ts +++ b/packages/nimble-components/src/combobox/tests/combobox.spec.ts @@ -9,7 +9,7 @@ import { waitAnimationFrame } from '../../utilities/tests/component'; import { checkFullyInViewport } from '../../utilities/tests/intersection-observer'; -import { ListOption, listOptionTag } from '../../list-option'; +import { listOptionTag } from '../../list-option'; async function setup( position?: string, @@ -127,33 +127,6 @@ describe('Combobox', () => { await disconnect(); }); - it('option added directly to DOM synchronously registers with Combobox', async () => { - const { element, connect, disconnect } = await setup(); - await connect(); - element.selectedIndex = 0; - await waitForUpdatesAsync(); - const newOption = new ListOption('foo', 'foo'); - const registerOptionSpy = spyOn( - element, - 'registerOption' - ).and.callThrough(); - registerOptionSpy.calls.reset(); - element.insertBefore(newOption, element.options[0]!); - - expect(registerOptionSpy.calls.count()).toBe(1); - expect(element.options).toContain(newOption); - - // While the option is registered synchronously as shown above, - // properties like selectedIndex will only be correct asynchronously - // See https://github.com/ni/nimble/issues/1915 - expect(element.selectedIndex).toBe(0); - await waitForUpdatesAsync(); - // This assertion shows that after 'slottedOptionsChanged' runs, the - // 'selectedIndex' state has been corrected to expected DOM order. - expect(element.selectedIndex).toBe(1); - await disconnect(); - }); - const ariaTestData: { attrName: string, propSetter: (x: Combobox, value: string) => void From 699749620c558e3119e22889a4c6f800a1dd4e51 Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:45:59 +0000 Subject: [PATCH 04/18] applying package updates [skip ci] --- .../projects/ni/nimble-angular/CHANGELOG.json | 15 +++++++++++++++ .../projects/ni/nimble-angular/CHANGELOG.md | 10 +++++++++- .../projects/ni/nimble-angular/package.json | 4 ++-- ...ents-54ec9080-33bb-47a6-a37d-d926c42de859.json | 7 ------- package-lock.json | 8 ++++---- packages/nimble-blazor/package.json | 2 +- packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ packages/nimble-components/CHANGELOG.md | 10 +++++++++- packages/nimble-components/package.json | 2 +- 9 files changed, 56 insertions(+), 17 deletions(-) delete mode 100644 change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json index 9e9b860a35..f170144ec8 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-angular", "entries": [ + { + "date": "Wed, 20 Mar 2024 16:45:59 GMT", + "version": "20.5.1", + "tag": "@ni/nimble-angular_v20.5.1", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@ni/nimble-angular", + "comment": "Bump @ni/nimble-components to v22.1.1", + "commit": "not available" + } + ] + } + }, { "date": "Mon, 18 Mar 2024 17:12:34 GMT", "version": "20.5.0", diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md index f7aafd80de..1a2aa3c1ca 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-angular -This log was last generated on Mon, 18 Mar 2024 17:12:34 GMT and should not be manually modified. +This log was last generated on Wed, 20 Mar 2024 16:45:59 GMT and should not be manually modified. <!-- Start content --> +## 20.5.1 + +Wed, 20 Mar 2024 16:45:59 GMT + +### Patches + +- Bump @ni/nimble-components to v22.1.1 + ## 20.5.0 Mon, 18 Mar 2024 17:12:34 GMT diff --git a/angular-workspace/projects/ni/nimble-angular/package.json b/angular-workspace/projects/ni/nimble-angular/package.json index ffb4b78ba8..cc13ba5b80 100644 --- a/angular-workspace/projects/ni/nimble-angular/package.json +++ b/angular-workspace/projects/ni/nimble-angular/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-angular", - "version": "20.5.0", + "version": "20.5.1", "description": "Angular components for the NI Nimble Design System", "scripts": { "invoke-publish": "cd ../../../ && npm run build:library && cd dist/ni/nimble-angular && npm publish" @@ -31,7 +31,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^22.1.0" + "@ni/nimble-components": "^22.1.1" }, "dependencies": { "tslib": "^2.2.0" diff --git a/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json b/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json deleted file mode 100644 index 897eb39604..0000000000 --- a/change/@ni-nimble-components-54ec9080-33bb-47a6-a37d-d926c42de859.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "patch", - "comment": "Remove ListOptionOwner from Combobox to address issue found in Angular", - "packageName": "@ni/nimble-components", - "email": "26874831+atmgrifter00@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/package-lock.json b/package-lock.json index 7a23d00821..f8fe26c4e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ }, "angular-workspace/projects/ni/nimble-angular": { "name": "@ni/nimble-angular", - "version": "20.5.0", + "version": "20.5.1", "license": "MIT", "dependencies": { "tslib": "^2.2.0" @@ -85,7 +85,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^22.1.0" + "@ni/nimble-components": "^22.1.1" } }, "node_modules/@11ty/dependency-tree": { @@ -33939,7 +33939,7 @@ }, "packages/nimble-blazor": { "name": "@ni/nimble-blazor", - "version": "14.5.0", + "version": "14.5.1", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -33975,7 +33975,7 @@ }, "packages/nimble-components": { "name": "@ni/nimble-components", - "version": "22.1.0", + "version": "22.1.1", "license": "MIT", "dependencies": { "@microsoft/fast-colors": "^5.3.1", diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index e804ada040..ff76936429 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-blazor", - "version": "14.5.0", + "version": "14.5.1", "description": "Blazor components for the NI Nimble Design System", "scripts": { "postinstall": "node build/generate-playwright-version-properties/source/index.js", diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index c060a73b09..8b2a7bfc67 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Wed, 20 Mar 2024 16:45:59 GMT", + "version": "22.1.1", + "tag": "@ni/nimble-components_v22.1.1", + "comments": { + "patch": [ + { + "author": "26874831+atmgrifter00@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "83f7fd9e601eed789e8f6eb61a9d4a87a1d1835b", + "comment": "Remove ListOptionOwner from Combobox to address issue found in Angular" + } + ] + } + }, { "date": "Wed, 20 Mar 2024 15:46:00 GMT", "version": "22.1.0", diff --git a/packages/nimble-components/CHANGELOG.md b/packages/nimble-components/CHANGELOG.md index 28514fbac5..8825f33110 100644 --- a/packages/nimble-components/CHANGELOG.md +++ b/packages/nimble-components/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-components -This log was last generated on Mon, 18 Mar 2024 17:12:34 GMT and should not be manually modified. +This log was last generated on Wed, 20 Mar 2024 16:45:59 GMT and should not be manually modified. <!-- Start content --> +## 22.1.1 + +Wed, 20 Mar 2024 16:45:59 GMT + +### Patches + +- Remove ListOptionOwner from Combobox to address issue found in Angular ([ni/nimble@83f7fd9](https://github.com/ni/nimble/commit/83f7fd9e601eed789e8f6eb61a9d4a87a1d1835b)) + ## 22.1.0 Mon, 18 Mar 2024 17:12:34 GMT diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index 946cac8bb2..eedf89911c 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-components", - "version": "22.1.0", + "version": "22.1.1", "description": "Styled web components for the NI Nimble Design System", "scripts": { "build": "npm run generate-icons && npm run generate-workers && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", From 755823b11215aa2a2c48f296546d0cb8acf6f64c Mon Sep 17 00:00:00 2001 From: m-akinc <7282195+m-akinc@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:13:17 -0500 Subject: [PATCH 05/18] Small change to design token naming scheme (#1947) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐Ÿคจ Rationale I encountered a couple design tokens with names that felt inconsistent: `buttonFillActivePrimaryColor` `buttonFillAccentActiveColor` It seemed like the appearance variant ("accent" or "primary") should be in the same relative position within the name, but our naming convention dictated these names instead. ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation Treat common state descriptors ("active", "disabled", "hover", and "selected") as a separate category of name segment than other distinguishing descriptors (like "accent" and "primary"). So instead of our old structure: `[element]-[part]-[state]-[token_type]` we now have: `[element]-[part]-[state]-[variant]-[token_type]` Luckily, the only existing token that violates this updated naming scheme is `buttonFillAccentActiveColor` (which should instead be `buttonFillActiveAccentColor`) and that token is being removed in [another PR](https://github.com/ni/nimble/pull/1934). ## ๐Ÿงช Testing N/A ## โœ… Checklist - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Milan Raj <rajsite@users.noreply.github.com> --- ...le-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json | 7 +++++++ packages/nimble-components/CONTRIBUTING.md | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json diff --git a/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json b/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json new file mode 100644 index 0000000000..1a72346f40 --- /dev/null +++ b/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Small change to design token naming scheme", + "packageName": "@ni/nimble-components", + "email": "7282195+m-akinc@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/packages/nimble-components/CONTRIBUTING.md b/packages/nimble-components/CONTRIBUTING.md index 607712adff..8366356817 100644 --- a/packages/nimble-components/CONTRIBUTING.md +++ b/packages/nimble-components/CONTRIBUTING.md @@ -490,12 +490,13 @@ To modify the generated tokens, complete these steps: Public names for theme-aware tokens are specified in `src/theme-provider/design-token-names.ts`. Use the following structure when creating new tokens. -`[element]-[part]-[state]-[token_type]` +`[element]-[part]-[interaction_states]-[remaining_states]-[token_type]` 1. Where **element** is the type to which the token applies (e.g. 'application', 'body', or 'title-plus-1'). 2. Where **part** is the specific part of the element to which the token applies (e.g. 'border', 'background', or shadow). -3. Where **state** is the more specific state descriptor (e.g. 'selected' or 'disabled'). Multiple states should be sorted alphabetically. -4. Where **token_type** is the token category (e.g. 'color', 'font', 'font-color', 'height', 'width', or 'size'). +3. Where **interaction_states** is one or more interaction states (e.g. 'active', 'disabled', 'hover', or 'selected'). Multiple values should be sorted alphabetically. +4. Where **remaining_states** the remaining, non-interaction states (e.g. 'accent', 'primary, or 'large'). Multiple values should be sorted alphabetically. +5. Where **token_type** is the token category (e.g. 'color', 'font', 'font-color', 'height', 'width', or 'size'). ### Size ramp From 9c16eb3e4337d67898ef7cc7c5ec745a1dd696f6 Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Thu, 21 Mar 2024 00:31:13 +0000 Subject: [PATCH 06/18] applying package updates [skip ci] --- ...ents-6a977921-7b82-4c0c-936b-fb4e855c103e.json | 7 ------- packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json diff --git a/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json b/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json deleted file mode 100644 index 1a72346f40..0000000000 --- a/change/@ni-nimble-components-6a977921-7b82-4c0c-936b-fb4e855c103e.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Small change to design token naming scheme", - "packageName": "@ni/nimble-components", - "email": "7282195+m-akinc@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index 8b2a7bfc67..7c3c87ef3a 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Thu, 21 Mar 2024 00:31:13 GMT", + "version": "22.1.1", + "tag": "@ni/nimble-components_v22.1.1", + "comments": { + "none": [ + { + "author": "7282195+m-akinc@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "755823b11215aa2a2c48f296546d0cb8acf6f64c", + "comment": "Small change to design token naming scheme" + } + ] + } + }, { "date": "Wed, 20 Mar 2024 16:45:59 GMT", "version": "22.1.1", From 7e52ce24569e94af5282b4b77f34608211cf74c9 Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:08:18 -0500 Subject: [PATCH 07/18] Fix sizing test in WebKit (#1954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale Resolves #1939 ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation I updated the test to use sizes that cause the columns to be whole numbers to avoid rounding precision issues as was previously seen. Additionally, the fractional widths now compute to values without repeating decimals, which contributes to the final widths being more consistent across browsers. ## ๐Ÿงช Testing Ran `npm run test-chrome && npm run test-firefox && npm run test-webkit` with the test at hand focused and verified that the test passes in all three browsers ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --- ...nts-f0730b00-2a69-4d06-8241-d97c34bf98b1.json | 7 +++++++ .../src/table/tests/table-column-sizing.spec.ts | 16 +++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json diff --git a/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json b/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json new file mode 100644 index 0000000000..177079b66d --- /dev/null +++ b/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Fix column sizing test to pass in webkit", + "packageName": "@ni/nimble-components", + "email": "20542556+mollykreis@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/packages/nimble-components/src/table/tests/table-column-sizing.spec.ts b/packages/nimble-components/src/table/tests/table-column-sizing.spec.ts index 56012c72c5..3b32cfa666 100644 --- a/packages/nimble-components/src/table/tests/table-column-sizing.spec.ts +++ b/packages/nimble-components/src/table/tests/table-column-sizing.spec.ts @@ -495,16 +495,18 @@ describe('Table Interactive Column Sizing', () => { expect(pageObject.isHorizontalScrollbarVisible()).toBeTrue(); }); - // WebKit skipped, see https://github.com/ni/nimble/issues/1939 - it('sizing table with a horizontal scrollbar does not change column widths until sized beyond current column pixel widths #SkipWebkit', async () => { - // create horizontal scrollbar with total column width of 450 - pageObject.dragSizeColumnByRightDivider(2, [100]); + it('sizing table with a horizontal scrollbar does not change column widths until sized beyond current column pixel widths', async () => { + // Create a horizontal scrollbar with a total column width of 500. This updates the columns' + // current fractional widths to 0.8, 0.8, 2, and 0.4, which keeps the columns widths as + // integers when the table is resized later in the test. Otherwise, different browsers + // may have slightly different rounding behaviors. + pageObject.dragSizeColumnByRightDivider(2, [150]); // size table below threshhold of total column widths await pageObject.sizeTableToGivenRowWidth(425, element); - expect(pageObject.getTotalCellRenderedWidth()).toBe(450); - // size table 50 pixels beyond total column widths - await pageObject.sizeTableToGivenRowWidth(500, element); expect(pageObject.getTotalCellRenderedWidth()).toBe(500); + // size table 100 pixels beyond total column widths + await pageObject.sizeTableToGivenRowWidth(600, element); + expect(pageObject.getTotalCellRenderedWidth()).toBe(600); expect(pageObject.isHorizontalScrollbarVisible()).toBeFalse(); }); From ab05b69d516175867402d8399015e38cfe078209 Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Thu, 21 Mar 2024 16:25:39 +0000 Subject: [PATCH 08/18] applying package updates [skip ci] --- ...ents-f0730b00-2a69-4d06-8241-d97c34bf98b1.json | 7 ------- packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 7 deletions(-) delete mode 100644 change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json diff --git a/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json b/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json deleted file mode 100644 index 177079b66d..0000000000 --- a/change/@ni-nimble-components-f0730b00-2a69-4d06-8241-d97c34bf98b1.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Fix column sizing test to pass in webkit", - "packageName": "@ni/nimble-components", - "email": "20542556+mollykreis@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index 7c3c87ef3a..bfdac4cd9d 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Thu, 21 Mar 2024 16:25:39 GMT", + "version": "22.1.1", + "tag": "@ni/nimble-components_v22.1.1", + "comments": { + "none": [ + { + "author": "20542556+mollykreis@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "7e52ce24569e94af5282b4b77f34608211cf74c9", + "comment": "Fix column sizing test to pass in webkit" + } + ] + } + }, { "date": "Thu, 21 Mar 2024 00:31:13 GMT", "version": "22.1.1", From b93385a27672ebc03e18a864e8fa268727595c66 Mon Sep 17 00:00:00 2001 From: Fred Visser <1458528+fredvisser@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:54:37 -0500 Subject: [PATCH 09/18] Add BodyPlus1 font token (and Body_2 base token) (#1944) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale in PR #1836 **BodyEmphasizedPlus1** font was added to try and address #1831. This PR fixes #1831 by adding a token for **BodyPlus1** and updating the previously added token name in a breaking change to be **BodyPlus1Emphasized**. Also updated the token suffixes list to treat `DisabledFontColor` as a `token_type` ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation Followed the Theme-aware tokens contributing docs. ## ๐Ÿงช Testing Manual review of Storybook token stories. ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Milan Raj <rajsite@users.noreply.github.com> --- ...-6e819e6f-2633-43f7-8e29-c38c7850ee59.json | 7 ++ ...-22976edc-9923-4946-87ba-6eee7aef6eed.json | 7 ++ .../theme-provider/design-token-comments.ts | 42 ++++++---- .../src/theme-provider/design-token-names.ts | 47 ++++++----- .../src/theme-provider/design-tokens.ts | 81 ++++++++++++------- .../theme-provider/tests/tokens.stories.ts | 1 + .../styledictionary/properties/fonts.json | 11 +++ .../styledictionary/properties/sizes.json | 3 + 8 files changed, 136 insertions(+), 63 deletions(-) create mode 100644 change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json create mode 100644 change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json diff --git a/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json b/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json new file mode 100644 index 0000000000..f29be2e94a --- /dev/null +++ b/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json @@ -0,0 +1,7 @@ +{ + "type": "major", + "comment": "Breaking change: Renamed bodyEmphasizedPlus1 to bodyPlus1Emphasized to align with token conventions. Also, added bodyPlus1 font token", + "packageName": "@ni/nimble-components", + "email": "1458528+fredvisser@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json b/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json new file mode 100644 index 0000000000..b29cdc7260 --- /dev/null +++ b/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Add Body_2 base font token", + "packageName": "@ni/nimble-tokens", + "email": "1458528+fredvisser@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/nimble-components/src/theme-provider/design-token-comments.ts b/packages/nimble-components/src/theme-provider/design-token-comments.ts index 7e38139d14..945379c8bf 100644 --- a/packages/nimble-components/src/theme-provider/design-token-comments.ts +++ b/packages/nimble-components/src/theme-provider/design-token-comments.ts @@ -210,6 +210,14 @@ export const comments: { readonly [key in TokenName]: string | null } = { 'Font line height for the "Placeholder" base token', placeholderFallbackFontFamily: 'Fallback font family for the "Placeholder" base token', + bodyFont: 'Font shorthand for the "Body" base token', + bodyFontColor: 'Font color for the "Body" base token', + bodyDisabledFontColor: 'Disabled font color for the "Body" base token', + bodyFontFamily: 'Font family for the "Body" base token', + bodyFontSize: 'Font size for the "Body" base token', + bodyFontWeight: 'Font weight for the "Body" base token', + bodyFontLineHeight: 'Font line height for the "Body" base token', + bodyFallbackFontFamily: 'Fallback font family for the "Body" base token', bodyEmphasizedFont: 'Font shorthand for the "BodyEmphasized" base token', bodyEmphasizedFontColor: 'Font color for the "BodyEmphasized" base token', bodyEmphasizedDisabledFontColor: @@ -221,30 +229,32 @@ export const comments: { readonly [key in TokenName]: string | null } = { 'Font line height for the "BodyEmphasized" base token', bodyEmphasizedFallbackFontFamily: 'Fallback font family for the "BodyEmphasized" base token', - bodyEmphasizedPlus1Font: + bodyPlus1Font: 'Font shorthand for the "Body_2" base token', + bodyPlus1FontColor: 'Font color for the "Body_2" base token', + bodyPlus1DisabledFontColor: + 'Disabled font color for the "Body_2" base token', + bodyPlus1FontFamily: 'Font family for the "Body_2" base token', + bodyPlus1FontSize: 'Font size for the "Body_2" base token', + bodyPlus1FontWeight: 'Font weight for the "Body_2" base token', + bodyPlus1FontLineHeight: 'Font line height for the "Body_2" base token', + bodyPlus1FallbackFontFamily: + 'Fallback font family for the "Body_2" base token', + bodyPlus1EmphasizedFont: 'Font shorthand for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FontColor: + bodyPlus1EmphasizedFontColor: 'Font color for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1DisabledFontColor: + bodyPlus1EmphasizedDisabledFontColor: 'Disabled font color for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FontFamily: + bodyPlus1EmphasizedFontFamily: 'Font family for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FontSize: + bodyPlus1EmphasizedFontSize: 'Font size for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FontWeight: + bodyPlus1EmphasizedFontWeight: 'Font weight for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FontLineHeight: + bodyPlus1EmphasizedFontLineHeight: 'Font line height for the "BodyEmphasized_2" base token', - bodyEmphasizedPlus1FallbackFontFamily: + bodyPlus1EmphasizedFallbackFontFamily: 'Fallback font family for the "BodyEmphasized_2" base token', - bodyFont: 'Font shorthand for the "Body" base token', - bodyFontColor: 'Font color for the "Body" base token', - bodyDisabledFontColor: 'Disabled font color for the "Body" base token', - bodyFontFamily: 'Font family for the "Body" base token', - bodyFontSize: 'Font size for the "Body" base token', - bodyFontWeight: 'Font weight for the "Body" base token', - bodyFontLineHeight: 'Font line height for the "Body" base token', - bodyFallbackFontFamily: 'Fallback font family for the "Body" base token', groupHeaderFont: 'Font shorthand for the "Group_Header_1" base token', groupHeaderFontColor: 'Font color for the "Group_Header_1" base token', groupHeaderDisabledFontColor: diff --git a/packages/nimble-components/src/theme-provider/design-token-names.ts b/packages/nimble-components/src/theme-provider/design-token-names.ts index 3725fadbba..02900b47d5 100644 --- a/packages/nimble-components/src/theme-provider/design-token-names.ts +++ b/packages/nimble-components/src/theme-provider/design-token-names.ts @@ -169,25 +169,6 @@ export const tokenNames: { readonly [key in TokenName]: string } = { placeholderFontWeight: 'placeholder-font-weight', placeholderFontLineHeight: 'placeholder-font-line-height', placeholderFallbackFontFamily: 'placeholder-fallback-font-family', - bodyEmphasizedFont: 'body-emphasized-font', - bodyEmphasizedFontColor: 'body-emphasized-font-color', - bodyEmphasizedDisabledFontColor: 'body-emphasized-disabled-font-color', - bodyEmphasizedFontFamily: 'body-emphasized-font-family', - bodyEmphasizedFontSize: 'body-emphasized-font-size', - bodyEmphasizedFontWeight: 'body-emphasized-font-weight', - bodyEmphasizedFontLineHeight: 'body-emphasized-font-line-height', - bodyEmphasizedFallbackFontFamily: 'body-emphasized-fallback-font-family', - bodyEmphasizedPlus1Font: 'body-emphasized-plus-1-font', - bodyEmphasizedPlus1FontColor: 'body-emphasized-plus-1-font-color', - bodyEmphasizedPlus1DisabledFontColor: - 'body-emphasized-plus-1-disabled-font-color', - bodyEmphasizedPlus1FontFamily: 'body-emphasized-plus-1-font-family', - bodyEmphasizedPlus1FontSize: 'body-emphasized-plus-1-font-size', - bodyEmphasizedPlus1FontWeight: 'body-emphasized-plus-1-font-weight', - bodyEmphasizedPlus1FontLineHeight: - 'body-emphasized-plus-1-font-line-height', - bodyEmphasizedPlus1FallbackFontFamily: - 'body-emphasized-plus-1-fallback-font-family', bodyFont: 'body-font', bodyFontColor: 'body-font-color', bodyDisabledFontColor: 'body-disabled-font-color', @@ -196,6 +177,33 @@ export const tokenNames: { readonly [key in TokenName]: string } = { bodyFontWeight: 'body-font-weight', bodyFontLineHeight: 'body-font-line-height', bodyFallbackFontFamily: 'body-fallback-font-family', + bodyEmphasizedFont: 'body-emphasized-font', + bodyEmphasizedFontColor: 'body-emphasized-font-color', + bodyEmphasizedDisabledFontColor: 'body-emphasized-disabled-font-color', + bodyEmphasizedFontFamily: 'body-emphasized-font-family', + bodyEmphasizedFontSize: 'body-emphasized-font-size', + bodyEmphasizedFontWeight: 'body-emphasized-font-weight', + bodyEmphasizedFontLineHeight: 'body-emphasized-font-line-height', + bodyEmphasizedFallbackFontFamily: 'body-emphasized-fallback-font-family', + bodyPlus1Font: 'body-plus-1-font', + bodyPlus1FontColor: 'body-plus-1-font-color', + bodyPlus1DisabledFontColor: 'body-plus-1-disabled-font-color', + bodyPlus1FontFamily: 'body-plus-1-font-family', + bodyPlus1FontSize: 'body-plus-1-font-size', + bodyPlus1FontWeight: 'body-plus-1-font-weight', + bodyPlus1FontLineHeight: 'body-plus-1-font-line-height', + bodyPlus1FallbackFontFamily: 'body-plus-1-fallback-font-family', + bodyPlus1EmphasizedFont: 'body-plus-1-emphasized-font', + bodyPlus1EmphasizedFontColor: 'body-plus-1-emphasized-font-color', + bodyPlus1EmphasizedDisabledFontColor: + 'body-plus-1-emphasized-disabled-font-color', + bodyPlus1EmphasizedFontFamily: 'body-plus-1-emphasized-font-family', + bodyPlus1EmphasizedFontSize: 'body-plus-1-emphasized-font-size', + bodyPlus1EmphasizedFontWeight: 'body-plus-1-emphasized-font-weight', + bodyPlus1EmphasizedFontLineHeight: + 'body-plus-1-emphasized-font-line-height', + bodyPlus1EmphasizedFallbackFontFamily: + 'body-plus-1-emphasized-fallback-font-family', groupHeaderFont: 'group-header-font', groupHeaderFontColor: 'group-header-font-color', groupHeaderDisabledFontColor: 'group-header-disabled-font-color', @@ -270,6 +278,7 @@ export const scssInternalPropertySetterMarkdown = ( // Order of suffixes in the array matter, as we want single word suffixes after the multi-word ones const tokenSuffixes = [ 'RgbPartialColor', + 'DisabledFontColor', 'FontColor', 'FontLineHeight', 'FontWeight', diff --git a/packages/nimble-components/src/theme-provider/design-tokens.ts b/packages/nimble-components/src/theme-provider/design-tokens.ts index 0261fe694d..015722a783 100644 --- a/packages/nimble-components/src/theme-provider/design-tokens.ts +++ b/packages/nimble-components/src/theme-provider/design-tokens.ts @@ -23,6 +23,9 @@ import { BodyFamily, BodySize, BodyWeight, + Body2Family, + Body2Size, + Body2Weight, ControlLabel1Family, ControlLabel1Size, ControlLabel1Weight, @@ -83,6 +86,7 @@ import { BodyEmphasizedLineHeight, BodyEmphasized2LineHeight, BodyLineHeight, + Body2LineHeight, GroupLabel1LineHeight, ControlLabel1LineHeight, ButtonLabel1LineHeight, @@ -118,6 +122,7 @@ const Subtitle2FallbackFontFamily = 'Source Sans Pro Fallback'; const LinkFallbackFontFamily = 'Source Sans Pro Fallback'; const PlaceholderFallbackFontFamily = 'Source Sans Pro Fallback'; const BodyFallbackFontFamily = 'Source Sans Pro Fallback'; +const Body2FallbackFontFamily = 'Source Sans Pro Fallback'; const BodyEmphasizedFallbackFontFamily = 'Source Sans Pro Fallback'; const BodyEmphasized2FallbackFontFamily = 'Source Sans Pro Fallback'; const GroupLabel1FallbackFontFamily = 'Source Sans Pro Fallback'; @@ -627,6 +632,26 @@ export const [ PlaceholderFallbackFontFamily ); +export const [ + bodyFont, + bodyFontColor, + bodyDisabledFontColor, + bodyFontFamily, + bodyFontWeight, + bodyFontSize, + bodyFontLineHeight, + bodyFallbackFontFamily +] = createFontTokens( + tokenNames.bodyFont, + (element: HTMLElement) => getDefaultFontColorForTheme(element), + (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), + BodyFamily, + BodyWeight, + BodySize, + BodyLineHeight, + BodyFallbackFontFamily +); + export const [ bodyEmphasizedFont, bodyEmphasizedFontColor, @@ -648,43 +673,43 @@ export const [ ); export const [ - bodyEmphasizedPlus1Font, - bodyEmphasizedPlus1FontColor, - bodyEmphasizedPlus1DisabledFontColor, - bodyEmphasizedPlus1FontFamily, - bodyEmphasizedPlus1FontWeight, - bodyEmphasizedPlus1FontSize, - bodyEmphasizedPlus1FontLineHeight, - bodyEmphasizedPlus1FallbackFontFamily + bodyPlus1Font, + bodyPlus1FontColor, + bodyPlus1DisabledFontColor, + bodyPlus1FontFamily, + bodyPlus1FontWeight, + bodyPlus1FontSize, + bodyPlus1FontLineHeight, + bodyPlus1FallbackFontFamily ] = createFontTokens( - tokenNames.bodyEmphasizedPlus1Font, + tokenNames.bodyPlus1Font, (element: HTMLElement) => getDefaultFontColorForTheme(element), (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), - BodyEmphasized2Family, - BodyEmphasized2Weight, - BodyEmphasized2Size, - BodyEmphasized2LineHeight, - BodyEmphasized2FallbackFontFamily + Body2Family, + Body2Weight, + Body2Size, + Body2LineHeight, + Body2FallbackFontFamily ); export const [ - bodyFont, - bodyFontColor, - bodyDisabledFontColor, - bodyFontFamily, - bodyFontWeight, - bodyFontSize, - bodyFontLineHeight, - bodyFallbackFontFamily + bodyPlus1EmphasizedFont, + bodyPlus1EmphasizedFontColor, + bodyPlus1EmphasizedDisabledFontColor, + bodyPlus1EmphasizedFontFamily, + bodyPlus1EmphasizedFontWeight, + bodyPlus1EmphasizedFontSize, + bodyPlus1EmphasizedFontLineHeight, + bodyPlus1EmphasizedFallbackFontFamily ] = createFontTokens( - tokenNames.bodyFont, + tokenNames.bodyPlus1EmphasizedFont, (element: HTMLElement) => getDefaultFontColorForTheme(element), (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), - BodyFamily, - BodyWeight, - BodySize, - BodyLineHeight, - BodyFallbackFontFamily + BodyEmphasized2Family, + BodyEmphasized2Weight, + BodyEmphasized2Size, + BodyEmphasized2LineHeight, + BodyEmphasized2FallbackFontFamily ); export const [ diff --git a/packages/nimble-components/src/theme-provider/tests/tokens.stories.ts b/packages/nimble-components/src/theme-provider/tests/tokens.stories.ts index 595f922d0f..5c84b9fb61 100644 --- a/packages/nimble-components/src/theme-provider/tests/tokens.stories.ts +++ b/packages/nimble-components/src/theme-provider/tests/tokens.stories.ts @@ -96,6 +96,7 @@ const tokenTemplates: { } = { Color: colorTemplate, RgbPartialColor: rgbColorTemplate, + DisabledFontColor: colorTemplate, FontColor: colorTemplate, FontLineHeight: stringValueTemplate, FontWeight: stringValueTemplate, diff --git a/packages/nimble-tokens/source/styledictionary/properties/fonts.json b/packages/nimble-tokens/source/styledictionary/properties/fonts.json index 4745cd3608..9e43932adf 100644 --- a/packages/nimble-tokens/source/styledictionary/properties/fonts.json +++ b/packages/nimble-tokens/source/styledictionary/properties/fonts.json @@ -24,6 +24,14 @@ "value": "Regular" } }, + "Body_2": { + "family": { + "value": "Source Sans Pro" + }, + "weight": { + "value": "Regular" + } + }, "Header0": { "family": { "value": "Noto Serif" @@ -260,6 +268,9 @@ "Body": { "value": "14" }, + "Body_2": { + "value": "16" + }, "Header0": { "value": "36" }, diff --git a/packages/nimble-tokens/source/styledictionary/properties/sizes.json b/packages/nimble-tokens/source/styledictionary/properties/sizes.json index 97d1a1fa25..0b6de7129d 100644 --- a/packages/nimble-tokens/source/styledictionary/properties/sizes.json +++ b/packages/nimble-tokens/source/styledictionary/properties/sizes.json @@ -3,6 +3,9 @@ "Body-line-height": { "value": "18" }, + "Body_2-line-height": { + "value": "16" + }, "ControlLabel_1-line-height": { "value": "16" }, From 0025e151b7c1896cba37307a2a7c0a1b50de8379 Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:13:38 +0000 Subject: [PATCH 10/18] applying package updates [skip ci] --- .../projects/ni/nimble-angular/CHANGELOG.json | 15 +++++++++++++ .../projects/ni/nimble-angular/CHANGELOG.md | 10 ++++++++- .../projects/ni/nimble-angular/package.json | 4 ++-- ...-6e819e6f-2633-43f7-8e29-c38c7850ee59.json | 7 ------- ...-22976edc-9923-4946-87ba-6eee7aef6eed.json | 7 ------- package-lock.json | 12 +++++------ packages/nimble-blazor/package.json | 2 +- packages/nimble-components/CHANGELOG.json | 21 +++++++++++++++++++ packages/nimble-components/CHANGELOG.md | 11 +++++++++- packages/nimble-components/package.json | 4 ++-- packages/nimble-tokens/CHANGELOG.json | 15 +++++++++++++ packages/nimble-tokens/CHANGELOG.md | 10 ++++++++- packages/nimble-tokens/package.json | 2 +- 13 files changed, 91 insertions(+), 29 deletions(-) delete mode 100644 change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json delete mode 100644 change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json index f170144ec8..c95bf7331b 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-angular", "entries": [ + { + "date": "Thu, 21 Mar 2024 17:13:38 GMT", + "version": "20.5.2", + "tag": "@ni/nimble-angular_v20.5.2", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@ni/nimble-angular", + "comment": "Bump @ni/nimble-components to v23.0.0", + "commit": "not available" + } + ] + } + }, { "date": "Wed, 20 Mar 2024 16:45:59 GMT", "version": "20.5.1", diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md index 1a2aa3c1ca..3a4d8e308d 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-angular -This log was last generated on Wed, 20 Mar 2024 16:45:59 GMT and should not be manually modified. +This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. <!-- Start content --> +## 20.5.2 + +Thu, 21 Mar 2024 17:13:38 GMT + +### Patches + +- Bump @ni/nimble-components to v23.0.0 + ## 20.5.1 Wed, 20 Mar 2024 16:45:59 GMT diff --git a/angular-workspace/projects/ni/nimble-angular/package.json b/angular-workspace/projects/ni/nimble-angular/package.json index cc13ba5b80..b6db60197e 100644 --- a/angular-workspace/projects/ni/nimble-angular/package.json +++ b/angular-workspace/projects/ni/nimble-angular/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-angular", - "version": "20.5.1", + "version": "20.5.2", "description": "Angular components for the NI Nimble Design System", "scripts": { "invoke-publish": "cd ../../../ && npm run build:library && cd dist/ni/nimble-angular && npm publish" @@ -31,7 +31,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^22.1.1" + "@ni/nimble-components": "^23.0.0" }, "dependencies": { "tslib": "^2.2.0" diff --git a/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json b/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json deleted file mode 100644 index f29be2e94a..0000000000 --- a/change/@ni-nimble-components-6e819e6f-2633-43f7-8e29-c38c7850ee59.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "major", - "comment": "Breaking change: Renamed bodyEmphasizedPlus1 to bodyPlus1Emphasized to align with token conventions. Also, added bodyPlus1 font token", - "packageName": "@ni/nimble-components", - "email": "1458528+fredvisser@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json b/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json deleted file mode 100644 index b29cdc7260..0000000000 --- a/change/@ni-nimble-tokens-22976edc-9923-4946-87ba-6eee7aef6eed.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "minor", - "comment": "Add Body_2 base font token", - "packageName": "@ni/nimble-tokens", - "email": "1458528+fredvisser@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/package-lock.json b/package-lock.json index f8fe26c4e2..c045478cf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ }, "angular-workspace/projects/ni/nimble-angular": { "name": "@ni/nimble-angular", - "version": "20.5.1", + "version": "20.5.2", "license": "MIT", "dependencies": { "tslib": "^2.2.0" @@ -85,7 +85,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^22.1.1" + "@ni/nimble-components": "^23.0.0" } }, "node_modules/@11ty/dependency-tree": { @@ -33939,7 +33939,7 @@ }, "packages/nimble-blazor": { "name": "@ni/nimble-blazor", - "version": "14.5.1", + "version": "14.5.2", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -33975,14 +33975,14 @@ }, "packages/nimble-components": { "name": "@ni/nimble-components", - "version": "22.1.1", + "version": "23.0.0", "license": "MIT", "dependencies": { "@microsoft/fast-colors": "^5.3.1", "@microsoft/fast-element": "^1.12.0", "@microsoft/fast-foundation": "2.49.4", "@microsoft/fast-web-utilities": "^6.0.0", - "@ni/nimble-tokens": "^6.12.1", + "@ni/nimble-tokens": "^6.13.0", "@tanstack/table-core": "^8.10.7", "@tanstack/virtual-core": "^3.0.0-beta.68", "@tiptap/core": "^2.2.2", @@ -34974,7 +34974,7 @@ }, "packages/nimble-tokens": { "name": "@ni/nimble-tokens", - "version": "6.12.1", + "version": "6.13.0", "license": "MIT", "devDependencies": { "@microsoft/fast-colors": "^5.3.1", diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index ff76936429..a496b2b43e 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-blazor", - "version": "14.5.1", + "version": "14.5.2", "description": "Blazor components for the NI Nimble Design System", "scripts": { "postinstall": "node build/generate-playwright-version-properties/source/index.js", diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index bfdac4cd9d..df4d30114b 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Thu, 21 Mar 2024 17:13:38 GMT", + "version": "23.0.0", + "tag": "@ni/nimble-components_v23.0.0", + "comments": { + "major": [ + { + "author": "1458528+fredvisser@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "b93385a27672ebc03e18a864e8fa268727595c66", + "comment": "Breaking change: Renamed bodyEmphasizedPlus1 to bodyPlus1Emphasized to align with token conventions. Also, added bodyPlus1 font token" + }, + { + "author": "beachball", + "package": "@ni/nimble-components", + "comment": "Bump @ni/nimble-tokens to v6.13.0", + "commit": "not available" + } + ] + } + }, { "date": "Thu, 21 Mar 2024 16:25:39 GMT", "version": "22.1.1", diff --git a/packages/nimble-components/CHANGELOG.md b/packages/nimble-components/CHANGELOG.md index 8825f33110..a3208751fb 100644 --- a/packages/nimble-components/CHANGELOG.md +++ b/packages/nimble-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @ni/nimble-components -This log was last generated on Wed, 20 Mar 2024 16:45:59 GMT and should not be manually modified. +This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. <!-- Start content --> +## 23.0.0 + +Thu, 21 Mar 2024 17:13:38 GMT + +### Major changes + +- Breaking change: Renamed bodyEmphasizedPlus1 to bodyPlus1Emphasized to align with token conventions. Also, added bodyPlus1 font token ([ni/nimble@b93385a](https://github.com/ni/nimble/commit/b93385a27672ebc03e18a864e8fa268727595c66)) +- Bump @ni/nimble-tokens to v6.13.0 + ## 22.1.1 Wed, 20 Mar 2024 16:45:59 GMT diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index eedf89911c..d23d40c7e5 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-components", - "version": "22.1.1", + "version": "23.0.0", "description": "Styled web components for the NI Nimble Design System", "scripts": { "build": "npm run generate-icons && npm run generate-workers && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", @@ -68,7 +68,7 @@ "@microsoft/fast-element": "^1.12.0", "@microsoft/fast-foundation": "2.49.4", "@microsoft/fast-web-utilities": "^6.0.0", - "@ni/nimble-tokens": "^6.12.1", + "@ni/nimble-tokens": "^6.13.0", "@tanstack/table-core": "^8.10.7", "@tanstack/virtual-core": "^3.0.0-beta.68", "@tiptap/core": "^2.2.2", diff --git a/packages/nimble-tokens/CHANGELOG.json b/packages/nimble-tokens/CHANGELOG.json index 4b32d99095..089330fec9 100644 --- a/packages/nimble-tokens/CHANGELOG.json +++ b/packages/nimble-tokens/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-tokens", "entries": [ + { + "date": "Thu, 21 Mar 2024 17:13:38 GMT", + "version": "6.13.0", + "tag": "@ni/nimble-tokens_v6.13.0", + "comments": { + "minor": [ + { + "author": "1458528+fredvisser@users.noreply.github.com", + "package": "@ni/nimble-tokens", + "commit": "b93385a27672ebc03e18a864e8fa268727595c66", + "comment": "Add Body_2 base font token" + } + ] + } + }, { "date": "Tue, 12 Mar 2024 21:01:54 GMT", "version": "6.12.1", diff --git a/packages/nimble-tokens/CHANGELOG.md b/packages/nimble-tokens/CHANGELOG.md index 1640ba454b..def2a83a56 100644 --- a/packages/nimble-tokens/CHANGELOG.md +++ b/packages/nimble-tokens/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-tokens -This log was last generated on Tue, 12 Mar 2024 21:01:54 GMT and should not be manually modified. +This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. <!-- Start content --> +## 6.13.0 + +Thu, 21 Mar 2024 17:13:38 GMT + +### Minor changes + +- Add Body_2 base font token ([ni/nimble@b93385a](https://github.com/ni/nimble/commit/b93385a27672ebc03e18a864e8fa268727595c66)) + ## 6.12.1 Tue, 12 Mar 2024 21:01:54 GMT diff --git a/packages/nimble-tokens/package.json b/packages/nimble-tokens/package.json index c44fcb3619..afefbfb147 100644 --- a/packages/nimble-tokens/package.json +++ b/packages/nimble-tokens/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-tokens", - "version": "6.12.1", + "version": "6.13.0", "description": "Design tokens for the NI Nimble Design System", "scripts": { "build": "npm run build:svg-to-ts && npm run build:ts && npm run build:svg-to-ico && npm run build:generate-font-scss && npm run build:style-dictionary", From 9c6adb41673c9bfbd3284e499d72b8199679c9ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Mar 2024 19:24:41 +0000 Subject: [PATCH 11/18] Update dependency webpack-dev-middleware to v7.1.0 [SECURITY] (#1957) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com) This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [webpack-dev-middleware](https://togithub.com/webpack/webpack-dev-middleware) | [`7.0.0` -> `7.1.0`](https://renovatebot.com/diffs/npm/webpack-dev-middleware/7.0.0/7.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/webpack-dev-middleware/7.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/webpack-dev-middleware/7.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/webpack-dev-middleware/7.0.0/7.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/webpack-dev-middleware/7.0.0/7.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | ### GitHub Vulnerability Alerts #### [CVE-2024-29180](https://togithub.com/webpack/webpack-dev-middleware/security/advisories/GHSA-wr3j-pwj9-hqq6) ### Summary _The **webpack-dev-middleware** middleware does not validate the supplied URL address sufficiently before returning the local file. It is possible to access any file on the developer's machine._ ### Details The middleware can either work with the physical filesystem when reading the files or it can use a virtualized in-memory _memfs_ filesystem. If _writeToDisk_ configuration option is set to **true**, the physical filesystem is used: [https://github.com/webpack/webpack-dev-middleware/blob/7ed24e0b9f53ad1562343f9f517f0f0ad2a70377/src/utils/setupOutputFileSystem.js#L21](https://togithub.com/webpack/webpack-dev-middleware/blob/7ed24e0b9f53ad1562343f9f517f0f0ad2a70377/src/utils/setupOutputFileSystem.js#L21) The _**getFilenameFromUrl**_ method is used to parse URL and build the local file path. The public path prefix is stripped from the URL, and the **unsecaped** path suffix is appended to the _outputPath_: [https://github.com/webpack/webpack-dev-middleware/blob/7ed24e0b9f53ad1562343f9f517f0f0ad2a70377/src/utils/getFilenameFromUrl.js#L82](https://togithub.com/webpack/webpack-dev-middleware/blob/7ed24e0b9f53ad1562343f9f517f0f0ad2a70377/src/utils/getFilenameFromUrl.js#L82) As the URL is not unescaped and normalized automatically before calling the midlleware, it is possible to use _%2e_ and _%2f_ sequences to perform path traversal attack. ### PoC _A blank project can be created containing the following configuration file **webpack.config.js**:_ `module.exports = { devServer: { devMiddleware: { writeToDisk: true } } }; ` When started, it is possible to access any local file, e.g. _/etc/passwd_: `$ curl localhost:8080/public/..%2f..%2f..%2f..%2f../etc/passwd` ``` root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin ``` ### Impact The developers using _webpack-dev-server_ or _webpack-dev-middleware_ are affected by the issue. When the project is started, an attacker might access any file on the developer's machine and exfiltrate the content (e.g. password, configuration files, private source code, ...). If the development server is listening on a public IP address (or **0.0.0.0**), an attacker on the local network can access the local files without any interaction from the victim (direct connection to the port). If the server allows access from third-party domains (CORS, **_Allow-Access-Origin: *_** ), an attacker can send a malicious link to the victim. When visited, the client side script can connect to the local server and exfiltrate the local files. ### Recommendation The URL should be unescaped and normalized before any further processing. --- ### Release Notes <details> <summary>webpack/webpack-dev-middleware (webpack-dev-middleware)</summary> ### [`v7.1.0`](https://togithub.com/webpack/webpack-dev-middleware/blob/HEAD/CHANGELOG.md#710-2024-03-19) [Compare Source](https://togithub.com/webpack/webpack-dev-middleware/compare/v7.0.0...v7.1.0) ##### Features - prefer to use `fs.createReadStream` over `fs.readFileSync` to read files ([ab533de](https://togithub.com/webpack/webpack-dev-middleware/commit/ab533de933c6684218172b86992f35c3ca6c58a4)) ##### Bug Fixes - cleaup stream and handle errors ([#​1769](https://togithub.com/webpack/webpack-dev-middleware/issues/1769)) ([1258fdd](https://togithub.com/webpack/webpack-dev-middleware/commit/1258fdd3d9c175dbacf6bc3b36d5c3c545738f13)) - **security:** do not allow to read files above ([#​1771](https://togithub.com/webpack/webpack-dev-middleware/issues/1771)) ([e10008c](https://togithub.com/webpack/webpack-dev-middleware/commit/e10008c762e4d5821ed6990348dabf0d4d93a10e)) </details> --- ### Configuration ๐Ÿ“… **Schedule**: Branch creation - "" (UTC), Automerge - At any time (no schedule defined). ๐Ÿšฆ **Automerge**: Disabled by config. Please merge this manually once you are satisfied. โ™ป **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. ๐Ÿ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://developer.mend.io/github/ni/nimble). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yNjEuMCIsInVwZGF0ZWRJblZlciI6IjM3LjI2MS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c045478cf7..feef610ba6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33062,14 +33062,15 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.0.0.tgz", - "integrity": "sha512-tZ5hqsWwww/8DislmrzXE3x+4f+v10H1z57mA2dWFrILb4i3xX+dPhTkcdR0DLyQztrhF2AUmO5nN085UYjd/Q==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.1.0.tgz", + "integrity": "sha512-+RYhGOyviHkKdMi1aaT8WZBQW033YgyBgtQHF2kMWo3mYA9z7W2AjsyY/DIzvp2Bhzys4UgHXFsIyTiL5qRBVw==", "dev": true, "dependencies": { "colorette": "^2.0.10", "memfs": "^4.6.0", "mime-types": "^2.1.31", + "on-finished": "^2.4.1", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" }, @@ -33090,9 +33091,9 @@ } }, "node_modules/webpack-dev-middleware/node_modules/memfs": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.7.7.tgz", - "integrity": "sha512-x9qc6k88J/VVwnfTkJV8pRRswJ2156Rc4w5rciRqKceFDZ0y1MqsNL9pkg5sE0GOcDzZYbonreALhaHzg1siFw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.8.0.tgz", + "integrity": "sha512-fcs7trFxZlOMadmTw5nyfOwS3il9pr3y+6xzLfXNwmuR/D0i4wz6rJURxArAbcJDGalbpbMvQ/IFI0NojRZgRg==", "dev": true, "dependencies": { "tslib": "^2.0.0" @@ -34075,7 +34076,7 @@ "typescript": "~4.9.5", "webpack": "^5.75.0", "webpack-cli": "^5.0.1", - "webpack-dev-middleware": "^7.0.0" + "webpack-dev-middleware": "^7.1.0" }, "peerDependencies": { "apache-arrow": "^15.0.0" From 559c12f4b5eaae8fdbd18c6c0d2ecff097b699d5 Mon Sep 17 00:00:00 2001 From: Jesse Attas <jattasNI@users.noreply.github.com> Date: Fri, 22 Mar 2024 11:01:27 -0500 Subject: [PATCH 12/18] Manually update Plawright to 1.42.0 (#1956) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale #1747 has a recurring maintenance task to update the version of Playwright to the latest version that's available in npm and Nuget. We were on 1.40.0, the [latest on npm is 1.42.1](https://www.npmjs.com/package/playwright?activeTab=versions), and the [latest on Nuget is 1.42.0](https://www.nuget.org/packages/Microsoft.Playwright) [Detailed release notes](https://github.com/microsoft/playwright/releases). ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation 1. Searched for "1.40.0" in package.json files and updated to "1.42.0". 2. Ran `npm install` to regenerate package-lock.json ## ๐Ÿงช Testing 1. Verified locally that `packages/nimble-blazor/build/generate-playwright-version-properties/dist/Playwright.PackageVersion.props` is regenerated and the build and test commands pass. 2. Otherwise relying on PR build ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [ ] I have updated the project documentation to reflect my changes or determined no changes are needed. --- angular-workspace/package.json | 2 +- ...-4980f072-e099-43f9-bc09-988fe020a990.json | 7 ++++++ ...-7dfea167-198f-4c22-be90-becd425aca89.json | 7 ++++++ ...-3a874011-8c0c-4ad0-97a8-2708b9de5807.json | 7 ++++++ package-lock.json | 24 +++++++++---------- package.json | 2 +- packages/jasmine-parameterized/package.json | 2 +- packages/nimble-blazor/package.json | 2 +- packages/nimble-components/package.json | 2 +- 9 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json create mode 100644 change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json create mode 100644 change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json diff --git a/angular-workspace/package.json b/angular-workspace/package.json index 8850fcb683..7173fbc48e 100644 --- a/angular-workspace/package.json +++ b/angular-workspace/package.json @@ -58,7 +58,7 @@ "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "ng-packagr": "^15.2.2", - "playwright": "1.40.0", + "playwright": "1.42.0", "rollup": "^4.12.0", "typescript": "~4.9.5" } diff --git a/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json b/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json new file mode 100644 index 0000000000..c08cefbec8 --- /dev/null +++ b/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Update Playwright dev dependency to 1.42.0", + "packageName": "@ni/jasmine-parameterized", + "email": "jattasNI@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json b/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json new file mode 100644 index 0000000000..7dfac2a62c --- /dev/null +++ b/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Update Playwright dev dependency to 1.42.0", + "packageName": "@ni/nimble-blazor", + "email": "jattasNI@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json b/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json new file mode 100644 index 0000000000..256fe5f003 --- /dev/null +++ b/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Update Playwright dev dependency to 1.42.0", + "packageName": "@ni/nimble-components", + "email": "jattasNI@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/package-lock.json b/package-lock.json index feef610ba6..b9c0adaf64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "beachball": "^2.31.0", "cross-env": "^7.0.3", "patch-package": "^8.0.0", - "playwright": "1.40.0" + "playwright": "1.42.0" } }, "angular-workspace": { @@ -67,7 +67,7 @@ "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "ng-packagr": "^15.2.2", - "playwright": "1.40.0", + "playwright": "1.42.0", "rollup": "^4.12.0", "typescript": "~4.9.5" } @@ -26482,12 +26482,12 @@ } }, "node_modules/playwright": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.0.tgz", - "integrity": "sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.42.0.tgz", + "integrity": "sha512-Ko7YRUgj5xBHbntrgt4EIw/nE//XBHOKVKnBjO1KuZkmkhlbgyggTe5s9hjqQ1LpN+Xg+kHsQyt5Pa0Bw5XpvQ==", "dev": true, "dependencies": { - "playwright-core": "1.40.0" + "playwright-core": "1.42.0" }, "bin": { "playwright": "cli.js" @@ -26500,9 +26500,9 @@ } }, "node_modules/playwright-core": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.0.tgz", - "integrity": "sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.42.0.tgz", + "integrity": "sha512-0HD9y8qEVlcbsAjdpBaFjmaTHf+1FeIddy8VJLeiqwhcNqGCBe4Wp2e8knpqiYbzxtxarxiXyNDw2cG8sCaNMQ==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -33934,7 +33934,7 @@ "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "karma-spec-reporter": "^0.0.36", - "playwright": "1.40.0", + "playwright": "1.42.0", "typescript": "~4.9.5" } }, @@ -33951,7 +33951,7 @@ "@rollup/plugin-node-resolve": "^15.0.1", "cross-env": "^7.0.3", "glob": "^10.3.10", - "playwright": "1.40.0", + "playwright": "1.42.0", "rimraf": "^5.0.5", "rollup": "^4.12.0" } @@ -34063,7 +34063,7 @@ "karma-spec-reporter": "^0.0.36", "karma-webkit-launcher": "^2.1.0", "karma-webpack": "^5.0.0", - "playwright": "1.40.0", + "playwright": "1.42.0", "prettier-eslint": "^16.3.0", "prettier-eslint-cli": "^8.0.1", "remark-gfm": "^3.0.1", diff --git a/package.json b/package.json index 69f6114952..a0cde29a26 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,6 @@ "beachball": "^2.31.0", "cross-env": "^7.0.3", "patch-package": "^8.0.0", - "playwright": "1.40.0" + "playwright": "1.42.0" } } diff --git a/packages/jasmine-parameterized/package.json b/packages/jasmine-parameterized/package.json index 5683dbbc83..f4888edaea 100644 --- a/packages/jasmine-parameterized/package.json +++ b/packages/jasmine-parameterized/package.json @@ -51,7 +51,7 @@ "karma-jasmine": "^5.1.0", "karma-jasmine-html-reporter": "^2.0.0", "karma-spec-reporter": "^0.0.36", - "playwright": "1.40.0", + "playwright": "1.42.0", "typescript": "~4.9.5" } } diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index a496b2b43e..85d6a32cc7 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -48,7 +48,7 @@ "@rollup/plugin-node-resolve": "^15.0.1", "cross-env": "^7.0.3", "glob": "^10.3.10", - "playwright": "1.40.0", + "playwright": "1.42.0", "rimraf": "^5.0.5", "rollup": "^4.12.0" } diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index d23d40c7e5..b2052a19b5 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -151,7 +151,7 @@ "karma-spec-reporter": "^0.0.36", "karma-webkit-launcher": "^2.1.0", "karma-webpack": "^5.0.0", - "playwright": "1.40.0", + "playwright": "1.42.0", "prettier-eslint": "^16.3.0", "prettier-eslint-cli": "^8.0.1", "remark-gfm": "^3.0.1", From 626b6c7460f70b835ae97d2b3d02e8472328fbea Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Fri, 22 Mar 2024 16:18:25 +0000 Subject: [PATCH 13/18] applying package updates [skip ci] --- ...ized-4980f072-e099-43f9-bc09-988fe020a990.json | 7 ------- ...azor-7dfea167-198f-4c22-be90-becd425aca89.json | 7 ------- ...ents-3a874011-8c0c-4ad0-97a8-2708b9de5807.json | 7 ------- package-lock.json | 2 +- packages/jasmine-parameterized/CHANGELOG.json | 15 +++++++++++++++ packages/nimble-blazor/CHANGELOG.json | 15 +++++++++++++++ packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ 7 files changed, 46 insertions(+), 22 deletions(-) delete mode 100644 change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json delete mode 100644 change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json delete mode 100644 change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json diff --git a/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json b/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json deleted file mode 100644 index c08cefbec8..0000000000 --- a/change/@ni-jasmine-parameterized-4980f072-e099-43f9-bc09-988fe020a990.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Update Playwright dev dependency to 1.42.0", - "packageName": "@ni/jasmine-parameterized", - "email": "jattasNI@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json b/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json deleted file mode 100644 index 7dfac2a62c..0000000000 --- a/change/@ni-nimble-blazor-7dfea167-198f-4c22-be90-becd425aca89.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Update Playwright dev dependency to 1.42.0", - "packageName": "@ni/nimble-blazor", - "email": "jattasNI@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json b/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json deleted file mode 100644 index 256fe5f003..0000000000 --- a/change/@ni-nimble-components-3a874011-8c0c-4ad0-97a8-2708b9de5807.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "none", - "comment": "Update Playwright dev dependency to 1.42.0", - "packageName": "@ni/nimble-components", - "email": "jattasNI@users.noreply.github.com", - "dependentChangeType": "none" -} diff --git a/package-lock.json b/package-lock.json index b9c0adaf64..46b53e8b5b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34076,7 +34076,7 @@ "typescript": "~4.9.5", "webpack": "^5.75.0", "webpack-cli": "^5.0.1", - "webpack-dev-middleware": "^7.1.0" + "webpack-dev-middleware": "^7.0.0" }, "peerDependencies": { "apache-arrow": "^15.0.0" diff --git a/packages/jasmine-parameterized/CHANGELOG.json b/packages/jasmine-parameterized/CHANGELOG.json index 62aadb0a18..b9f515edf9 100644 --- a/packages/jasmine-parameterized/CHANGELOG.json +++ b/packages/jasmine-parameterized/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/jasmine-parameterized", "entries": [ + { + "date": "Fri, 22 Mar 2024 16:18:25 GMT", + "version": "0.2.3", + "tag": "@ni/jasmine-parameterized_v0.2.3", + "comments": { + "none": [ + { + "author": "jattasNI@users.noreply.github.com", + "package": "@ni/jasmine-parameterized", + "commit": "559c12f4b5eaae8fdbd18c6c0d2ecff097b699d5", + "comment": "Update Playwright dev dependency to 1.42.0" + } + ] + } + }, { "date": "Tue, 12 Mar 2024 21:01:53 GMT", "version": "0.2.3", diff --git a/packages/nimble-blazor/CHANGELOG.json b/packages/nimble-blazor/CHANGELOG.json index bb6c73b2d4..4f5282b62b 100644 --- a/packages/nimble-blazor/CHANGELOG.json +++ b/packages/nimble-blazor/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-blazor", "entries": [ + { + "date": "Fri, 22 Mar 2024 16:18:25 GMT", + "version": "14.5.2", + "tag": "@ni/nimble-blazor_v14.5.2", + "comments": { + "none": [ + { + "author": "jattasNI@users.noreply.github.com", + "package": "@ni/nimble-blazor", + "commit": "559c12f4b5eaae8fdbd18c6c0d2ecff097b699d5", + "comment": "Update Playwright dev dependency to 1.42.0" + } + ] + } + }, { "date": "Mon, 18 Mar 2024 17:12:34 GMT", "version": "14.5.0", diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index df4d30114b..13aaa57ee5 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Fri, 22 Mar 2024 16:18:25 GMT", + "version": "23.0.0", + "tag": "@ni/nimble-components_v23.0.0", + "comments": { + "none": [ + { + "author": "jattasNI@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "559c12f4b5eaae8fdbd18c6c0d2ecff097b699d5", + "comment": "Update Playwright dev dependency to 1.42.0" + } + ] + } + }, { "date": "Thu, 21 Mar 2024 17:13:38 GMT", "version": "23.0.0", From f56b73b45161a55b967dc03bbdd094a6527c814c Mon Sep 17 00:00:00 2001 From: Natan Muntean <33986780+munteannatan@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:45:21 +0200 Subject: [PATCH 14/18] Wafer Map Experimental Event Coordinator (#1916) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale I tried to expand on the strategy switching mechanism from the renderer, and reused it in the coordinator This approach has the benefits of isolating the experimental code while in development, and an easy way to switch to the new version by changing just the imports and switching mechanism and removing the old versions after they become obsolete ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation because arquero causes typescript errors I implemented an alternative search and posted a PR with fixes in arquero repo https://github.com/uwdata/arquero/pull/346 changed the zoom handler to catch events on the component, not just the canvas removed zooming border of around 100px when zooming in the wafer after PO decision, resulting in less complex code and touch controls enabling. ## ๐Ÿงช Testing existing tests are passing created new hover unit tests with wafer and data manager mocks ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: rajsite <rajsite@users.noreply.github.com> --- ...-163379f4-09c6-4606-95f4-05917dd50ee0.json | 7 + .../nimble-components/src/wafer-map/index.ts | 78 ++++++-- .../src/wafer-map/modules/data-manager.ts | 6 +- .../wafer-map/modules/event-coordinator.ts | 47 ----- .../modules/experimental/hover-handler.ts | 98 ++++++++++ .../{ => experimental}/worker-renderer.ts | 4 +- .../src/wafer-map/modules/hover-handler.ts | 50 +++-- .../src/wafer-map/modules/prerendering.ts | 14 +- .../wafer-map/modules/wafer-map-validator.ts | 52 ++--- .../src/wafer-map/modules/zoom-handler.ts | 83 +++----- .../src/wafer-map/tests/computations.spec.ts | 13 +- .../src/wafer-map/tests/data-generator.ts | 2 +- .../src/wafer-map/tests/hover-handler.spec.ts | 114 +++++++++++ .../tests/prerendering.coloring.spec.ts | 182 ++++++++---------- .../tests/prerendering.labeling.spec.ts | 162 +++++++--------- .../tests/prerendering.positioning.spec.ts | 62 +++--- .../src/wafer-map/tests/sets.ts | 2 +- .../src/wafer-map/tests/utilities.ts | 93 +++++++-- .../tests/wafer-map-validator.spec.ts | 27 ++- .../src/wafer-map/tests/wafer-map.spec.ts | 48 +++-- .../src/wafer-map/tests/wafer-map.stories.ts | 4 +- .../nimble-components/src/wafer-map/types.ts | 21 ++ 22 files changed, 698 insertions(+), 471 deletions(-) create mode 100644 change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json delete mode 100644 packages/nimble-components/src/wafer-map/modules/event-coordinator.ts create mode 100644 packages/nimble-components/src/wafer-map/modules/experimental/hover-handler.ts rename packages/nimble-components/src/wafer-map/modules/{ => experimental}/worker-renderer.ts (95%) create mode 100644 packages/nimble-components/src/wafer-map/tests/hover-handler.spec.ts diff --git a/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json b/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json new file mode 100644 index 0000000000..7456d8a059 --- /dev/null +++ b/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Created new hover event for the new diesTable api and changed the zoom event", + "packageName": "@ni/nimble-components", + "email": "33986780+munteannatan@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/nimble-components/src/wafer-map/index.ts b/packages/nimble-components/src/wafer-map/index.ts index aed309664d..70c09e9b8d 100644 --- a/packages/nimble-components/src/wafer-map/index.ts +++ b/packages/nimble-components/src/wafer-map/index.ts @@ -10,19 +10,23 @@ import { template } from './template'; import { styles } from './styles'; import { DataManager } from './modules/data-manager'; import { RenderingModule } from './modules/rendering'; -import { EventCoordinator } from './modules/event-coordinator'; import { + HoverDie, HoverDieOpacity, WaferMapColorScale, WaferMapColorScaleMode, WaferMapDie, WaferMapOrientation, WaferMapOriginLocation, - WaferMapValidity + WaferMapValidity, + type WaferRequiredFields } from './types'; import { WaferMapUpdateTracker } from './modules/wafer-map-update-tracker'; import { WaferMapValidator } from './modules/wafer-map-validator'; -import { WorkerRenderer } from './modules/worker-renderer'; +import { WorkerRenderer } from './modules/experimental/worker-renderer'; +import { HoverHandler } from './modules/hover-handler'; +import { HoverHandler as ExperimentalHoverHandler } from './modules/experimental/hover-handler'; +import { ZoomHandler } from './modules/zoom-handler'; declare global { interface HTMLElementTagNameMap { @@ -33,12 +37,14 @@ declare global { /** * A nimble-styled WaferMap */ -export class WaferMap extends FoundationElement { +export class WaferMap< + T extends WaferRequiredFields = WaferRequiredFields +> extends FoundationElement { /** * @internal * needs to be initialized before the properties trigger changes */ - public readonly waferMapUpdateTracker = new WaferMapUpdateTracker(this); + public readonly waferMapUpdateTracker: WaferMapUpdateTracker = new WaferMapUpdateTracker(this.asRequiredFieldsWaferMap); @attr({ attribute: 'origin-location' }) public originLocation: WaferMapOriginLocation = WaferMapOriginLocation.bottomLeft; @@ -88,15 +94,23 @@ export class WaferMap extends FoundationElement { /** * @internal */ - public readonly dataManager = new DataManager(this); + public readonly dataManager: DataManager = new DataManager( + this.asRequiredFieldsWaferMap + ); + /** * @internal */ - public readonly mainRenderer = new RenderingModule(this); + public readonly mainRenderer = new RenderingModule( + this.asRequiredFieldsWaferMap + ); + /** * @internal */ - public readonly workerRenderer = new WorkerRenderer(this); + public readonly workerRenderer = new WorkerRenderer( + this.asRequiredFieldsWaferMap + ); @observable public renderer: RenderingModule | WorkerRenderer = this.mainRenderer; @@ -144,20 +158,29 @@ export class WaferMap extends FoundationElement { /** * @internal */ - @observable public hoverDie: WaferMapDie | undefined; + @observable public hoverDie: WaferMapDie | HoverDie | undefined; @observable public highlightedTags: string[] = []; @observable public dies: WaferMapDie[] = []; - @observable public diesTable: Table | undefined; + @observable public diesTable: Table<T> | undefined; @observable public colorScale: WaferMapColorScale = { colors: [], values: [] }; - private readonly eventCoordinator = new EventCoordinator(this); + private readonly hoverHandler: HoverHandler = new HoverHandler( + this.asRequiredFieldsWaferMap + ); + + private readonly experimentalHoverHandler: ExperimentalHoverHandler = new ExperimentalHoverHandler(this.asRequiredFieldsWaferMap); + + private readonly zoomHandler: ZoomHandler = new ZoomHandler( + this.asRequiredFieldsWaferMap + ); + private readonly resizeObserver = this.createResizeObserver(); - private readonly waferMapValidator = new WaferMapValidator(this); + private readonly waferMapValidator: WaferMapValidator = new WaferMapValidator(this.asRequiredFieldsWaferMap); public get validity(): WaferMapValidity { return this.waferMapValidator.getValidity(); @@ -168,12 +191,18 @@ export class WaferMap extends FoundationElement { this.canvasContext = this.canvas.getContext('2d', { willReadFrequently: true })!; + this.hoverHandler.connect(); + this.experimentalHoverHandler.connect(); + this.zoomHandler.connect(); this.resizeObserver.observe(this); this.waferMapUpdateTracker.trackAll(); } public override disconnectedCallback(): void { super.disconnectedCallback(); + this.hoverHandler.disconnect(); + this.experimentalHoverHandler.disconnect(); + this.zoomHandler.disconnect(); this.resizeObserver.unobserve(this); } @@ -190,8 +219,12 @@ export class WaferMap extends FoundationElement { if (this.validity.invalidDiesTableSchema) { return; } + this.renderer = this.isExperimentalRenderer() + ? this.workerRenderer + : this.mainRenderer; if (this.waferMapUpdateTracker.requiresEventsUpdate) { - this.eventCoordinator.detachEvents(); + // zoom translateExtent needs to be recalculated when canvas size changes + this.zoomHandler.disconnect(); if (this.waferMapUpdateTracker.requiresContainerDimensionsUpdate) { this.dataManager.updateContainerDimensions(); this.renderer.updateSortedDiesAndDrawWafer(); @@ -211,12 +244,19 @@ export class WaferMap extends FoundationElement { } else if (this.waferMapUpdateTracker.requiresDrawnWaferUpdate) { this.renderer.drawWafer(); } - this.eventCoordinator.attachEvents(); + this.zoomHandler.connect(); } else if (this.waferMapUpdateTracker.requiresRenderHoverUpdate) { this.renderer.renderHover(); } } + /** + * @internal + */ + public isExperimentalRenderer(): boolean { + return this.diesTable !== undefined; + } + private validate(): void { this.waferMapValidator.validateGridDimensions(); this.waferMapValidator.validateDiesTableSchema(); @@ -291,17 +331,11 @@ export class WaferMap extends FoundationElement { private diesChanged(): void { this.waferMapUpdateTracker.track('dies'); - this.renderer = this.diesTable === undefined - ? this.mainRenderer - : this.workerRenderer; this.waferMapUpdateTracker.queueUpdate(); } private diesTableChanged(): void { this.waferMapUpdateTracker.track('dies'); - this.renderer = this.diesTable === undefined - ? this.mainRenderer - : this.workerRenderer; this.waferMapUpdateTracker.queueUpdate(); } @@ -330,6 +364,10 @@ export class WaferMap extends FoundationElement { this.waferMapUpdateTracker.track('hoverDie'); this.waferMapUpdateTracker.queueUpdate(); } + + private get asRequiredFieldsWaferMap(): WaferMap { + return this as WaferMap; + } } const nimbleWaferMap = WaferMap.compose({ diff --git a/packages/nimble-components/src/wafer-map/modules/data-manager.ts b/packages/nimble-components/src/wafer-map/modules/data-manager.ts index fb9fdbc3e9..b098683bfd 100644 --- a/packages/nimble-components/src/wafer-map/modules/data-manager.ts +++ b/packages/nimble-components/src/wafer-map/modules/data-manager.ts @@ -58,13 +58,13 @@ export class DataManager { return this.dataMap; } - private readonly computations; - private readonly prerendering; + private readonly computations: Computations; + private readonly prerendering: Prerendering; private dataMap!: Map<string, WaferMapDie>; public constructor(private readonly wafermap: WaferMap) { this.computations = new Computations(wafermap); - this.prerendering = new Prerendering(wafermap, this); + this.prerendering = new Prerendering(wafermap); } public updateContainerDimensions(): void { diff --git a/packages/nimble-components/src/wafer-map/modules/event-coordinator.ts b/packages/nimble-components/src/wafer-map/modules/event-coordinator.ts deleted file mode 100644 index 420d401be5..0000000000 --- a/packages/nimble-components/src/wafer-map/modules/event-coordinator.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { WaferMapDie } from '../types'; -import { ZoomHandler } from './zoom-handler'; -import type { WaferMap } from '..'; -import { HoverHandler } from './hover-handler'; - -export interface EventCoordinatorCallbacks { - dieSelected: (die: WaferMapDie) => void; -} - -/** - * EventCoordinator deals with user interactions and events - */ -export class EventCoordinator { - private readonly zoomHandler; - private readonly hoverHandler; - public constructor(private readonly wafermap: WaferMap) { - this.zoomHandler = new ZoomHandler(wafermap); - this.hoverHandler = new HoverHandler(wafermap); - } - - public attachEvents(): void { - this.zoomHandler.createZoomBehavior(); - this.wafermap.addEventListener('mousemove', this.onMouseMove); - this.wafermap.addEventListener('mouseout', this.onMouseOut); - this.wafermap.canvas.addEventListener('wheel', this.onWheelMove, { - passive: false - }); - } - - public detachEvents(): void { - this.wafermap.removeEventListener('mousemove', this.onMouseMove); - this.wafermap.removeEventListener('mouseout', this.onMouseOut); - this.wafermap.canvas.removeEventListener('wheel', this.onWheelMove); - } - - private readonly onWheelMove = (event: Event): void => { - event.preventDefault(); - }; - - private readonly onMouseMove = (event: MouseEvent): void => { - this.hoverHandler.mousemove(event); - }; - - private readonly onMouseOut = (): void => { - this.hoverHandler.mouseout(); - }; -} diff --git a/packages/nimble-components/src/wafer-map/modules/experimental/hover-handler.ts b/packages/nimble-components/src/wafer-map/modules/experimental/hover-handler.ts new file mode 100644 index 0000000000..82339eebdc --- /dev/null +++ b/packages/nimble-components/src/wafer-map/modules/experimental/hover-handler.ts @@ -0,0 +1,98 @@ +import type { WaferMap } from '../..'; +import { PointCoordinates, WaferMapOriginLocation } from '../../types'; + +/** + * HoverHandler deals with user interactions and events like hovering + */ +export class HoverHandler { + public constructor(private readonly wafermap: WaferMap) {} + + /** + * @internal + */ + public connect(): void { + this.wafermap.addEventListener('mousemove', this.onMouseMove); + this.wafermap.addEventListener('mouseout', this.onMouseOut); + } + + /** + * @internal + */ + public disconnect(): void { + this.wafermap.removeEventListener('mousemove', this.onMouseMove); + this.wafermap.removeEventListener('mouseout', this.onMouseOut); + } + + /** + * @internal + * keep public for testing until data manager refactor + */ + public readonly onMouseMove = (event: MouseEvent): void => { + if (!this.wafermap.isExperimentalRenderer()) { + return; + } + // get original mouse position in case we are in zoom. + const invertedPoint = this.wafermap.transform.invert([ + event.offsetX, + event.offsetY + ]); + + // does not work yet until data manager will parse diesTable + const dieCoordinates = this.calculateDieCoordinates({ + x: invertedPoint[0], + y: invertedPoint[1] + }); + const colIndex = this.wafermap + .diesTable!.getChild('colIndex')! + .toArray(); + const rowIndex = this.wafermap + .diesTable!.getChild('rowIndex')! + .toArray(); + + // will replace iterating with arquero filtering after fixing errors + for (let i = 0; i < colIndex.length; i++) { + if ( + colIndex[i] === dieCoordinates.x + && rowIndex[i] === dieCoordinates.y + ) { + this.wafermap.hoverDie = { + index: i, + x: dieCoordinates.x, + y: dieCoordinates.y + }; + return; + } + } + this.wafermap.hoverDie = undefined; + }; + + private readonly onMouseOut = (_event: MouseEvent): void => { + this.wafermap.hoverDie = undefined; + }; + + private calculateDieCoordinates( + mousePosition: PointCoordinates + ): PointCoordinates { + const originLocation = this.wafermap.originLocation; + const xRoundFunction = originLocation === WaferMapOriginLocation.bottomLeft + || originLocation === WaferMapOriginLocation.topLeft + ? Math.floor + : Math.ceil; + const yRoundFunction = originLocation === WaferMapOriginLocation.bottomLeft + || originLocation === WaferMapOriginLocation.bottomRight + ? Math.floor + : Math.ceil; + // go to x and y scale to get the x,y values of the die. + const x = xRoundFunction( + this.wafermap.dataManager.invertedHorizontalScale( + mousePosition.x - this.wafermap.dataManager.margin.left + ) + ); + const y = yRoundFunction( + this.wafermap.dataManager.invertedVerticalScale( + mousePosition.y - this.wafermap.dataManager.margin.top + ) + ); + return { x, y }; + } +} diff --git a/packages/nimble-components/src/wafer-map/modules/worker-renderer.ts b/packages/nimble-components/src/wafer-map/modules/experimental/worker-renderer.ts similarity index 95% rename from packages/nimble-components/src/wafer-map/modules/worker-renderer.ts rename to packages/nimble-components/src/wafer-map/modules/experimental/worker-renderer.ts index 24dbcc8a73..5556c7bfe2 100644 --- a/packages/nimble-components/src/wafer-map/modules/worker-renderer.ts +++ b/packages/nimble-components/src/wafer-map/modules/experimental/worker-renderer.ts @@ -1,5 +1,5 @@ -import type { WaferMap } from '..'; -import { HoverDieOpacity } from '../types'; +import type { WaferMap } from '../..'; +import { HoverDieOpacity } from '../../types'; /** * Responsible for drawing the dies inside the wafer map, adding dieText and scaling the canvas diff --git a/packages/nimble-components/src/wafer-map/modules/hover-handler.ts b/packages/nimble-components/src/wafer-map/modules/hover-handler.ts index cab13191d6..393d7ba015 100644 --- a/packages/nimble-components/src/wafer-map/modules/hover-handler.ts +++ b/packages/nimble-components/src/wafer-map/modules/hover-handler.ts @@ -6,13 +6,33 @@ import { PointCoordinates, WaferMapOriginLocation } from '../types'; */ export class HoverHandler { public constructor(private readonly wafermap: WaferMap) {} - public mousemove(event: MouseEvent): void { + + /** + * @internal + */ + public connect(): void { + this.wafermap.addEventListener('mousemove', this.onMouseMove); + this.wafermap.addEventListener('mouseout', this.onMouseOut); + } + + /** + * @internal + */ + public disconnect(): void { + this.wafermap.removeEventListener('mousemove', this.onMouseMove); + this.wafermap.removeEventListener('mouseout', this.onMouseOut); + } + + private readonly onMouseMove = (event: MouseEvent): void => { + if (this.wafermap.isExperimentalRenderer()) { + return; + } const mousePosition: PointCoordinates = { x: event.offsetX, y: event.offsetY }; - if (!this.hoversOverDie(this.wafermap, mousePosition)) { + if (!this.hoversOverDie(mousePosition)) { this.wafermap.hoverDie = undefined; return; } @@ -22,23 +42,22 @@ export class HoverHandler { mousePosition.y ]); - const dieCoordinates = this.calculateDieCoordinates(this.wafermap, { + const dieCoordinates = this.calculateDieCoordinates({ x: invertedPoint[0], y: invertedPoint[1] }); this.wafermap.hoverDie = this.wafermap.dataManager.getWaferMapDie(dieCoordinates); - } + }; - public mouseout(): void { + private readonly onMouseOut = (_event: MouseEvent): void => { this.wafermap.hoverDie = undefined; - } + }; private calculateDieCoordinates( - wafermap: WaferMap, mousePosition: PointCoordinates ): PointCoordinates { - const originLocation = wafermap.originLocation; + const originLocation = this.wafermap.originLocation; const xRoundFunction = originLocation === WaferMapOriginLocation.bottomLeft || originLocation === WaferMapOriginLocation.topLeft ? Math.floor @@ -49,23 +68,20 @@ export class HoverHandler { : Math.ceil; // go to x and y scale to get the x,y values of the die. const x = xRoundFunction( - wafermap.dataManager.invertedHorizontalScale( - mousePosition.x - wafermap.dataManager.margin.left + this.wafermap.dataManager.invertedHorizontalScale( + mousePosition.x - this.wafermap.dataManager.margin.left ) ); const y = yRoundFunction( - wafermap.dataManager.invertedVerticalScale( - mousePosition.y - wafermap.dataManager.margin.top + this.wafermap.dataManager.invertedVerticalScale( + mousePosition.y - this.wafermap.dataManager.margin.top ) ); return { x, y }; } - private hoversOverDie( - wafermap: WaferMap, - mousePosition: PointCoordinates - ): boolean { - const rgba = wafermap.canvasContext.getImageData( + private hoversOverDie(mousePosition: PointCoordinates): boolean { + const rgba = this.wafermap.canvasContext.getImageData( mousePosition.x, mousePosition.y, 1, diff --git a/packages/nimble-components/src/wafer-map/modules/prerendering.ts b/packages/nimble-components/src/wafer-map/modules/prerendering.ts index 9d4db977d0..85f464d548 100644 --- a/packages/nimble-components/src/wafer-map/modules/prerendering.ts +++ b/packages/nimble-components/src/wafer-map/modules/prerendering.ts @@ -8,7 +8,6 @@ import type { WaferMapDie } from '../types'; import type { WaferMap } from '..'; -import type { DataManager } from './data-manager'; /** * Prerendering prepares render-ready dies data to be used by the rendering module @@ -34,14 +33,11 @@ export class Prerendering { private readonly emptyDieColor = 'rgba(218,223,236,1)'; private readonly nanDieColor = 'rgba(122,122,122,1)'; - public constructor( - private readonly wafermap: WaferMap, - private readonly dataManager: Readonly<DataManager> - ) {} + public constructor(private readonly wafermap: WaferMap) {} public updateLabelsFontSize(): void { this._labelsFontSize = this.calculateLabelsFontSize( - this.dataManager.dieDimensions, + this.wafermap.dataManager.dieDimensions, this.wafermap.maxCharacters ); this.updateDiesRenderInfo(); @@ -61,10 +57,10 @@ export class Prerendering { } private computeDieRenderInfo(die: WaferMapDie): DieRenderInfo | null { - const margin = this.dataManager.margin; + const margin = this.wafermap.dataManager.margin; - const scaledX = this.dataManager.horizontalScale(die.x); - const scaledY = this.dataManager.verticalScale(die.y); + const scaledX = this.wafermap.dataManager.horizontalScale(die.x); + const scaledY = this.wafermap.dataManager.verticalScale(die.y); if (scaledX === undefined || scaledY === undefined) { return null; diff --git a/packages/nimble-components/src/wafer-map/modules/wafer-map-validator.ts b/packages/nimble-components/src/wafer-map/modules/wafer-map-validator.ts index 9ef38a00a0..6788f50149 100644 --- a/packages/nimble-components/src/wafer-map/modules/wafer-map-validator.ts +++ b/packages/nimble-components/src/wafer-map/modules/wafer-map-validator.ts @@ -25,10 +25,10 @@ export class WaferMapValidator { public validateGridDimensions(): boolean { this.invalidGridDimensions = false; if ( - typeof this.wafermap.gridMinX === 'undefined' - && typeof this.wafermap.gridMaxX === 'undefined' - && typeof this.wafermap.gridMinY === 'undefined' - && typeof this.wafermap.gridMaxY === 'undefined' + this.wafermap.gridMinX === undefined + && this.wafermap.gridMaxX === undefined + && this.wafermap.gridMinY === undefined + && this.wafermap.gridMaxY === undefined ) { this.invalidGridDimensions = false; } else if ( @@ -49,38 +49,20 @@ export class WaferMapValidator { if (this.wafermap.diesTable === undefined) { this.invalidDiesTableSchema = false; } else { - const colIndexField = this.wafermap.diesTable.schema.fields.findIndex( - f => f.name === 'colIndex' - ); - const rowIndexField = this.wafermap.diesTable.schema.fields.findIndex( - f => f.name === 'rowIndex' - ); - const valueField = this.wafermap.diesTable.schema.fields.findIndex( - f => f.name === 'value' - ); + const fields = this.wafermap.diesTable.schema.fields; + const colField = fields.find(field => field.name === 'colIndex'); + const rowField = fields.find(field => field.name === 'rowIndex'); + const valueField = fields.find(field => field.name === 'value'); if ( - this.wafermap.diesTable.numCols < 3 - || colIndexField === -1 - || rowIndexField === -1 - || valueField === -1 - || !DataType.isInt( - this.wafermap.diesTable.schema.fields[colIndexField]!.type - ) - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - || this.wafermap.diesTable.schema.fields[colIndexField]!.type - .bitWidth !== 32 - || !DataType.isInt( - this.wafermap.diesTable.schema.fields[rowIndexField]!.type - ) - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - || this.wafermap.diesTable.schema.fields[rowIndexField]!.type - .bitWidth !== 32 - || !DataType.isFloat( - this.wafermap.diesTable.schema.fields[valueField]!.type - ) - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - || this.wafermap.diesTable.schema.fields[valueField]!.type - .precision !== Precision.DOUBLE + !colField + || !rowField + || !valueField + || !DataType.isInt(colField.type) + || colField.type.bitWidth !== 32 + || !DataType.isInt(rowField.type) + || rowField.type.bitWidth !== 32 + || !DataType.isFloat(valueField.type) + || valueField.type.precision !== Precision.DOUBLE ) { this.invalidDiesTableSchema = true; } diff --git a/packages/nimble-components/src/wafer-map/modules/zoom-handler.ts b/packages/nimble-components/src/wafer-map/modules/zoom-handler.ts index 38a82d89b1..79635b403c 100644 --- a/packages/nimble-components/src/wafer-map/modules/zoom-handler.ts +++ b/packages/nimble-components/src/wafer-map/modules/zoom-handler.ts @@ -1,11 +1,5 @@ import { select } from 'd3-selection'; -import { - zoom, - ZoomBehavior, - zoomIdentity, - ZoomTransform, - zoomTransform -} from 'd3-zoom'; +import { zoom, ZoomTransform } from 'd3-zoom'; import type { WaferMap } from '..'; interface ZoomEvent { @@ -16,61 +10,44 @@ interface ZoomEvent { * ZoomHandler deals with user interactions and events like zooming */ export class ZoomHandler { - private zoomTransform: ZoomTransform = zoomIdentity; - private readonly minScale = 1.1; - private readonly minExtentPoint: [number, number] = [-100, -100]; - private readonly extentPadding = 100; - private zoomBehavior!: ZoomBehavior<Element, unknown>; + private readonly scaleExtent: [number, number] = [1, 100]; + private readonly minExtentPoint: [number, number] = [0, 0]; public constructor(private readonly wafermap: WaferMap) {} - public createZoomBehavior(): void { - this.zoomBehavior = zoom() - .scaleExtent([ - 1.1, - this.getZoomMax( - this.wafermap.canvasWidth * this.wafermap.canvasHeight, - this.wafermap.dataManager.containerDimensions.width - * this.wafermap.dataManager.containerDimensions.height - ) - ]) + /** + * @internal + */ + public connect(): void { + this.createZoomBehavior(); + this.wafermap.addEventListener('wheel', this.onWheelMove, { + passive: false + }); + } + + /** + * @internal + */ + public disconnect(): void { + zoom().on('zoom', null)(select(this.wafermap as Element)); + this.wafermap.removeEventListener('wheel', this.onWheelMove); + } + + private createZoomBehavior(): void { + zoom() + .scaleExtent(this.scaleExtent) .translateExtent([ this.minExtentPoint, - [ - this.wafermap.canvasWidth + this.extentPadding, - this.wafermap.canvasHeight + this.extentPadding - ] + [this.wafermap.canvasWidth, this.wafermap.canvasHeight] ]) - .filter((event: Event) => { - const transform = zoomTransform(this.wafermap.canvas); - const filterEval = transform.k >= this.minScale || event.type === 'wheel'; - return filterEval; - }) .on('zoom', (event: ZoomEvent) => { // D3 will automatically remove existing handlers when adding new ones // See: https://github.com/d3/d3-zoom/blob/v3.0.0/README.md#zoom_on - this.rescale(event); - }); - - this.zoomBehavior(select(this.wafermap.canvas as Element)); + this.wafermap.transform = event.transform; + })(select(this.wafermap as Element)); } - private rescale(event: ZoomEvent): void { - const transform = event.transform; - if (transform.k === this.minScale) { - this.zoomTransform = zoomIdentity; - this.zoomBehavior.transform( - select(this.wafermap.canvas as Element), - zoomIdentity - ); - } else { - this.zoomTransform = transform; - } - - this.wafermap.transform = this.zoomTransform; - } - - private getZoomMax(canvasArea: number, dataArea: number): number { - return Math.ceil((dataArea / canvasArea) * 100); - } + private readonly onWheelMove = (event: Event): void => { + event.preventDefault(); + }; } diff --git a/packages/nimble-components/src/wafer-map/tests/computations.spec.ts b/packages/nimble-components/src/wafer-map/tests/computations.spec.ts index deb673b81c..0f0ead89ef 100644 --- a/packages/nimble-components/src/wafer-map/tests/computations.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/computations.spec.ts @@ -1,4 +1,3 @@ -import type { WaferMap } from '..'; import { Computations } from '../modules/computations'; import { Margin, WaferMapOriginLocation } from '../types'; import { getWaferMapMockComputations, getWaferMapDies } from './utilities'; @@ -20,7 +19,7 @@ describe('Wafermap Computations module', () => { 100, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); @@ -70,7 +69,7 @@ describe('Wafermap Computations module', () => { 200, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); @@ -114,7 +113,7 @@ describe('Wafermap Computations module', () => { 100, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); @@ -136,7 +135,7 @@ describe('Wafermap Computations module', () => { 100, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); @@ -158,7 +157,7 @@ describe('Wafermap Computations module', () => { 100, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); @@ -180,7 +179,7 @@ describe('Wafermap Computations module', () => { 100, 100 ); - computationsModule = new Computations(waferMock as WaferMap); + computationsModule = new Computations(waferMock); computationsModule.updateContainerDimensions(); }); diff --git a/packages/nimble-components/src/wafer-map/tests/data-generator.ts b/packages/nimble-components/src/wafer-map/tests/data-generator.ts index fff32e67e5..77cc8efa71 100644 --- a/packages/nimble-components/src/wafer-map/tests/data-generator.ts +++ b/packages/nimble-components/src/wafer-map/tests/data-generator.ts @@ -154,6 +154,6 @@ export const generateWaferTableData = ( return tableFromArrays({ colIndex: Int32Array.from(colIndex), rowIndex: Int32Array.from(rowIndex), - value: Float32Array.from(value) + value: Float64Array.from(value) }); }; diff --git a/packages/nimble-components/src/wafer-map/tests/hover-handler.spec.ts b/packages/nimble-components/src/wafer-map/tests/hover-handler.spec.ts new file mode 100644 index 0000000000..7bee0ae2aa --- /dev/null +++ b/packages/nimble-components/src/wafer-map/tests/hover-handler.spec.ts @@ -0,0 +1,114 @@ +import { zoomIdentity } from 'd3-zoom'; +import { tableFromArrays } from 'apache-arrow'; +import { html } from '@microsoft/fast-element'; +import { parameterizeSpec } from '@ni/jasmine-parameterized'; +import { HoverHandler } from '../modules/experimental/hover-handler'; +import { WaferMapOriginLocation } from '../types'; +import { + getDataManagerMockForHover, + getScaleQuantile, + getWaferMapMockHover +} from './utilities'; +import type { WaferMap } from '..'; +import { processUpdates } from '../../testing/async-helpers'; +import { Fixture, fixture } from '../../utilities/tests/fixture'; + +async function setup(): Promise<Fixture<HTMLDivElement>> { + return fixture<HTMLDivElement>(html`<div></div>`); +} + +describe('HoverHandler', () => { + let element: HTMLDivElement; + let connect: () => Promise<void>; + let disconnect: () => Promise<void>; + let hoverHandler: HoverHandler; + let waferMock: WaferMap; + + beforeEach(async () => { + ({ element, connect, disconnect } = await setup()); + await connect(); + waferMock = getWaferMapMockHover( + tableFromArrays({ + colIndex: Int32Array.from([1, 2, 3]), + rowIndex: Int32Array.from([1, 2, 3]), + value: Float64Array.from([1, 2, 3]) + }), + zoomIdentity, + WaferMapOriginLocation.bottomLeft, + undefined, + getDataManagerMockForHover( + { left: 0, right: 0, top: 0, bottom: 0 }, + getScaleQuantile([1, 11], [1, 2, 3, 4]), + getScaleQuantile([1, 11], [1, 2, 3, 4]) + ), + true + ); + }); + + afterEach(async () => { + await disconnect(); + }); + + const testCases = [ + { + name: WaferMapOriginLocation.bottomLeft, + expectedDie: { index: 1, x: 2, y: 2 } + }, + { + name: WaferMapOriginLocation.topLeft, + expectedDie: { index: 1, x: 2, y: 2 } + }, + { + name: WaferMapOriginLocation.bottomRight, + expectedDie: { index: 1, x: 2, y: 2 } + }, + { + name: WaferMapOriginLocation.topRight, + expectedDie: { index: 1, x: 2, y: 2 } + } + ] as const; + + parameterizeSpec(testCases, (spec, name, value) => { + spec( + `will return the expected index when mouse moved in range from ${name}`, + () => { + waferMock.originLocation = value.name; + hoverHandler = new HoverHandler(waferMock); + element.addEventListener('mousemove', event => hoverHandler.onMouseMove(event)); + element.dispatchEvent( + new MouseEvent('mousemove', { + clientX: 4, + clientY: 4 + }) + ); + processUpdates(); + expect(waferMock.hoverDie).toEqual(value.expectedDie); + } + ); + }); + + const undefinedTestCases = [ + { name: WaferMapOriginLocation.bottomLeft, expectedDie: undefined }, + { name: WaferMapOriginLocation.topLeft, expectedDie: undefined }, + { name: WaferMapOriginLocation.bottomRight, expectedDie: undefined }, + { name: WaferMapOriginLocation.topRight, expectedDie: undefined } + ] as const; + parameterizeSpec(undefinedTestCases, (spec, name, value) => { + spec( + `will return undefined when mouse moved out of range from ${name}`, + () => { + waferMock.originLocation = value.name; + hoverHandler = new HoverHandler(waferMock); + element.addEventListener('mousemove', event => hoverHandler.onMouseMove(event)); + element.dispatchEvent( + new MouseEvent('mousemove', { + clientX: 15, + clientY: 15 + }) + ); + processUpdates(); + expect(waferMock.hoverDie).toEqual(value.expectedDie); + } + ); + }); +}); diff --git a/packages/nimble-components/src/wafer-map/tests/prerendering.coloring.spec.ts b/packages/nimble-components/src/wafer-map/tests/prerendering.coloring.spec.ts index 5cfb169a65..2b93f87e82 100644 --- a/packages/nimble-components/src/wafer-map/tests/prerendering.coloring.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/prerendering.coloring.spec.ts @@ -1,5 +1,3 @@ -import type { WaferMap } from '..'; -import type { DataManager } from '../modules/data-manager'; import { Prerendering } from '../modules/prerendering'; import { WaferMapColorScaleMode } from '../types'; import { @@ -28,6 +26,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: ['red'], values: ['1'] }, @@ -35,18 +39,10 @@ describe('Wafermap Prerendering module', () => { colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -70,6 +66,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { @@ -80,18 +82,10 @@ describe('Wafermap Prerendering module', () => { colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -115,6 +109,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { @@ -125,18 +125,10 @@ describe('Wafermap Prerendering module', () => { colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -167,6 +159,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: ['red'], values: ['1'] }, @@ -174,18 +172,10 @@ describe('Wafermap Prerendering module', () => { colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -209,6 +199,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { @@ -219,18 +215,10 @@ describe('Wafermap Prerendering module', () => { colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -260,6 +248,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + getScaleBand([0, 1], [0, 100]), + getScaleBand([0, 1], [0, 100]) + ); const waferMock = getWaferMapMockPrerendering( [ { @@ -273,18 +267,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - getScaleBand([0, 1], [0, 100]), - getScaleBand([0, 1], [0, 100]) - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -308,6 +294,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + getScaleBand([0, 1], [0, 100]), + getScaleBand([0, 1], [0, 100]) + ); const waferMock = getWaferMapMockPrerendering( [ { @@ -321,18 +313,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - getScaleBand([0, 1], [0, 100]), - getScaleBand([0, 1], [0, 100]) - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -356,6 +340,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: ['red'], values: [] }, @@ -363,18 +353,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.ordinal, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -405,6 +387,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: ['red'], values: [] }, @@ -412,18 +400,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.ordinal, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); diff --git a/packages/nimble-components/src/wafer-map/tests/prerendering.labeling.spec.ts b/packages/nimble-components/src/wafer-map/tests/prerendering.labeling.spec.ts index 60c98db5b8..fb3d5ffdf7 100644 --- a/packages/nimble-components/src/wafer-map/tests/prerendering.labeling.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/prerendering.labeling.spec.ts @@ -1,5 +1,3 @@ -import type { WaferMap } from '..'; -import type { DataManager } from '../modules/data-manager'; import { Prerendering } from '../modules/prerendering'; import { WaferMapColorScaleMode } from '../types'; import { @@ -24,6 +22,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -31,18 +35,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -68,6 +64,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -75,18 +77,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -106,6 +100,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -113,18 +113,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -148,6 +140,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -155,18 +153,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -191,6 +181,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -198,18 +194,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -236,6 +224,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDiesAsNaN(), { colors: [], values: [] }, @@ -243,18 +237,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -281,6 +267,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDiesAsFloats(), { colors: [], values: [] }, @@ -288,18 +280,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -330,6 +314,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -337,18 +327,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); diff --git a/packages/nimble-components/src/wafer-map/tests/prerendering.positioning.spec.ts b/packages/nimble-components/src/wafer-map/tests/prerendering.positioning.spec.ts index a54606c526..8b65558c50 100644 --- a/packages/nimble-components/src/wafer-map/tests/prerendering.positioning.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/prerendering.positioning.spec.ts @@ -1,5 +1,3 @@ -import type { WaferMap } from '..'; -import type { DataManager } from '../modules/data-manager'; import { Prerendering } from '../modules/prerendering'; import { WaferMapColorScaleMode } from '../types'; import { @@ -23,6 +21,12 @@ describe('Wafermap Prerendering module', () => { const margin = { top: 20, right: 10, bottom: 0, left: 0 }; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -30,18 +34,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -83,6 +79,12 @@ describe('Wafermap Prerendering module', () => { const highlightedTags: string[] = []; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + horizontalScale, + defaultVerticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -90,18 +92,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - horizontalScale, - defaultVerticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); @@ -132,6 +126,12 @@ describe('Wafermap Prerendering module', () => { const highlightedTags: string[] = []; beforeEach(() => { + const dataManagerMock = getDataManagerMock( + dieDimensions, + margin, + defaultHorizontalScale, + verticalScale + ); const waferMock = getWaferMapMockPrerendering( getWaferMapDies(), { colors: [], values: [] }, @@ -139,18 +139,10 @@ describe('Wafermap Prerendering module', () => { WaferMapColorScaleMode.linear, dieLabelsHidden, dieLabelsSuffix, - maxCharacters - ); - const dataManagerMock = getDataManagerMock( - dieDimensions, - margin, - defaultHorizontalScale, - verticalScale - ); - prerenderingModule = new Prerendering( - waferMock as WaferMap, - dataManagerMock as DataManager + maxCharacters, + dataManagerMock ); + prerenderingModule = new Prerendering(waferMock); prerenderingModule.updateLabelsFontSize(); }); diff --git a/packages/nimble-components/src/wafer-map/tests/sets.ts b/packages/nimble-components/src/wafer-map/tests/sets.ts index 3b26320e4c..80089b35ee 100644 --- a/packages/nimble-components/src/wafer-map/tests/sets.ts +++ b/packages/nimble-components/src/wafer-map/tests/sets.ts @@ -105,7 +105,7 @@ export const wafermapDiesTableSets: Table[] = [ tableFromArrays({ colIndex: Int32Array.from([0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4]), rowIndex: Int32Array.from([2, 2, 1, 3, 2, 1, 0, 3, 4, 2, 1, 3, 2]), - value: Float32Array.from([ + value: Float64Array.from([ 14.24, 76.43, 44.63, 67.93, 72.71, 79.04, 26.49, 37.79, 59.82, 52.9, 98.5, 20.83, 62.8 ]), diff --git a/packages/nimble-components/src/wafer-map/tests/utilities.ts b/packages/nimble-components/src/wafer-map/tests/utilities.ts index f654e3b9bf..f30aa122dc 100644 --- a/packages/nimble-components/src/wafer-map/tests/utilities.ts +++ b/packages/nimble-components/src/wafer-map/tests/utilities.ts @@ -1,7 +1,9 @@ -import { ScaleBand, scaleBand } from 'd3-scale'; +import { ScaleBand, ScaleQuantile, scaleBand, scaleQuantile } from 'd3-scale'; import type { Table } from 'apache-arrow'; +import type { ZoomTransform } from 'd3-zoom'; import { Dimensions, + HoverDie, Margin, WaferMapColorScale, WaferMapColorScaleMode, @@ -64,6 +66,12 @@ export function getScaleBand( return scaleBand<number>().domain(domain).range(range); } +export function getScaleQuantile( + domain: number[] = [], + range: number[] = [] +): ScaleQuantile<number, number> { + return scaleQuantile().domain(domain).range(range); +} export const defaultHorizontalScale = scaleBand<number>() .domain([2, 3, 4, 5, 6]) .range([2, 7]); @@ -77,16 +85,39 @@ export function getDataManagerMock( margin: Margin, horizontalScale: ScaleBand<number> = getScaleBand([], []), verticalScale: ScaleBand<number> = getScaleBand([], []) -): Pick< +): DataManager { + const dataManagerMock: Pick< DataManager, 'horizontalScale' | 'verticalScale' | 'dieDimensions' | 'margin' - > { - return { + > = { horizontalScale, verticalScale, dieDimensions, margin }; + return dataManagerMock as DataManager; +} + +export function getDataManagerMockForHover( + margin: Margin, + invertedHorizontalScale: ScaleQuantile<number, number> = getScaleQuantile( + [], + [] + ), + invertedVerticalScale: ScaleQuantile<number, number> = getScaleQuantile( + [], + [] + ) +): DataManager { + const dataManagerMock: Pick< + DataManager, + 'invertedHorizontalScale' | 'invertedVerticalScale' | 'margin' + > = { + invertedHorizontalScale, + invertedVerticalScale, + margin + }; + return dataManagerMock as DataManager; } export function getWaferMapMockPrerendering( @@ -96,8 +127,10 @@ export function getWaferMapMockPrerendering( colorScaleMode: WaferMapColorScaleMode = WaferMapColorScaleMode.linear, dieLabelsHidden = true, dieLabelsSuffix = '', - maxCharacters = 4 -): Pick< + maxCharacters = 4, + dataManager = {} as DataManager +): WaferMap { + const waferMapMock: Pick< WaferMap, | 'dies' | 'colorScale' @@ -106,18 +139,46 @@ export function getWaferMapMockPrerendering( | 'dieLabelsHidden' | 'dieLabelsSuffix' | 'maxCharacters' - > { - return { + | 'dataManager' + > = { dies, colorScale, highlightedTags, colorScaleMode, dieLabelsHidden, dieLabelsSuffix, - maxCharacters + maxCharacters, + dataManager }; + return waferMapMock as WaferMap; } +export function getWaferMapMockHover( + diesTable: Table, + transform: ZoomTransform, + originLocation: WaferMapOriginLocation, + hoverDie: HoverDie | undefined, + dataManager: DataManager, + isExperimentalRenderer: boolean +): WaferMap { + const waferMapMock: Pick< + WaferMap, + | 'diesTable' + | 'transform' + | 'originLocation' + | 'hoverDie' + | 'dataManager' + | 'isExperimentalRenderer' + > = { + diesTable, + transform, + originLocation, + hoverDie, + dataManager, + isExperimentalRenderer: () => isExperimentalRenderer + }; + return waferMapMock as WaferMap; +} export function getWaferMapMockComputations( dies: WaferMapDie[] = getWaferMapDies(), originLocation: WaferMapOriginLocation, @@ -127,17 +188,18 @@ export function getWaferMapMockComputations( invalidGridDimensions: false, invalidDiesTableSchema: false } -): Pick< +): WaferMap { + const waferMapMock: Pick< WaferMap, 'dies' | 'originLocation' | 'canvasWidth' | 'canvasHeight' | 'validity' - > { - return { + > = { dies, originLocation, canvasWidth, canvasHeight, validity }; + return waferMapMock as WaferMap; } export function getWaferMapMockValidator( @@ -146,15 +208,16 @@ export function getWaferMapMockValidator( gridMinY: number | undefined, gridMaxY: number | undefined, diesTable: Table | undefined = undefined -): Pick< +): WaferMap { + const waferMapMock: Pick< WaferMap, 'gridMinX' | 'gridMaxX' | 'gridMinY' | 'gridMaxY' | 'diesTable' - > { - return { + > = { gridMinX, gridMaxX, gridMinY, gridMaxY, diesTable }; + return waferMapMock as WaferMap; } diff --git a/packages/nimble-components/src/wafer-map/tests/wafer-map-validator.spec.ts b/packages/nimble-components/src/wafer-map/tests/wafer-map-validator.spec.ts index 732833fa9a..659fbee23c 100644 --- a/packages/nimble-components/src/wafer-map/tests/wafer-map-validator.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/wafer-map-validator.spec.ts @@ -1,5 +1,4 @@ import { Table, tableFromArrays } from 'apache-arrow'; -import type { WaferMap } from '..'; import { WaferMapValidator } from '../modules/wafer-map-validator'; import { getWaferMapMockValidator } from './utilities'; @@ -13,7 +12,7 @@ describe('Wafermap Validator module', () => { undefined, undefined ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.isValid()).toBeTrue(); @@ -21,7 +20,7 @@ describe('Wafermap Validator module', () => { it('with equal grid dimensions should be valid', () => { const waferMock = getWaferMapMockValidator(0, 0, 0, 0); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.isValid()).toBeTrue(); @@ -29,7 +28,7 @@ describe('Wafermap Validator module', () => { it('with positive grid dimensions should be valid', () => { const waferMock = getWaferMapMockValidator(1, 2, 1, 2); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.isValid()).toBeTrue(); @@ -37,7 +36,7 @@ describe('Wafermap Validator module', () => { it('with negative grid dimensions should be valid', () => { const waferMock = getWaferMapMockValidator(-2, -1, -2, -1); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.isValid()).toBeTrue(); @@ -45,7 +44,7 @@ describe('Wafermap Validator module', () => { it('with one undefined grid dimension should not be valid', () => { const waferMock = getWaferMapMockValidator(0, 0, 0, undefined); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.isValid()).toBeFalse(); @@ -53,7 +52,7 @@ describe('Wafermap Validator module', () => { it('with impossible grid dimension should not be valid', () => { const waferMock = getWaferMapMockValidator(1, -1, 1, -1); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateGridDimensions(); expect(waferMapValidator.getValidity()).toEqual({ @@ -71,7 +70,7 @@ describe('Wafermap Validator module', () => { undefined, undefined ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeTrue(); }); @@ -88,7 +87,7 @@ describe('Wafermap Validator module', () => { value: Float64Array.from([]) }) ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeTrue(); @@ -106,7 +105,7 @@ describe('Wafermap Validator module', () => { value: Float32Array.from([]) }) ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeFalse(); @@ -124,7 +123,7 @@ describe('Wafermap Validator module', () => { value: Float64Array.from([]) }) ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeFalse(); @@ -142,7 +141,7 @@ describe('Wafermap Validator module', () => { value: Int32Array.from([]) }) ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeFalse(); @@ -156,7 +155,7 @@ describe('Wafermap Validator module', () => { undefined, new Table() ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeFalse(); @@ -172,7 +171,7 @@ describe('Wafermap Validator module', () => { rowIndex: Int32Array.from([]) }) ); - waferMapValidator = new WaferMapValidator(waferMock as WaferMap); + waferMapValidator = new WaferMapValidator(waferMock); waferMapValidator.validateDiesTableSchema(); expect(waferMapValidator.isValid()).toBeFalse(); diff --git a/packages/nimble-components/src/wafer-map/tests/wafer-map.spec.ts b/packages/nimble-components/src/wafer-map/tests/wafer-map.spec.ts index f811df6fce..e443b632ee 100644 --- a/packages/nimble-components/src/wafer-map/tests/wafer-map.spec.ts +++ b/packages/nimble-components/src/wafer-map/tests/wafer-map.spec.ts @@ -9,7 +9,7 @@ import { WaferMapOriginLocation } from '../types'; import { RenderingModule } from '../modules/rendering'; -import { WorkerRenderer } from '../modules/worker-renderer'; +import { WorkerRenderer } from '../modules/experimental/worker-renderer'; async function setup(): Promise<Fixture<WaferMap>> { return fixture<WaferMap>(html`<nimble-wafer-map></nimble-wafer-map>`); @@ -88,24 +88,12 @@ describe('WaferMap', () => { expect(spy).toHaveBeenCalledTimes(1); }); - it('will use RenderingModule after dies change', () => { - element.dies = [{ x: 1, y: 1, value: '1' }]; - processUpdates(); - expect(element.renderer instanceof RenderingModule).toBeTrue(); - }); - it('will update once after diesTable change', () => { element.diesTable = new Table(); processUpdates(); expect(spy).toHaveBeenCalledTimes(1); }); - it('will use WorkerRenderer after diesTable change', () => { - element.diesTable = new Table(); - processUpdates(); - expect(element.renderer instanceof WorkerRenderer).toBeTrue(); - }); - it('will update once after colorScale changes', () => { element.colorScale = { colors: ['red', 'red'], values: ['1', '1'] }; processUpdates(); @@ -158,6 +146,28 @@ describe('WaferMap', () => { renderHoverSpy = spyOn(element.workerRenderer, 'renderHover'); }); + it('will use RenderingModule after dies change', () => { + element.dies = [{ x: 1, y: 1, value: '1' }]; + processUpdates(); + expect(element.renderer instanceof RenderingModule).toBeTrue(); + }); + + it('will use WorkerRenderer after supported diesTable change', () => { + element.diesTable = tableFromArrays({ + colIndex: Int32Array.from([]), + rowIndex: Int32Array.from([]), + value: Float64Array.from([]) + }); + processUpdates(); + expect(element.renderer instanceof WorkerRenderer).toBeTrue(); + }); + + it('will use RenderingModule after unsupported diesTable change', () => { + element.diesTable = new Table(); + processUpdates(); + expect(element.renderer instanceof RenderingModule).toBeTrue(); + }); + it('will call renderHover after supported diesTable change', () => { element.diesTable = tableFromArrays({ colIndex: Int32Array.from([]), @@ -191,7 +201,7 @@ describe('WaferMap', () => { }); it('will zoom in the wafer-map', () => { - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: -2, deltaMode: -1 }) ); processUpdates(); @@ -200,7 +210,7 @@ describe('WaferMap', () => { }); it('will zoom out to identity', () => { - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: -2, deltaMode: -1 }) ); @@ -208,7 +218,7 @@ describe('WaferMap', () => { const zoomedValue = getTransform(); expect(zoomedValue).not.toEqual(initialValue); - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: 2, deltaMode: -1 }) ); @@ -218,7 +228,7 @@ describe('WaferMap', () => { }); it('will not zoom out when at identity', () => { - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: 2, deltaMode: -1 }) ); processUpdates(); @@ -258,7 +268,7 @@ describe('WaferMap', () => { expect(initialHeight).toBe(460); expect(initialWidth).toBe(460); - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: -2, deltaMode: -1 }) ); processUpdates(); @@ -277,7 +287,7 @@ describe('WaferMap', () => { processUpdates(); const initialTransform = element.hoverTransform; expect(initialTransform).not.toEqual(''); - element.canvas.dispatchEvent( + element.dispatchEvent( new WheelEvent('wheel', { deltaY: -2, deltaMode: -1 }) ); processUpdates(); diff --git a/packages/nimble-components/src/wafer-map/tests/wafer-map.stories.ts b/packages/nimble-components/src/wafer-map/tests/wafer-map.stories.ts index 2cd7f02974..c0b82ce309 100644 --- a/packages/nimble-components/src/wafer-map/tests/wafer-map.stories.ts +++ b/packages/nimble-components/src/wafer-map/tests/wafer-map.stories.ts @@ -81,7 +81,7 @@ const getDiesSet = ( )!; break; default: - returnedValue = [] as WaferMapDie[]; + returnedValue = []; } return returnedValue; }; @@ -133,7 +133,7 @@ const getHighlightedTags = (setName: string, sets: string[][]): string[] => { returnedValue = sets[3]!; break; default: - returnedValue = [] as string[]; + returnedValue = []; break; } return returnedValue; diff --git a/packages/nimble-components/src/wafer-map/types.ts b/packages/nimble-components/src/wafer-map/types.ts index cac887b0a0..7193593c4f 100644 --- a/packages/nimble-components/src/wafer-map/types.ts +++ b/packages/nimble-components/src/wafer-map/types.ts @@ -1,3 +1,5 @@ +import type { Float64, Int32 } from 'apache-arrow'; + export const WaferMapOriginLocation = { bottomLeft: 'bottom-left', bottomRight: 'bottom-right', @@ -43,6 +45,12 @@ export interface WaferMapDie { tags?: string[]; } +export interface HoverDie { + index: number; + x: number; + y: number; +} + export interface WaferMapColorScale { colors: string[]; values: string[]; @@ -79,3 +87,16 @@ export interface WaferMapValidity extends ValidityObject { readonly invalidGridDimensions: boolean; readonly invalidDiesTableSchema: boolean; } + +// Apache arrow probably should not be using a Record and index types on TypeMap +// because in strict checking they end up required. +// See: https://github.com/apache/arrow/issues/12663#issuecomment-1088244575 +// We can work around that issue by using a type alias instead of an interface +// Where index signatures are looser. +// See: https://github.com/microsoft/TypeScript/issues/15300#issuecomment-1317901527 +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type WaferRequiredFields = { + colIndex: Int32, + rowIndex: Int32, + value: Float64 +}; From 7bfc34b3aea5927b5658fa9a2f877c06e4e35d70 Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Mon, 25 Mar 2024 17:03:11 +0000 Subject: [PATCH 15/18] applying package updates [skip ci] --- .../projects/ni/nimble-angular/CHANGELOG.json | 15 +++++++++++++++ .../projects/ni/nimble-angular/CHANGELOG.md | 10 +++++++++- .../projects/ni/nimble-angular/package.json | 4 ++-- ...ents-163379f4-09c6-4606-95f4-05917dd50ee0.json | 7 ------- package-lock.json | 8 ++++---- packages/nimble-blazor/package.json | 2 +- packages/nimble-components/CHANGELOG.json | 15 +++++++++++++++ packages/nimble-components/CHANGELOG.md | 10 +++++++++- packages/nimble-components/package.json | 2 +- 9 files changed, 56 insertions(+), 17 deletions(-) delete mode 100644 change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json index c95bf7331b..43e44a26b9 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-angular", "entries": [ + { + "date": "Mon, 25 Mar 2024 17:03:11 GMT", + "version": "20.5.3", + "tag": "@ni/nimble-angular_v20.5.3", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@ni/nimble-angular", + "comment": "Bump @ni/nimble-components to v23.0.1", + "commit": "not available" + } + ] + } + }, { "date": "Thu, 21 Mar 2024 17:13:38 GMT", "version": "20.5.2", diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md index 3a4d8e308d..9f66bd06eb 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-angular -This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. +This log was last generated on Mon, 25 Mar 2024 17:03:11 GMT and should not be manually modified. <!-- Start content --> +## 20.5.3 + +Mon, 25 Mar 2024 17:03:11 GMT + +### Patches + +- Bump @ni/nimble-components to v23.0.1 + ## 20.5.2 Thu, 21 Mar 2024 17:13:38 GMT diff --git a/angular-workspace/projects/ni/nimble-angular/package.json b/angular-workspace/projects/ni/nimble-angular/package.json index b6db60197e..d98a826070 100644 --- a/angular-workspace/projects/ni/nimble-angular/package.json +++ b/angular-workspace/projects/ni/nimble-angular/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-angular", - "version": "20.5.2", + "version": "20.5.3", "description": "Angular components for the NI Nimble Design System", "scripts": { "invoke-publish": "cd ../../../ && npm run build:library && cd dist/ni/nimble-angular && npm publish" @@ -31,7 +31,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^23.0.0" + "@ni/nimble-components": "^23.0.1" }, "dependencies": { "tslib": "^2.2.0" diff --git a/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json b/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json deleted file mode 100644 index 7456d8a059..0000000000 --- a/change/@ni-nimble-components-163379f4-09c6-4606-95f4-05917dd50ee0.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "patch", - "comment": "Created new hover event for the new diesTable api and changed the zoom event", - "packageName": "@ni/nimble-components", - "email": "33986780+munteannatan@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/package-lock.json b/package-lock.json index 46b53e8b5b..3767bc84bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ }, "angular-workspace/projects/ni/nimble-angular": { "name": "@ni/nimble-angular", - "version": "20.5.2", + "version": "20.5.3", "license": "MIT", "dependencies": { "tslib": "^2.2.0" @@ -85,7 +85,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^23.0.0" + "@ni/nimble-components": "^23.0.1" } }, "node_modules/@11ty/dependency-tree": { @@ -33940,7 +33940,7 @@ }, "packages/nimble-blazor": { "name": "@ni/nimble-blazor", - "version": "14.5.2", + "version": "14.5.3", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -33976,7 +33976,7 @@ }, "packages/nimble-components": { "name": "@ni/nimble-components", - "version": "23.0.0", + "version": "23.0.1", "license": "MIT", "dependencies": { "@microsoft/fast-colors": "^5.3.1", diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index 85d6a32cc7..fc97e5c96e 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-blazor", - "version": "14.5.2", + "version": "14.5.3", "description": "Blazor components for the NI Nimble Design System", "scripts": { "postinstall": "node build/generate-playwright-version-properties/source/index.js", diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index 13aaa57ee5..f72608c8e3 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Mon, 25 Mar 2024 17:03:11 GMT", + "version": "23.0.1", + "tag": "@ni/nimble-components_v23.0.1", + "comments": { + "patch": [ + { + "author": "33986780+munteannatan@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "f56b73b45161a55b967dc03bbdd094a6527c814c", + "comment": "Created new hover event for the new diesTable api and changed the zoom event" + } + ] + } + }, { "date": "Fri, 22 Mar 2024 16:18:25 GMT", "version": "23.0.0", diff --git a/packages/nimble-components/CHANGELOG.md b/packages/nimble-components/CHANGELOG.md index a3208751fb..4b8e71ac3a 100644 --- a/packages/nimble-components/CHANGELOG.md +++ b/packages/nimble-components/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-components -This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. +This log was last generated on Mon, 25 Mar 2024 17:03:11 GMT and should not be manually modified. <!-- Start content --> +## 23.0.1 + +Mon, 25 Mar 2024 17:03:11 GMT + +### Patches + +- Created new hover event for the new diesTable api and changed the zoom event ([ni/nimble@f56b73b](https://github.com/ni/nimble/commit/f56b73b45161a55b967dc03bbdd094a6527c814c)) + ## 23.0.0 Thu, 21 Mar 2024 17:13:38 GMT diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index b2052a19b5..171e0ee8b9 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-components", - "version": "23.0.0", + "version": "23.0.1", "description": "Styled web components for the NI Nimble Design System", "scripts": { "build": "npm run generate-icons && npm run generate-workers && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", From 95fa45b84942b1fe3ee67cb5c215ab7192e66229 Mon Sep 17 00:00:00 2001 From: Fred Visser <1458528+fredvisser@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:34:46 -0500 Subject: [PATCH 16/18] Add dependency review check (#1930) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## ๐Ÿคจ Rationale #801 highlighted that our current use of `npm audit` is brittle. This action should elevate any issues tracked by Github to the PR. ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation - Use the example config file from https://github.com/actions/dependency-review-action?tab=readme-ov-file - I'll remove the Snyk integration when this PR goes in ## ๐Ÿงช Testing This PR only highlights the packages that are changed (the Github Actions), but since the [Github dependency graph](https://github.com/ni/nimble/network/dependencies) sees our other NPM dependencies, I expect this will evaluate package.json issues when a PR has those changes in it. I could add known bad issues to this PR to validate, or we could just submit this and validate over time. ## โœ… Checklist <!--- Review the list and put an x in the boxes that apply or ~~strike through~~ around items that don't (along with an explanation). --> - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --- .github/workflows/dependency-review.yml | 17 +++++++++++++++++ .github/workflows/main.yml | 5 ----- CONTRIBUTING.md | 6 +++--- 3 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000000..c6e603f450 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,17 @@ +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + pull-requests: write + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 + with: + comment-summary-in-pr: on-failure diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7ab04208e6..4bc5b6ef05 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,11 +58,6 @@ jobs: # only informational so swallow error codes - run: npm outdated || exit 0 - # Audit - - run: npm audit --only=prod - # https://github.com/ni/nimble/issues/801 - # - run: npm audit --audit-level=critical - # Build - run: npm run build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6570fceeb..8003ae7ad3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -79,9 +79,9 @@ When generating a change file, follow these guidelines: 2. Write a brief but useful description with Nimble clients in mind. If making a major (breaking) change, explain what clients need to do to adopt it. The description can be plain text or [markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax), with newlines specified via `\n` if needed. 3. If you prefer not to expose your email address to the world, [configure GitHub to "Keep my email address private"](https://github.com/settings/emails) before generating the change file. -### NPM audit +### Dependency Review -The repository runs [`npm audit`](https://docs.npmjs.com/cli/v8/commands/npm-audit) to prevent submissions if any dependencies have known vulnerabilities. This can occur during on a PR that introduces a new dependency version or on an unrelated PR if a vulnerability was recently reported on an existing dependency. If this check fails, our options include: +The repository runs the [Dependency Review](https://github.com/actions/dependency-review-action) action to prevent submissions if any dependencies have known vulnerabilities. This can occur during on a PR that introduces a new dependency version or on an unrelated PR if a vulnerability was recently reported on an existing dependency. If this check fails, our options include: #### Vulnerabilities with fixes available @@ -93,7 +93,7 @@ The repository runs [`npm audit`](https://docs.npmjs.com/cli/v8/commands/npm-aud If a fix for the vulnerability isn't available or if it isn't practical to uptake the fix, our options include: 1. Remove the vulnerable dependency and find a different way to achieve the same functionality. -2. Temporarily use a more lenient [audit level](https://docs.npmjs.com/cli/v8/commands/npm-audit#audit-level) for this repository (e.g. allowing `low` or `moderate` vulnerabilities). We should ensure there is an issue on the dependency's repository asking them to fix the vulnerability and also file an issue against this repository to track fixing the vulnerability and restoring strict auditing. +2. Dismiss the alert in the [GitHub Security - Dependabot](https://github.com/ni/nimble/security/dependabot) dashboard, and document your rationale for doing so. We should ensure there is an issue on the dependency's repository asking them to fix the vulnerability and also file an issue against this repository to track fixing the vulnerability and restoring strict auditing. ### Chromatic visual component tests From 594ac221124cc1b52cd28113714bb8ff71e5820b Mon Sep 17 00:00:00 2001 From: m-akinc <7282195+m-akinc@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:27:25 -0500 Subject: [PATCH 17/18] Support primary and accent variants for toggle and menu buttons (#1934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## ๐Ÿคจ Rationale Fixes: #1906 ## ๐Ÿ‘ฉโ€๐Ÿ’ป Implementation - The ask was for the accent appearance variant on the menu button, but because the menu button uses the toggle button internally, I added the `appearance-variant` attribute to both toggle and menu button. - I added support for both primary and accent appearance variants. - When adding the new attribute states to the toggle and menu button matrix stories, I moved some common button state arrays to a new file in `patterns/buttons/tests`. - While examining visual designs/colors, I found and fixed several issues: - The `DigitalGreenDark` token value was incorrect, based on the Figma document. I updated this value, which affected block-accent button color and the rich-text mention font color. - Anchors in active, prominent, and prominent+active states were using the wrong color tokens. - The icon color for outline-accent buttons should match the text color, but didn't. - After consulting with Brandon, he directed me to change the active/pressed colors for the block-primary and block-accent button appearances so they would be consistent with other button active/pressed colors. Previously, they were slightly darker versions of the primary and accent colors (see below). This allowed me to remove the two, now-unused tokens: `buttonFillActivePrimaryColor` and `buttonFillAccentActiveColor`. ![image](https://github.com/ni/nimble/assets/7282195/29237669-5812-44dd-a426-5388ccac7262) To avoid increasing the size of this PR, Angular/Blazor support will be added in a follow-up PR. ## ๐Ÿงช Testing Lots of manual state styling testing in Storybook. Also Chromatic visual tests. ## โœ… Checklist - [x] I have updated the project documentation to reflect my changes or determined no changes are needed. --------- Co-authored-by: Milan Raj <rajsite@users.noreply.github.com> --- ...-083cf44c-68b4-43f6-b689-efd81c8228b4.json | 7 + ...-12958de0-2edc-4e06-a0ff-61431c96010a.json | 7 + .../tests/anchor-button-matrix.stories.ts | 33 +-- .../src/anchor-button/tests/anchor-button.mdx | 6 +- .../src/button/tests/button-matrix.stories.ts | 30 +-- .../src/button/tests/button.mdx | 202 +----------------- .../src/menu-button/index.ts | 11 +- .../src/menu-button/template.ts | 1 + .../tests/menu-button-matrix.stories.ts | 34 ++- .../src/menu-button/tests/menu-button.mdx | 6 +- .../menu-button/tests/menu-button.stories.ts | 32 ++- .../src/menu-button/types.ts | 5 +- .../src/patterns/button/styles.ts | 84 ++++---- .../src/patterns/button/tests/states.ts | 25 +++ .../patterns/button/tests/styling-docs.mdx | 194 +++++++++++++++++ .../src/spinner/tests/spinner.mdx | 2 +- .../theme-provider/design-token-comments.ts | 4 - .../src/theme-provider/design-token-names.ts | 2 - .../src/theme-provider/design-tokens.ts | 34 +-- .../src/toggle-button/index.ts | 10 +- .../src/toggle-button/styles.ts | 98 ++++----- .../tests/toggle-button-matrix.stories.ts | 34 ++- .../src/toggle-button/tests/toggle-button.mdx | 6 +- .../tests/toggle-button.stories.ts | 24 ++- .../src/toggle-button/types.ts | 5 +- .../styledictionary/properties/colors.json | 2 +- 26 files changed, 449 insertions(+), 449 deletions(-) create mode 100644 change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json create mode 100644 change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json create mode 100644 packages/nimble-components/src/patterns/button/tests/states.ts create mode 100644 packages/nimble-components/src/patterns/button/tests/styling-docs.mdx diff --git a/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json b/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json new file mode 100644 index 0000000000..f20c5cd2f2 --- /dev/null +++ b/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json @@ -0,0 +1,7 @@ +{ + "type": "major", + "comment": "Support primary and accent variants for toggle and menu buttons. BREAKING CHANGE: Removed theme-aware tokens `buttonFillActivePrimaryColor` and `buttonFillAccentActiveColor`. Use `fillSelectedColor` instead.", + "packageName": "@ni/nimble-components", + "email": "7282195+m-akinc@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json b/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json new file mode 100644 index 0000000000..cfca0025d2 --- /dev/null +++ b/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Fix value of DigitalGreenDark", + "packageName": "@ni/nimble-tokens", + "email": "7282195+m-akinc@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/nimble-components/src/anchor-button/tests/anchor-button-matrix.stories.ts b/packages/nimble-components/src/anchor-button/tests/anchor-button-matrix.stories.ts index 8042bcfc73..5306713f61 100644 --- a/packages/nimble-components/src/anchor-button/tests/anchor-button-matrix.stories.ts +++ b/packages/nimble-components/src/anchor-button/tests/anchor-button-matrix.stories.ts @@ -1,10 +1,5 @@ import type { StoryFn, Meta } from '@storybook/html'; import { html, ViewTemplate, when } from '@microsoft/fast-element'; -import { pascalCase } from '@microsoft/fast-web-utilities'; -import { - ButtonAppearance, - ButtonAppearanceVariant -} from '../../patterns/button/types'; import { createMatrix, sharedMatrixParameters, @@ -17,6 +12,14 @@ import { textCustomizationWrapper } from '../../utilities/tests/text-customizati import { anchorButtonTag } from '..'; import { iconLinkTag } from '../../icons/link'; import { iconArrowExpanderRightTag } from '../../icons/arrow-expander-right'; +import { + appearanceStates, + type AppearanceState, + type AppearanceVariantState, + type PartVisibilityState, + appearanceVariantStates, + partVisibilityStates +} from '../../patterns/button/tests/states'; const metadata: Meta = { title: 'Tests/Anchor Button', @@ -27,26 +30,6 @@ const metadata: Meta = { export default metadata; -/* array of iconVisible, labelVisible, endIconVisible */ -const partVisibilityStates = [ - [true, true, false], - [true, false, false], - [false, true, false], - [true, true, true], - [false, true, true] -] as const; -type PartVisibilityState = (typeof partVisibilityStates)[number]; - -const appearanceStates: [string, string | undefined][] = Object.entries( - ButtonAppearance -).map(([key, value]) => [pascalCase(key), value]); -type AppearanceState = (typeof appearanceStates)[number]; - -const appearanceVariantStates: [string, string | undefined][] = Object.entries( - ButtonAppearanceVariant -).map(([key, value]) => [pascalCase(key), value]); -type AppearanceVariantState = (typeof appearanceVariantStates)[number]; - // prettier-ignore const component = ( [disabledName, disabled]: DisabledState, diff --git a/packages/nimble-components/src/anchor-button/tests/anchor-button.mdx b/packages/nimble-components/src/anchor-button/tests/anchor-button.mdx index f989f03654..eb28b9228d 100644 --- a/packages/nimble-components/src/anchor-button/tests/anchor-button.mdx +++ b/packages/nimble-components/src/anchor-button/tests/anchor-button.mdx @@ -8,6 +8,8 @@ import { } from '@storybook/blocks'; import TargetDocs from '../../patterns/anchor/tests/target-docs.mdx'; import ContentHiddenDocs from '../../patterns/button/tests/content-hidden-docs.mdx'; +import StylingDocs from '../../patterns/button/tests/styling-docs.mdx'; +import { anchorButtonTag } from '..'; import * as anchorButtonStories from './anchor-button.stories'; <Meta of={anchorButtonStories} /> @@ -18,9 +20,7 @@ An anchor button is a component with the visual appearance of a button, but it n <Canvas of={anchorButtonStories.outlineAnchorButton} /> <Controls of={anchorButtonStories.outlineAnchorButton} /> -{/* ## Appearances */} - -{/* ## Appearance Variants */} +<StylingDocs components={{ Button: anchorButtonTag }} /> {/* ## Usage */} diff --git a/packages/nimble-components/src/button/tests/button-matrix.stories.ts b/packages/nimble-components/src/button/tests/button-matrix.stories.ts index 353dd05d6c..fc0e33694d 100644 --- a/packages/nimble-components/src/button/tests/button-matrix.stories.ts +++ b/packages/nimble-components/src/button/tests/button-matrix.stories.ts @@ -1,7 +1,5 @@ import type { StoryFn, Meta } from '@storybook/html'; import { html, ViewTemplate, when } from '@microsoft/fast-element'; -import { pascalCase } from '@microsoft/fast-web-utilities'; -import { ButtonAppearance, ButtonAppearanceVariant } from '../types'; import { createMatrix, sharedMatrixParameters, @@ -15,6 +13,14 @@ import { buttonTag } from '..'; import { iconKeyTag } from '../../icons/key'; import { iconArrowExpanderDownTag } from '../../icons/arrow-expander-down'; import { bodyFont } from '../../theme-provider/design-tokens'; +import { + appearanceStates, + type AppearanceState, + type AppearanceVariantState, + type PartVisibilityState, + appearanceVariantStates, + partVisibilityStates +} from '../../patterns/button/tests/states'; const metadata: Meta = { title: 'Tests/Button', @@ -25,26 +31,6 @@ const metadata: Meta = { export default metadata; -/* array of iconVisible, labelVisible, endIconVisible */ -const partVisibilityStates = [ - [true, true, false], - [true, false, false], - [false, true, false], - [true, true, true], - [false, true, true] -] as const; -type PartVisibilityState = (typeof partVisibilityStates)[number]; - -const appearanceStates: [string, string | undefined][] = Object.entries( - ButtonAppearance -).map(([key, value]) => [pascalCase(key), value]); -type AppearanceState = (typeof appearanceStates)[number]; - -const appearanceVariantStates: [string, string | undefined][] = Object.entries( - ButtonAppearanceVariant -).map(([key, value]) => [pascalCase(key), value]); -type AppearanceVariantState = (typeof appearanceVariantStates)[number]; - // prettier-ignore const component = ( [disabledName, disabled]: DisabledState, diff --git a/packages/nimble-components/src/button/tests/button.mdx b/packages/nimble-components/src/button/tests/button.mdx index e8a22b9ca6..bc9156eb54 100644 --- a/packages/nimble-components/src/button/tests/button.mdx +++ b/packages/nimble-components/src/button/tests/button.mdx @@ -1,7 +1,6 @@ import { Canvas, Meta, Controls, Title } from '@storybook/blocks'; import ContentHiddenDocs from '../../patterns/button/tests/content-hidden-docs.mdx'; -import { NimbleButton } from './button.react'; -import { NimbleIconKey } from '../../icons/tests/key.react'; +import StylingDocs from '../../patterns/button/tests/styling-docs.mdx'; import { buttonTag } from '..'; import { anchorButtonTag } from '../../anchor-button'; import * as buttonStories from './button.stories'; @@ -18,209 +17,12 @@ If you want a button that triggers navigation to a URL, use the <Tag name={ancho <Canvas of={buttonStories.outlineButton} /> <Controls of={buttonStories.outlineButton} /> -## Styling - -### Appearances - -These appearances have the default styling of the <Tag name={buttonTag}/>. Each should be considered for use before using appearance variant buttons. - -#### Ghost Button: - -<Frame> - <Container> - <Column stylingClass="controls"> - <NimbleButton appearance="ghost">{`Ghost Button`}</NimbleButton> - <NimbleButton appearance="ghost" content-hidden> - <NimbleIconKey slot="start"></NimbleIconKey> - {`Ghost Button`} - </NimbleButton> - - </Column> - <Column> - <ul> - <li>Ghost is the default appearance and should be the first considered for use.</li> - <li> - Use as the default and standard option to create a clean airy and open UI - feel. Ghost buttons fit comfortably in tight spaces and help control the - visual density of the UI. - </li> - <li> - Be careful when using that the surrounding context does not cause this - button to be confused for emphasized body text, tabs or a standalone links. - </li> - <li>Use in combination with a primary outline or primary block buttons to create a hierarchy of importance. There is no primary ghost button.</li> - </ul> - </Column> - </Container> - -</Frame> - -#### Outline Button: - -<Frame> - <Container> - <Column stylingClass="controls"> - <NimbleButton appearance="outline">{`Outline Button`}</NimbleButton> - <NimbleButton appearance="outline" content-hidden> - <NimbleIconKey slot="start"></NimbleIconKey> - {`Outline Button`} - </NimbleButton> - </Column> - <Column> - <ul> - <li> - Outline is the secondary style and should be considered for - use when ghost button is not sufficient. - </li> - <li> - Use as an alternative standard button when a ghost button is - not suitable. Use like a ghost button to create a clean, - light and airy feel. - </li> - <li> - The outline button is more visually direct about the - control's functionality than a ghost button. - </li> - <li> - Use in combination with ghost buttons (but not block - buttons) to create hierarchy. - </li> - </ul> - </Column> - </Container> -</Frame> - -#### Block Button: - -<Frame> - <Container> - <Column stylingClass="controls"> - <NimbleButton appearance="block">{`Block Button`}</NimbleButton> - <NimbleButton appearance="block" content-hidden> - <NimbleIconKey slot="start"></NimbleIconKey> - {`Block Button`} - </NimbleButton> - </Column> - <Column> - <ul> - <li> - Block is the tertiary style used for creating the most eye - catching and functionally direct button. Use in areas where - controls are not often present or obvious, or when lots of - busy information can cause an important control to be - overlooked. - </li> - <li> - Use as a standard button when the most visible solution is - required. Use as an alternative to overly subtle button - solutions when it is important to emphasize an action and - the functionality of the control. - </li> - <li> - Use in combination with ghost buttons (but not outline - buttons) to create hierarchy. - </li> - </ul> - </Column> - </Container> -</Frame> - -### Appearance Variants - -Button appearance variants are mainly used when a button needs be distinguished for one of the following reasons: - -- To indicate the action that allows the user to accomplish their most common or important goal -- To indicate the action that allows the user to complete their task - -There are currently two available values for `appearance-variant`: `primary` and `accent`. - -#### Accent Button: - -<Frame> - <Container config="325px 1fr"> - <Column stylingClass="controls"> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton - appearance="outline" - appearance-variant="accent" - >{`Outline Accent`}</NimbleButton> - <Divider /> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton - appearance="block" - appearance-variant="accent" - >{`Block Accent`}</NimbleButton> - </Column> - <Column> - <Do> - Use only 1 accent button in a section. It should be used when - trying to achieve the most prominent eye-catching approach. - Consider the contextual implications of using a green colored - button in relation to its name or metaphor. Remember that color - has accessibility constraints and the color alone should not be - relied on. - </Do> - <Do> - Use in situations that lack color and enthusiasm to help support - the brand. - </Do> - <Do>Use in combination with ghost buttons to create hierarchy.</Do> - <Dont> - Do not use an outline button with a block button to create - hierarchy. - </Dont> - </Column> - </Container> -</Frame> - -#### Primary Button: - -<Frame> - <Container config="325px 1fr"> - <Column stylingClass="controls"> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="outline" appearance-variant="primary"> - {`Outline Primary`} - </NimbleButton> - <Divider/> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="ghost">{`Ghost`}</NimbleButton> - <NimbleButton appearance="block" appearance-variant="primary"> - {`Block Primary`} - </NimbleButton> - </Column> - <Column> - <Do> - Use only 1 primary button in a section. It should be used when - there is a conflict with color and its context. - </Do> - <Do>Use in combination with ghost buttons to create hierarchy.</Do> - <Dont> - Do not use an outline button with a block button to create - hierarchy. - </Dont> - </Column> - </Container> - -</Frame> - -#### Examples: - -To see more examples of appearance variant button hierarchy, see the nimble-button Figma docs for [Primary and Standard Actions](https://www.figma.com/file/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?type=design&node-id=1604-74603&mode=design&t=SQ3lyK83VHBUaOkg-0). +<StylingDocs components={{ Button: buttonTag }} /> ## Sizing Nimble Buttons are currently always 32px tall. Designs exist for other sizes; if you need these in an application, please comment on [Configurable height for nimble controls (#610)](https://github.com/ni/nimble/issues/610). -## Styling / Theme - -Use the Color UI version for backgrounds with color (e.g. purple, blue). - -See the usage details for more information on button styling / usage. - ## Accessibility Please work with your designer and ensure you have a 4.5:1 diff --git a/packages/nimble-components/src/menu-button/index.ts b/packages/nimble-components/src/menu-button/index.ts index de3bbef6d3..d0fec46402 100644 --- a/packages/nimble-components/src/menu-button/index.ts +++ b/packages/nimble-components/src/menu-button/index.ts @@ -6,11 +6,15 @@ import { keyArrowUp, keyEscape } from '@microsoft/fast-web-utilities'; -import { ButtonAppearance } from '../button/types'; +import { + ButtonAppearance, + ButtonAppearanceVariant, + MenuButtonToggleEventDetail, + MenuButtonPosition +} from './types'; import type { ToggleButton } from '../toggle-button'; import { styles } from './styles'; import { template } from './template'; -import { MenuButtonToggleEventDetail, MenuButtonPosition } from './types'; import type { ButtonPattern } from '../patterns/button/types'; import type { AnchoredRegion } from '../anchored-region'; @@ -27,6 +31,9 @@ export class MenuButton extends FoundationElement implements ButtonPattern { @attr public appearance: ButtonAppearance = ButtonAppearance.outline; + @attr({ attribute: 'appearance-variant' }) + public appearanceVariant: ButtonAppearanceVariant; + @attr({ mode: 'boolean' }) public disabled = false; diff --git a/packages/nimble-components/src/menu-button/template.ts b/packages/nimble-components/src/menu-button/template.ts index a32ccc5659..891527ec98 100644 --- a/packages/nimble-components/src/menu-button/template.ts +++ b/packages/nimble-components/src/menu-button/template.ts @@ -12,6 +12,7 @@ export const template = html<MenuButton>` <${toggleButtonTag} part="button" appearance="${x => x.appearance}" + appearance-variant="${x => x.appearanceVariant}" ?content-hidden="${x => x.contentHidden}" ?checked="${x => x.open}" ?disabled="${x => x.disabled}" diff --git a/packages/nimble-components/src/menu-button/tests/menu-button-matrix.stories.ts b/packages/nimble-components/src/menu-button/tests/menu-button-matrix.stories.ts index 3b9de718a7..14f7d570cd 100644 --- a/packages/nimble-components/src/menu-button/tests/menu-button-matrix.stories.ts +++ b/packages/nimble-components/src/menu-button/tests/menu-button-matrix.stories.ts @@ -1,7 +1,5 @@ import type { StoryFn, Meta } from '@storybook/html'; import { html, ViewTemplate, when } from '@microsoft/fast-element'; -import { pascalCase } from '@microsoft/fast-web-utilities'; -import { ButtonAppearance } from '../types'; import { createMatrix, sharedMatrixParameters, @@ -15,6 +13,14 @@ import { iconKeyTag } from '../../icons/key'; import { menuButtonTag } from '..'; import { menuTag } from '../../menu'; import { menuItemTag } from '../../menu-item'; +import { + appearanceStates, + type AppearanceState, + type AppearanceVariantState, + type PartVisibilityState, + appearanceVariantStates, + partVisibilityStates +} from '../../patterns/button/tests/states'; const metadata: Meta = { title: 'Tests/Menu Button', @@ -25,34 +31,21 @@ const metadata: Meta = { export default metadata; -/* array of iconVisible, labelVisible, endIconVisible */ -const partVisibilityStates = [ - [true, true, false], - [true, false, false], - [false, true, false], - [true, true, true], - [false, true, true] -] as const; -type PartVisibilityState = (typeof partVisibilityStates)[number]; - -const appearanceStates = Object.entries(ButtonAppearance).map( - ([key, value]) => [pascalCase(key), value] -); -type AppearanceState = (typeof appearanceStates)[number]; - // prettier-ignore const component = ( [iconVisible, labelVisible, endIconVisible]: PartVisibilityState, [disabledName, disabled]: DisabledState, - [appearanceName, appearance]: AppearanceState + [appearanceName, appearance]: AppearanceState, + [appearanceVariantName, appearanceVariant]: AppearanceVariantState, ): ViewTemplate => html` <${menuButtonTag} appearance="${() => appearance}" + appearance-variant="${() => appearanceVariant}" ?disabled=${() => disabled} ?content-hidden=${() => !labelVisible} style="margin-right: 8px; margin-bottom: 8px;"> ${when(() => iconVisible, html`<${iconKeyTag} slot="start"></${iconKeyTag}>`)} - ${() => `${appearanceName!} Menu Button ${disabledName}`} + ${() => `${appearanceVariantName} ${appearanceName} Menu Button ${disabledName}`} ${when(() => endIconVisible, html`<${iconArrowExpanderDownTag} slot="end"></${iconArrowExpanderDownTag}>`)} <${menuTag} slot="menu"> @@ -66,7 +59,8 @@ export const menuButtonThemeMatrix: StoryFn = createMatrixThemeStory( createMatrix(component, [ partVisibilityStates, disabledStates, - appearanceStates + appearanceStates, + appearanceVariantStates ]) ); diff --git a/packages/nimble-components/src/menu-button/tests/menu-button.mdx b/packages/nimble-components/src/menu-button/tests/menu-button.mdx index 7c39ab4534..319b1a9e7b 100644 --- a/packages/nimble-components/src/menu-button/tests/menu-button.mdx +++ b/packages/nimble-components/src/menu-button/tests/menu-button.mdx @@ -1,5 +1,7 @@ import { Controls, Canvas, Meta, Title } from '@storybook/blocks'; import ContentHiddenDocs from '../../patterns/button/tests/content-hidden-docs.mdx'; +import StylingDocs from '../../patterns/button/tests/styling-docs.mdx'; +import { menuButtonTag } from '..'; import * as menuButtonStories from './menu-button.stories'; <Meta of={menuButtonStories} /> @@ -11,9 +13,7 @@ often styled as a typical push button with a downward pointing arrow or triangle <Canvas of={menuButtonStories.outlineButton} /> <Controls of={menuButtonStories.outlineButton} /> -{/* ## Appearances */} - -{/* ## Appearance Variants */} +<StylingDocs components={{ Button: menuButtonTag }} /> {/* ## Usage */} diff --git a/packages/nimble-components/src/menu-button/tests/menu-button.stories.ts b/packages/nimble-components/src/menu-button/tests/menu-button.stories.ts index 8a8e6bfcd3..74aa21800c 100644 --- a/packages/nimble-components/src/menu-button/tests/menu-button.stories.ts +++ b/packages/nimble-components/src/menu-button/tests/menu-button.stories.ts @@ -5,16 +5,25 @@ import { createUserSelectedThemeStory, disableStorybookZoomTransform } from '../../utilities/tests/storybook'; -import { ButtonAppearance, MenuButtonPosition } from '../types'; +import { + ButtonAppearance, + ButtonAppearanceVariant, + MenuButtonPosition +} from '../types'; import { iconArrowExpanderDownTag } from '../../icons/arrow-expander-down'; import { iconKeyTag } from '../../icons/key'; import { menuButtonTag } from '..'; import { menuTag } from '../../menu'; import { menuItemTag } from '../../menu-item'; +import { + appearanceDescription, + appearanceVariantDescription +} from '../../patterns/button/tests/doc-strings'; interface MenuButtonArgs { label: string; - appearance: string; + appearance: keyof typeof ButtonAppearance; + appearanceVariant: keyof typeof ButtonAppearanceVariant; open: boolean; disabled: boolean; icon: boolean; @@ -41,8 +50,15 @@ const metadata: Meta<MenuButtonArgs> = { }, argTypes: { appearance: { - options: Object.values(ButtonAppearance), - control: { type: 'radio' } + options: Object.keys(ButtonAppearance), + control: { type: 'radio' }, + description: appearanceDescription + }, + appearanceVariant: { + name: 'appearance-variant', + options: Object.keys(ButtonAppearanceVariant), + control: { type: 'radio' }, + description: appearanceVariantDescription }, icon: { description: @@ -63,7 +79,8 @@ const metadata: Meta<MenuButtonArgs> = { ?open="${x => x.open}" ?disabled="${x => x.disabled}" ?content-hidden="${x => x.contentHidden}" - appearance="${x => x.appearance}" + appearance="${x => ButtonAppearance[x.appearance]}" + appearance-variant="${x => ButtonAppearanceVariant[x.appearanceVariant]}" position="${x => x.menuPosition}" > ${when(x => x.icon, html`<${iconKeyTag} slot="start"></${iconKeyTag}>`)} @@ -88,8 +105,9 @@ const metadata: Meta<MenuButtonArgs> = { </${menuButtonTag}> `), args: { - label: 'Ghost Menu Button', - appearance: 'ghost', + label: 'Menu Button', + appearance: 'outline', + appearanceVariant: 'default', open: false, disabled: false, icon: false, diff --git a/packages/nimble-components/src/menu-button/types.ts b/packages/nimble-components/src/menu-button/types.ts index d9a1d76fcb..4d2371dee1 100644 --- a/packages/nimble-components/src/menu-button/types.ts +++ b/packages/nimble-components/src/menu-button/types.ts @@ -2,7 +2,10 @@ * Types of menu button appearance. * @public */ -export { ButtonAppearance } from '../patterns/button/types'; +export { + ButtonAppearance, + ButtonAppearanceVariant +} from '../patterns/button/types'; /** * The options of where to position the menu relative to the menu button. diff --git a/packages/nimble-components/src/patterns/button/styles.ts b/packages/nimble-components/src/patterns/button/styles.ts index 481ab08275..ee8e4b4310 100644 --- a/packages/nimble-components/src/patterns/button/styles.ts +++ b/packages/nimble-components/src/patterns/button/styles.ts @@ -16,10 +16,8 @@ import { standardPadding, buttonPrimaryFontColor, buttonFillPrimaryColor, - buttonFillActivePrimaryColor, buttonFillAccentColor, buttonAccentBlockFontColor, - buttonFillAccentActiveColor, buttonBorderAccentOutlineColor, buttonAccentOutlineFontColor } from '../../theme-provider/design-tokens'; @@ -28,7 +26,7 @@ import { ButtonAppearance } from './types'; import { accessiblyHidden } from '../../utilities/style/accessibly-hidden'; export const styles = css` - @layer base, hover, focusVisible, active, disabled, top; + @layer base, checked, hover, focusVisible, active, disabled, top; @layer base { ${display('inline-flex')} @@ -102,15 +100,15 @@ export const styles = css` display: contents; } - :host([content-hidden]) .content { - ${accessiblyHidden} - } - [part='start'] { display: contents; ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; } + :host([content-hidden]) .content { + ${accessiblyHidden} + } + [part='end'] { display: contents; ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; @@ -139,6 +137,8 @@ export const styles = css` @layer active { .control:active { box-shadow: none; + color: ${buttonLabelFontColor}; + border-color: ${borderHoverColor}; background-image: linear-gradient( ${fillSelectedColor}, ${fillSelectedColor} @@ -149,29 +149,30 @@ export const styles = css` .control:active::before { outline: none; } + + .control:active [part='start'], + .control:active [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; + } } @layer disabled { :host([disabled]) { - color: ${buttonLabelDisabledFontColor}; cursor: default; } :host([disabled]) .control { + color: ${buttonLabelDisabledFontColor}; box-shadow: none; background-image: none; - color: rgba(${actionRgbPartialColor}, 0.3); + background-size: 100% 100%; } :host([disabled]) .control::before { box-shadow: none; } - :host([disabled]) slot[name='start']::slotted(*) { - opacity: 0.3; - ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; - } - + :host([disabled]) slot[name='start']::slotted(*), :host([disabled]) slot[name='end']::slotted(*) { opacity: 0.3; ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; @@ -247,7 +248,6 @@ export const styles = css` rgba(${borderRgbPartialColor}, 0.1), rgba(${borderRgbPartialColor}, 0.1) ); - background-size: 100% 100%; border-color: rgba(${borderRgbPartialColor}, 0.1); } } @@ -268,6 +268,26 @@ export const buttonAppearanceVariantStyles = css``.withBehaviors( border-color: ${buttonBorderAccentOutlineColor}; color: ${buttonAccentOutlineFontColor}; } + + :host([appearance-variant='accent']) [part='start'], + :host([appearance-variant='accent']) [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonAccentOutlineFontColor}; + } + } + + @layer active { + :host([appearance-variant='accent']) .control:active { + color: ${buttonAccentOutlineFontColor}; + } + + :host([appearance-variant='accent']) + .control:active + [part='start'], + :host([appearance-variant='accent']) + .control:active + [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonAccentOutlineFontColor}; + } } ` ), @@ -275,10 +295,6 @@ export const buttonAppearanceVariantStyles = css``.withBehaviors( ButtonAppearance.block, css` @layer base { - :host([appearance-variant='primary']) [part='start'] { - ${iconColor.cssCustomProperty}: white; - } - :host([appearance-variant='primary']) .control { background-image: linear-gradient( ${buttonFillPrimaryColor}, @@ -288,14 +304,6 @@ export const buttonAppearanceVariantStyles = css``.withBehaviors( border-color: ${buttonFillPrimaryColor}; } - :host([appearance-variant='primary']) [part='end'] { - ${iconColor.cssCustomProperty}: white; - } - - :host([appearance-variant='accent']) [part='start'] { - ${iconColor.cssCustomProperty}: white; - } - :host([appearance-variant='accent']) .control { background-image: linear-gradient( ${buttonFillAccentColor}, @@ -305,24 +313,14 @@ export const buttonAppearanceVariantStyles = css``.withBehaviors( border-color: ${buttonFillAccentColor}; } - :host([appearance-variant='accent']) [part='end'] { - ${iconColor.cssCustomProperty}: white; - } - } - - @layer active { - :host([appearance-variant='primary']) .control:active { - background-image: linear-gradient( - ${buttonFillActivePrimaryColor}, - ${buttonFillActivePrimaryColor} - ); + :host([appearance-variant='primary']) [part='start'], + :host([appearance-variant='primary']) [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonPrimaryFontColor}; } - :host([appearance-variant='accent']) .control:active { - background-image: linear-gradient( - ${buttonFillAccentActiveColor}, - ${buttonFillAccentActiveColor} - ); + :host([appearance-variant='accent']) [part='start'], + :host([appearance-variant='accent']) [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonPrimaryFontColor}; } } ` diff --git a/packages/nimble-components/src/patterns/button/tests/states.ts b/packages/nimble-components/src/patterns/button/tests/states.ts new file mode 100644 index 0000000000..7ea753741f --- /dev/null +++ b/packages/nimble-components/src/patterns/button/tests/states.ts @@ -0,0 +1,25 @@ +import { ButtonAppearance, ButtonAppearanceVariant } from '../types'; + +/* array of iconVisible, labelVisible, endIconVisible */ +export const partVisibilityStates = [ + [true, true, false], + [true, false, false], + [false, true, false], + [true, true, true], + [false, true, true] +] as const; +export type PartVisibilityState = (typeof partVisibilityStates)[number]; + +export const appearanceStates = [ + ['Outline', ButtonAppearance.outline], + ['Ghost', ButtonAppearance.ghost], + ['Block', ButtonAppearance.block] +] as const; +export type AppearanceState = (typeof appearanceStates)[number]; + +export const appearanceVariantStates = [ + ['Default', ButtonAppearanceVariant.default], + ['Primary', ButtonAppearanceVariant.primary], + ['Accent', ButtonAppearanceVariant.accent] +] as const; +export type AppearanceVariantState = (typeof appearanceVariantStates)[number]; diff --git a/packages/nimble-components/src/patterns/button/tests/styling-docs.mdx b/packages/nimble-components/src/patterns/button/tests/styling-docs.mdx new file mode 100644 index 0000000000..8de2c9a749 --- /dev/null +++ b/packages/nimble-components/src/patterns/button/tests/styling-docs.mdx @@ -0,0 +1,194 @@ +import { NimbleIconKey } from '../../../icons/tests/key.react'; + +## Styling + +### Appearances + +These are the standard styling options for the button. Each should be considered for use before employing an appearance variant. + +#### Ghost Button: + +<Frame> + <Container> + <Column stylingClass="controls"> + <Button appearance="ghost">{`Ghost Button`}</Button> + <Button appearance="ghost" content-hidden> + <NimbleIconKey slot="start"></NimbleIconKey> + {`Ghost Button`} + </Button> + + </Column> + <Column> + <ul> + <li>Ghost is the default appearance and should be the first considered for use.</li> + <li> + Use as the default and standard option to create a clean airy and open UI + feel. Ghost buttons fit comfortably in tight spaces and help control the + visual density of the UI. + </li> + <li> + Be careful when using that the surrounding context does not cause this + button to be confused for emphasized body text, tabs or a standalone links. + </li> + <li>Use in combination with a primary outline or primary block buttons to create a hierarchy of importance. There is no primary ghost button.</li> + </ul> + </Column> + </Container> + +</Frame> + +#### Outline Button: + +<Frame> + <Container> + <Column stylingClass="controls"> + <Button appearance="outline">{`Outline Button`}</Button> + <Button appearance="outline" content-hidden> + <NimbleIconKey slot="start"></NimbleIconKey> + {`Outline Button`} + </Button> + </Column> + <Column> + <ul> + <li> + Outline is the secondary style and should be considered for + use when ghost button is not sufficient. + </li> + <li> + Use as an alternative standard button when a ghost button is + not suitable. Use like a ghost button to create a clean, + light and airy feel. + </li> + <li> + The outline button is more visually direct about the + control's functionality than a ghost button. + </li> + <li> + Use in combination with ghost buttons (but not block + buttons) to create hierarchy. + </li> + </ul> + </Column> + </Container> +</Frame> + +#### Block Button: + +<Frame> + <Container> + <Column stylingClass="controls"> + <Button appearance="block">{`Block Button`}</Button> + <Button appearance="block" content-hidden> + <NimbleIconKey slot="start"></NimbleIconKey> + {`Block Button`} + </Button> + </Column> + <Column> + <ul> + <li> + Block is the tertiary style used for creating the most eye + catching and functionally direct button. Use in areas where + controls are not often present or obvious, or when lots of + busy information can cause an important control to be + overlooked. + </li> + <li> + Use as a standard button when the most visible solution is + required. Use as an alternative to overly subtle button + solutions when it is important to emphasize an action and + the functionality of the control. + </li> + <li> + Use in combination with ghost buttons (but not outline + buttons) to create hierarchy. + </li> + </ul> + </Column> + </Container> +</Frame> + +### Appearance Variants + +Button appearance variants are mainly used when a button needs be distinguished for one of the following reasons: + +- To indicate the action that allows the user to accomplish their most common or important goal +- To indicate the action that allows the user to complete their task + +There are two available values for `appearance-variant`: `primary` and `accent`. + +#### Accent Button: + +<Frame> + <Container config="325px 1fr"> + <Column stylingClass="controls"> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="ghost">{`Ghost`}</Button> + <Button + appearance="outline" + appearance-variant="accent" + >{`Outline Accent`}</Button> + <Divider /> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="ghost">{`Ghost`}</Button> + <Button + appearance="block" + appearance-variant="accent" + >{`Block Accent`}</Button> + </Column> + <Column> + <Do> + Use only 1 accent button in a section. It should be used when + trying to achieve the most prominent eye-catching approach. + Consider the contextual implications of using a green colored + button in relation to its name or metaphor. Remember that color + has accessibility constraints and the color alone should not be + relied on. + </Do> + <Do> + Use in situations that lack color and enthusiasm to help support + the brand. + </Do> + <Do>Use in combination with ghost buttons to create hierarchy.</Do> + <Dont> + Do not use an outline button with a block button to create + hierarchy. + </Dont> + </Column> + </Container> +</Frame> + +#### Primary Button: + +<Frame> + <Container config="325px 1fr"> + <Column stylingClass="controls"> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="outline" appearance-variant="primary"> + {`Outline Primary`} + </Button> + <Divider/> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="ghost">{`Ghost`}</Button> + <Button appearance="block" appearance-variant="primary"> + {`Block Primary`} + </Button> + </Column> + <Column> + <Do> + Use only 1 primary button in a section. It should be used when + there is a conflict with color and its context. + </Do> + <Do>Use in combination with ghost buttons to create hierarchy.</Do> + <Dont> + Do not use an outline button with a block button to create + hierarchy. + </Dont> + </Column> + </Container> + +</Frame> + +#### Examples: + +To see more examples of appearance variant button hierarchy, see the Figma docs for [Primary and Standard Actions](https://www.figma.com/file/PO9mFOu5BCl8aJvFchEeuN/Nimble_Components?type=design&node-id=1604-74603&mode=design&t=SQ3lyK83VHBUaOkg-0). diff --git a/packages/nimble-components/src/spinner/tests/spinner.mdx b/packages/nimble-components/src/spinner/tests/spinner.mdx index ca16347852..a93463cef2 100644 --- a/packages/nimble-components/src/spinner/tests/spinner.mdx +++ b/packages/nimble-components/src/spinner/tests/spinner.mdx @@ -27,7 +27,7 @@ Multiple 16px spinners can be used on a single screen at one time. ## Styling / Theme -Use the `default` appearance Color UI version for backgrounds with color (e.g. purple, blue). Do not use the `accent` appearance on any colored backgrounds, instead use the `default` Color UI version. +Use the `default` appearance and Color theme for UIs with a strong background color. Do not use the `accent` appearance with the Color theme. See the `size` and `appearance` usage details for information on customizing the spinner size and guidance for which appearance to use. diff --git a/packages/nimble-components/src/theme-provider/design-token-comments.ts b/packages/nimble-components/src/theme-provider/design-token-comments.ts index 945379c8bf..986dfb39f3 100644 --- a/packages/nimble-components/src/theme-provider/design-token-comments.ts +++ b/packages/nimble-components/src/theme-provider/design-token-comments.ts @@ -13,8 +13,6 @@ export const comments: { readonly [key in TokenName]: string | null } = { 'Control fill color for "primary" appearance-variant buttons', buttonPrimaryFontColor: 'Font color for "primary" appearance-variant buttons', - buttonFillActivePrimaryColor: - 'Active fill color for "primary" appearance-variant buttons', buttonFillAccentColor: 'Control fill color for "accent" appearance-variant buttons', buttonAccentBlockFontColor: @@ -23,8 +21,6 @@ export const comments: { readonly [key in TokenName]: string | null } = { 'Font color for "accent" appearance-variant outline buttons', buttonBorderAccentOutlineColor: 'Border color for "accent" appearance-variant outline buttons', - buttonFillAccentActiveColor: - 'Active fill color for "accent" appearance-variant buttons', fillSelectedColor: 'Control fill color when a control is selected', fillSelectedRgbPartialColor: 'DEPRECATED: *-partial tokens are used with rgba() to set color transparency in component stylesheets', diff --git a/packages/nimble-components/src/theme-provider/design-token-names.ts b/packages/nimble-components/src/theme-provider/design-token-names.ts index 02900b47d5..6ba34439e4 100644 --- a/packages/nimble-components/src/theme-provider/design-token-names.ts +++ b/packages/nimble-components/src/theme-provider/design-token-names.ts @@ -15,12 +15,10 @@ export const tokenNames: { readonly [key in TokenName]: string } = { sectionBackgroundColor: 'section-background-color', buttonFillPrimaryColor: 'button-fill-primary-color', buttonPrimaryFontColor: 'button-primary-font-color', - buttonFillActivePrimaryColor: 'button-fill-active-primary-color', buttonFillAccentColor: 'button-fill-accent-color', buttonAccentBlockFontColor: 'button-accent-block-font-color', buttonAccentOutlineFontColor: 'button-accent-outline-font-color', buttonBorderAccentOutlineColor: 'button-border-accent-outline-color', - buttonFillAccentActiveColor: 'button-fill-accent-active-color', fillSelectedColor: 'fill-selected-color', fillSelectedRgbPartialColor: 'fill-selected-rgb-partial-color', fillHoverSelectedColor: 'fill-hover-selected-color', diff --git a/packages/nimble-components/src/theme-provider/design-tokens.ts b/packages/nimble-components/src/theme-provider/design-tokens.ts index 015722a783..dcb6b0fb05 100644 --- a/packages/nimble-components/src/theme-provider/design-tokens.ts +++ b/packages/nimble-components/src/theme-provider/design-tokens.ts @@ -98,8 +98,7 @@ import { GridHeaderFamily, GridHeaderWeight, GridHeaderSize, - DigitalGreenDark105, - DigitalGreenDark110 + DigitalGreenDark105 } from '@ni/nimble-tokens/dist/styledictionary/js/tokens'; import { modalBackdropColorThemeColorStatic, @@ -248,15 +247,6 @@ export const buttonPrimaryFontColor = DesignToken.create<string>( styleNameFromTokenName(tokenNames.buttonPrimaryFontColor) ).withDefault((element: HTMLElement) => getColorForTheme(element, Black15, Black15, White)); -export const buttonFillActivePrimaryColor = DesignToken.create<string>( - styleNameFromTokenName(tokenNames.buttonFillActivePrimaryColor) -).withDefault((element: HTMLElement) => getColorForTheme( - element, - hexToRgbaCssColor(Black91, 0.85), - hexToRgbaCssColor(Black15, 0.2), - hexToRgbaCssColor(White, 0.2) -)); - export const buttonFillAccentColor = DesignToken.create<string>( styleNameFromTokenName(tokenNames.buttonFillAccentColor) ).withDefault((element: HTMLElement) => getColorForTheme( @@ -283,15 +273,6 @@ export const buttonBorderAccentOutlineColor = DesignToken.create<string>( hexToRgbaCssColor(White, 0.3) )); -export const buttonFillAccentActiveColor = DesignToken.create<string>( - styleNameFromTokenName(tokenNames.buttonFillAccentActiveColor) -).withDefault((element: HTMLElement) => getColorForTheme( - element, - DigitalGreenDark110, - DigitalGreenDark, - hexToRgbaCssColor(White, 0.2) -)); - // Component Sizing Tokens export const controlHeight = DesignToken.create<string>( styleNameFromTokenName(tokenNames.controlHeight) @@ -560,8 +541,8 @@ export const [ tokenNames.linkActiveFont, (element: HTMLElement) => getColorForTheme( element, - DigitalGreenDark, - PowerGreen, + DigitalGreenLight, + DigitalGreenLight, hexToRgbaCssColor(White, 0.6) ), (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), @@ -583,7 +564,7 @@ export const [ linkProminentFallbackFontFamily ] = createFontTokens( tokenNames.linkProminentFont, - (element: HTMLElement) => getColorForTheme(element, DigitalGreenDark, PowerGreen, PowerGreen), + (element: HTMLElement) => getColorForTheme(element, DigitalGreenDark105, PowerGreen, PowerGreen), (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), LinkLightUiFamily, LinkLightUiWeight, @@ -603,7 +584,12 @@ export const [ linkActiveProminentFallbackFontFamily ] = createFontTokens( tokenNames.linkActiveProminentFont, - (element: HTMLElement) => getDefaultFontColorForTheme(element), + (element: HTMLElement) => getColorForTheme( + element, + DigitalGreenLight, + DigitalGreenLight, + PowerGreen + ), (element: HTMLElement) => hexToRgbaCssColor(getDefaultFontColorForTheme(element), 0.3), LinkLightUiFamily, LinkLightUiWeight, diff --git a/packages/nimble-components/src/toggle-button/index.ts b/packages/nimble-components/src/toggle-button/index.ts index dc876ed997..d1ae498136 100644 --- a/packages/nimble-components/src/toggle-button/index.ts +++ b/packages/nimble-components/src/toggle-button/index.ts @@ -10,7 +10,7 @@ import { import { styles } from './styles'; import { template } from './template'; import type { ButtonPattern } from '../patterns/button/types'; -import { ButtonAppearance } from './types'; +import { ButtonAppearance, ButtonAppearanceVariant } from './types'; declare global { interface HTMLElementTagNameMap { @@ -30,6 +30,14 @@ export class ToggleButton extends FoundationSwitch implements ButtonPattern { @attr public appearance: ButtonAppearance = ButtonAppearance.outline; + /** + * @public + * @remarks + * HTML Attribute: appearance-variant + */ + @attr({ attribute: 'appearance-variant' }) + public appearanceVariant: ButtonAppearanceVariant; + /** * @public * @remarks diff --git a/packages/nimble-components/src/toggle-button/styles.ts b/packages/nimble-components/src/toggle-button/styles.ts index ad1edbb3b8..090746dc19 100644 --- a/packages/nimble-components/src/toggle-button/styles.ts +++ b/packages/nimble-components/src/toggle-button/styles.ts @@ -1,70 +1,37 @@ import { css } from '@microsoft/fast-element'; -import { focusVisible } from '../utilities/style/focus'; import { - borderHoverColor, - borderWidth, + buttonAccentOutlineFontColor, + buttonLabelFontColor, fillSelectedColor, - fillSelectedRgbPartialColor + fillSelectedRgbPartialColor, + iconColor } from '../theme-provider/design-tokens'; -import { styles as buttonStyles } from '../patterns/button/styles'; +import { + buttonAppearanceVariantStyles, + styles as buttonStyles +} from '../patterns/button/styles'; +import { appearanceBehavior } from '../utilities/style/appearance'; +import { ButtonAppearance } from './types'; export const styles = css` ${buttonStyles} + ${buttonAppearanceVariantStyles} - @layer base { + @layer checked { .control[aria-pressed='true'] { background-color: transparent; + color: ${buttonLabelFontColor}; background-image: linear-gradient( ${fillSelectedColor}, ${fillSelectedColor} ); border-color: rgba(${fillSelectedRgbPartialColor}, 0.3); } - } - - @layer hover { - .control[aria-pressed='true']:hover { - border-color: ${borderHoverColor}; - box-shadow: 0px 0px 0px ${borderWidth} ${borderHoverColor} inset; - background-image: linear-gradient( - ${fillSelectedColor}, - ${fillSelectedColor} - ); - background-size: calc(100% - 4px) calc(100% - 4px); - } - } - - @layer focusVisible { - .control[aria-pressed='true']${focusVisible} { - border-color: ${borderHoverColor}; - box-shadow: 0px 0px 0px ${borderWidth} ${borderHoverColor} inset; - background-image: linear-gradient( - ${fillSelectedColor}, - ${fillSelectedColor} - ); - background-size: calc(100% - 4px) calc(100% - 4px); - } - - .control[aria-pressed='true']${focusVisible}::before { - outline: ${borderWidth} solid ${borderHoverColor}; - outline-offset: -3px; - color: transparent; - } - } - - @layer active { - .control[aria-pressed='true']:active { - box-shadow: none; - background-image: linear-gradient( - ${fillSelectedColor}, - ${fillSelectedColor} - ); - background-size: calc(100% - 2px) calc(100% - 2px); - } - .control[aria-pressed='true']:active::before { - outline: none; + .control[aria-pressed='true'] [part='start'], + .control[aria-pressed='true'] [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonLabelFontColor}; } } @@ -76,15 +43,26 @@ export const styles = css` ); border-color: rgba(${fillSelectedRgbPartialColor}, 0.3); } - - :host([disabled]) .control[aria-pressed='true']:hover { - background-image: linear-gradient( - ${fillSelectedColor}, - ${fillSelectedColor} - ); - background-size: 100% 100%; - border-color: rgba(${fillSelectedRgbPartialColor}, 0.3); - box-shadow: none; - } } -`; +`.withBehaviors( + appearanceBehavior( + ButtonAppearance.outline, + css` + @layer checked { + :host([appearance-variant='accent']) + .control[aria-pressed='true'] { + color: ${buttonAccentOutlineFontColor}; + } + + :host([appearance-variant='accent']) + .control[aria-pressed='true'] + [part='start'], + :host([appearance-variant='accent']) + .control[aria-pressed='true'] + [part='end'] { + ${iconColor.cssCustomProperty}: ${buttonAccentOutlineFontColor}; + } + } + ` + ) +); diff --git a/packages/nimble-components/src/toggle-button/tests/toggle-button-matrix.stories.ts b/packages/nimble-components/src/toggle-button/tests/toggle-button-matrix.stories.ts index a2772921b3..7e6fc7e002 100644 --- a/packages/nimble-components/src/toggle-button/tests/toggle-button-matrix.stories.ts +++ b/packages/nimble-components/src/toggle-button/tests/toggle-button-matrix.stories.ts @@ -1,7 +1,5 @@ import type { StoryFn, Meta } from '@storybook/html'; import { html, ViewTemplate, when } from '@microsoft/fast-element'; -import { pascalCase } from '@microsoft/fast-web-utilities'; -import { ButtonAppearance } from '../types'; import { createMatrix, sharedMatrixParameters, @@ -14,6 +12,14 @@ import { textCustomizationWrapper } from '../../utilities/tests/text-customizati import { toggleButtonTag } from '..'; import { iconArrowExpanderDownTag } from '../../icons/arrow-expander-down'; import { iconKeyTag } from '../../icons/key'; +import { + appearanceStates, + type AppearanceState, + type AppearanceVariantState, + type PartVisibilityState, + appearanceVariantStates, + partVisibilityStates +} from '../../patterns/button/tests/states'; const metadata: Meta = { title: 'Tests/Toggle Button', @@ -24,21 +30,6 @@ const metadata: Meta = { export default metadata; -/* array of iconVisible, labelVisible, endIconVisible */ -const partVisibilityStates = [ - [true, true, false], - [true, false, false], - [false, true, false], - [true, true, true], - [false, true, true] -] as const; -type PartVisibilityState = (typeof partVisibilityStates)[number]; - -const appearanceStates: [string, string | undefined][] = Object.entries( - ButtonAppearance -).map(([key, value]) => [pascalCase(key), value]); -type AppearanceState = (typeof appearanceStates)[number]; - const checkedStates = [ ['Checked', true], ['Unchecked', false] @@ -50,16 +41,18 @@ const component = ( [iconVisible, labelVisible, endIconVisible]: PartVisibilityState, [checkedName, checked]: CheckedState, [disabledName, disabled]: DisabledState, - [appearanceName, appearance]: AppearanceState + [appearanceName, appearance]: AppearanceState, + [appearanceVariantName, appearanceVariant]: AppearanceVariantState ): ViewTemplate => html` <${toggleButtonTag} appearance="${() => appearance}" + appearance-variant="${() => appearanceVariant}" ?disabled=${() => disabled} ?content-hidden=${() => !labelVisible} ?checked=${() => checked} style="margin-right: 8px; margin-bottom: 8px;"> ${when(() => iconVisible, html`<${iconKeyTag} slot="start"></${iconKeyTag}>`)} - ${() => `${checkedName} ${appearanceName} Toggle Button ${disabledName}`} + ${() => `${checkedName} ${appearanceVariantName} ${appearanceName} Toggle Button ${disabledName}`} ${when(() => endIconVisible, html`<${iconArrowExpanderDownTag} slot="end"></${iconArrowExpanderDownTag}>`)} </${toggleButtonTag}> `; @@ -69,7 +62,8 @@ export const toggleButtonThemeMatrix: StoryFn = createMatrixThemeStory( partVisibilityStates, checkedStates, disabledStates, - appearanceStates + appearanceStates, + appearanceVariantStates ]) ); diff --git a/packages/nimble-components/src/toggle-button/tests/toggle-button.mdx b/packages/nimble-components/src/toggle-button/tests/toggle-button.mdx index cc2ba73349..1c505a644b 100644 --- a/packages/nimble-components/src/toggle-button/tests/toggle-button.mdx +++ b/packages/nimble-components/src/toggle-button/tests/toggle-button.mdx @@ -1,5 +1,7 @@ import { Controls, Canvas, Meta, Title } from '@storybook/blocks'; import ContentHiddenDocs from '../../patterns/button/tests/content-hidden-docs.mdx'; +import StylingDocs from '../../patterns/button/tests/styling-docs.mdx'; +import { toggleButtonTag } from '..'; import * as toggleButtonStories from './toggle-button.stories'; <Meta of={toggleButtonStories} /> @@ -14,9 +16,7 @@ screen reader would say something like "Mute toggle button pressed". <Canvas of={toggleButtonStories.outlineButton} /> <Controls of={toggleButtonStories.outlineButton} /> -{/* ## Appearances */} - -{/* ## Appearance Variants */} +<StylingDocs components={{ Button: toggleButtonTag }} /> {/* ## Usage */} diff --git a/packages/nimble-components/src/toggle-button/tests/toggle-button.stories.ts b/packages/nimble-components/src/toggle-button/tests/toggle-button.stories.ts index 960d0cfad1..6e3be5500e 100644 --- a/packages/nimble-components/src/toggle-button/tests/toggle-button.stories.ts +++ b/packages/nimble-components/src/toggle-button/tests/toggle-button.stories.ts @@ -2,8 +2,10 @@ import { html, when } from '@microsoft/fast-element'; import { withActions } from '@storybook/addon-actions/decorator'; import type { HtmlRenderer, Meta, StoryObj } from '@storybook/html'; import { createUserSelectedThemeStory } from '../../utilities/tests/storybook'; -import { ButtonAppearance } from '../types'; +import { ButtonAppearance, ButtonAppearanceVariant } from '../types'; import { + appearanceDescription, + appearanceVariantDescription, contentHiddenDescription, endIconDescription, iconDescription @@ -14,7 +16,8 @@ import { iconKeyTag } from '../../icons/key'; interface ToggleButtonArgs { label: string; - appearance: string; + appearance: keyof typeof ButtonAppearance; + appearanceVariant: keyof typeof ButtonAppearanceVariant; checked: boolean; disabled: boolean; icon: boolean; @@ -33,7 +36,14 @@ const metadata: Meta<ToggleButtonArgs> = { argTypes: { appearance: { options: Object.values(ButtonAppearance), - control: { type: 'radio' } + control: { type: 'radio' }, + description: appearanceDescription + }, + appearanceVariant: { + name: 'appearance-variant', + options: Object.keys(ButtonAppearanceVariant), + control: { type: 'radio' }, + description: appearanceVariantDescription }, contentHidden: { description: contentHiddenDescription @@ -51,7 +61,8 @@ const metadata: Meta<ToggleButtonArgs> = { ?checked="${x => x.checked}" ?disabled="${x => x.disabled}" ?content-hidden="${x => x.contentHidden}" - appearance="${x => x.appearance}" + appearance="${x => ButtonAppearance[x.appearance]}" + appearance-variant="${x => ButtonAppearanceVariant[x.appearanceVariant]}" > ${when(x => x.icon, html`<${iconKeyTag} slot="start"></${iconKeyTag}>`)} ${x => x.label} @@ -59,8 +70,9 @@ const metadata: Meta<ToggleButtonArgs> = { </${toggleButtonTag}> `), args: { - label: 'Ghost Toggle Button', - appearance: 'ghost', + label: 'Toggle Button', + appearance: 'outline', + appearanceVariant: 'default', checked: true, icon: false, endIcon: false, diff --git a/packages/nimble-components/src/toggle-button/types.ts b/packages/nimble-components/src/toggle-button/types.ts index eaf843c952..f38e4ea704 100644 --- a/packages/nimble-components/src/toggle-button/types.ts +++ b/packages/nimble-components/src/toggle-button/types.ts @@ -2,4 +2,7 @@ * Types of toggle button appearance. * @public */ -export { ButtonAppearance } from '../patterns/button/types'; +export { + ButtonAppearance, + ButtonAppearanceVariant +} from '../patterns/button/types'; diff --git a/packages/nimble-tokens/source/styledictionary/properties/colors.json b/packages/nimble-tokens/source/styledictionary/properties/colors.json index 812df2c5ad..245808c7d9 100644 --- a/packages/nimble-tokens/source/styledictionary/properties/colors.json +++ b/packages/nimble-tokens/source/styledictionary/properties/colors.json @@ -91,7 +91,7 @@ "value": "#AEB0B3ff" }, "DigitalGreenDark": { - "value": "#006B46ff" + "value": "#008557ff" }, "DigitalGreenDark105": { "value": "#00734Bff" From e7f9887fbe87b85026c30ca767b96f314074b51e Mon Sep 17 00:00:00 2001 From: rajsite <rajsite@users.noreply.github.com> Date: Tue, 26 Mar 2024 20:45:41 +0000 Subject: [PATCH 18/18] applying package updates [skip ci] --- .../projects/ni/nimble-angular/CHANGELOG.json | 15 +++++++++++++ .../projects/ni/nimble-angular/CHANGELOG.md | 10 ++++++++- .../projects/ni/nimble-angular/package.json | 4 ++-- ...-083cf44c-68b4-43f6-b689-efd81c8228b4.json | 7 ------- ...-12958de0-2edc-4e06-a0ff-61431c96010a.json | 7 ------- package-lock.json | 12 +++++------ packages/nimble-blazor/package.json | 2 +- packages/nimble-components/CHANGELOG.json | 21 +++++++++++++++++++ packages/nimble-components/CHANGELOG.md | 11 +++++++++- packages/nimble-components/package.json | 4 ++-- packages/nimble-tokens/CHANGELOG.json | 15 +++++++++++++ packages/nimble-tokens/CHANGELOG.md | 10 ++++++++- packages/nimble-tokens/package.json | 2 +- 13 files changed, 91 insertions(+), 29 deletions(-) delete mode 100644 change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json delete mode 100644 change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json index 43e44a26b9..b9e3854a33 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-angular", "entries": [ + { + "date": "Tue, 26 Mar 2024 20:45:41 GMT", + "version": "20.5.4", + "tag": "@ni/nimble-angular_v20.5.4", + "comments": { + "patch": [ + { + "author": "beachball", + "package": "@ni/nimble-angular", + "comment": "Bump @ni/nimble-components to v24.0.0", + "commit": "not available" + } + ] + } + }, { "date": "Mon, 25 Mar 2024 17:03:11 GMT", "version": "20.5.3", diff --git a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md index 9f66bd06eb..48ee1ccd3b 100644 --- a/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md +++ b/angular-workspace/projects/ni/nimble-angular/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-angular -This log was last generated on Mon, 25 Mar 2024 17:03:11 GMT and should not be manually modified. +This log was last generated on Tue, 26 Mar 2024 20:45:41 GMT and should not be manually modified. <!-- Start content --> +## 20.5.4 + +Tue, 26 Mar 2024 20:45:41 GMT + +### Patches + +- Bump @ni/nimble-components to v24.0.0 + ## 20.5.3 Mon, 25 Mar 2024 17:03:11 GMT diff --git a/angular-workspace/projects/ni/nimble-angular/package.json b/angular-workspace/projects/ni/nimble-angular/package.json index d98a826070..d91a8cef19 100644 --- a/angular-workspace/projects/ni/nimble-angular/package.json +++ b/angular-workspace/projects/ni/nimble-angular/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-angular", - "version": "20.5.3", + "version": "20.5.4", "description": "Angular components for the NI Nimble Design System", "scripts": { "invoke-publish": "cd ../../../ && npm run build:library && cd dist/ni/nimble-angular && npm publish" @@ -31,7 +31,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^23.0.1" + "@ni/nimble-components": "^24.0.0" }, "dependencies": { "tslib": "^2.2.0" diff --git a/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json b/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json deleted file mode 100644 index f20c5cd2f2..0000000000 --- a/change/@ni-nimble-components-083cf44c-68b4-43f6-b689-efd81c8228b4.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "major", - "comment": "Support primary and accent variants for toggle and menu buttons. BREAKING CHANGE: Removed theme-aware tokens `buttonFillActivePrimaryColor` and `buttonFillAccentActiveColor`. Use `fillSelectedColor` instead.", - "packageName": "@ni/nimble-components", - "email": "7282195+m-akinc@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json b/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json deleted file mode 100644 index cfca0025d2..0000000000 --- a/change/@ni-nimble-tokens-12958de0-2edc-4e06-a0ff-61431c96010a.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "patch", - "comment": "Fix value of DigitalGreenDark", - "packageName": "@ni/nimble-tokens", - "email": "7282195+m-akinc@users.noreply.github.com", - "dependentChangeType": "patch" -} diff --git a/package-lock.json b/package-lock.json index 3767bc84bf..1f10fb0a25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ }, "angular-workspace/projects/ni/nimble-angular": { "name": "@ni/nimble-angular", - "version": "20.5.3", + "version": "20.5.4", "license": "MIT", "dependencies": { "tslib": "^2.2.0" @@ -85,7 +85,7 @@ "@angular/forms": "^15.2.10", "@angular/localize": "^15.2.10", "@angular/router": "^15.2.10", - "@ni/nimble-components": "^23.0.1" + "@ni/nimble-components": "^24.0.0" } }, "node_modules/@11ty/dependency-tree": { @@ -33940,7 +33940,7 @@ }, "packages/nimble-blazor": { "name": "@ni/nimble-blazor", - "version": "14.5.3", + "version": "14.5.4", "hasInstallScript": true, "license": "MIT", "devDependencies": { @@ -33976,14 +33976,14 @@ }, "packages/nimble-components": { "name": "@ni/nimble-components", - "version": "23.0.1", + "version": "24.0.0", "license": "MIT", "dependencies": { "@microsoft/fast-colors": "^5.3.1", "@microsoft/fast-element": "^1.12.0", "@microsoft/fast-foundation": "2.49.4", "@microsoft/fast-web-utilities": "^6.0.0", - "@ni/nimble-tokens": "^6.13.0", + "@ni/nimble-tokens": "^6.13.1", "@tanstack/table-core": "^8.10.7", "@tanstack/virtual-core": "^3.0.0-beta.68", "@tiptap/core": "^2.2.2", @@ -34975,7 +34975,7 @@ }, "packages/nimble-tokens": { "name": "@ni/nimble-tokens", - "version": "6.13.0", + "version": "6.13.1", "license": "MIT", "devDependencies": { "@microsoft/fast-colors": "^5.3.1", diff --git a/packages/nimble-blazor/package.json b/packages/nimble-blazor/package.json index fc97e5c96e..600b5504f1 100644 --- a/packages/nimble-blazor/package.json +++ b/packages/nimble-blazor/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-blazor", - "version": "14.5.3", + "version": "14.5.4", "description": "Blazor components for the NI Nimble Design System", "scripts": { "postinstall": "node build/generate-playwright-version-properties/source/index.js", diff --git a/packages/nimble-components/CHANGELOG.json b/packages/nimble-components/CHANGELOG.json index f72608c8e3..77cd4aa225 100644 --- a/packages/nimble-components/CHANGELOG.json +++ b/packages/nimble-components/CHANGELOG.json @@ -1,6 +1,27 @@ { "name": "@ni/nimble-components", "entries": [ + { + "date": "Tue, 26 Mar 2024 20:45:41 GMT", + "version": "24.0.0", + "tag": "@ni/nimble-components_v24.0.0", + "comments": { + "major": [ + { + "author": "7282195+m-akinc@users.noreply.github.com", + "package": "@ni/nimble-components", + "commit": "594ac221124cc1b52cd28113714bb8ff71e5820b", + "comment": "Support primary and accent variants for toggle and menu buttons. BREAKING CHANGE: Removed theme-aware tokens `buttonFillActivePrimaryColor` and `buttonFillAccentActiveColor`. Use `fillSelectedColor` instead." + }, + { + "author": "beachball", + "package": "@ni/nimble-components", + "comment": "Bump @ni/nimble-tokens to v6.13.1", + "commit": "not available" + } + ] + } + }, { "date": "Mon, 25 Mar 2024 17:03:11 GMT", "version": "23.0.1", diff --git a/packages/nimble-components/CHANGELOG.md b/packages/nimble-components/CHANGELOG.md index 4b8e71ac3a..ab617d9fbd 100644 --- a/packages/nimble-components/CHANGELOG.md +++ b/packages/nimble-components/CHANGELOG.md @@ -1,9 +1,18 @@ # Change Log - @ni/nimble-components -This log was last generated on Mon, 25 Mar 2024 17:03:11 GMT and should not be manually modified. +This log was last generated on Tue, 26 Mar 2024 20:45:41 GMT and should not be manually modified. <!-- Start content --> +## 24.0.0 + +Tue, 26 Mar 2024 20:45:41 GMT + +### Major changes + +- Support primary and accent variants for toggle and menu buttons. BREAKING CHANGE: Removed theme-aware tokens `buttonFillActivePrimaryColor` and `buttonFillAccentActiveColor`. Use `fillSelectedColor` instead. ([ni/nimble@594ac22](https://github.com/ni/nimble/commit/594ac221124cc1b52cd28113714bb8ff71e5820b)) +- Bump @ni/nimble-tokens to v6.13.1 + ## 23.0.1 Mon, 25 Mar 2024 17:03:11 GMT diff --git a/packages/nimble-components/package.json b/packages/nimble-components/package.json index 171e0ee8b9..e5f92fa550 100644 --- a/packages/nimble-components/package.json +++ b/packages/nimble-components/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-components", - "version": "23.0.1", + "version": "24.0.0", "description": "Styled web components for the NI Nimble Design System", "scripts": { "build": "npm run generate-icons && npm run generate-workers && npm run build-components && npm run bundle-components && npm run generate-scss && npm run build-storybook", @@ -68,7 +68,7 @@ "@microsoft/fast-element": "^1.12.0", "@microsoft/fast-foundation": "2.49.4", "@microsoft/fast-web-utilities": "^6.0.0", - "@ni/nimble-tokens": "^6.13.0", + "@ni/nimble-tokens": "^6.13.1", "@tanstack/table-core": "^8.10.7", "@tanstack/virtual-core": "^3.0.0-beta.68", "@tiptap/core": "^2.2.2", diff --git a/packages/nimble-tokens/CHANGELOG.json b/packages/nimble-tokens/CHANGELOG.json index 089330fec9..040f937e44 100644 --- a/packages/nimble-tokens/CHANGELOG.json +++ b/packages/nimble-tokens/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@ni/nimble-tokens", "entries": [ + { + "date": "Tue, 26 Mar 2024 20:45:41 GMT", + "version": "6.13.1", + "tag": "@ni/nimble-tokens_v6.13.1", + "comments": { + "patch": [ + { + "author": "7282195+m-akinc@users.noreply.github.com", + "package": "@ni/nimble-tokens", + "commit": "594ac221124cc1b52cd28113714bb8ff71e5820b", + "comment": "Fix value of DigitalGreenDark" + } + ] + } + }, { "date": "Thu, 21 Mar 2024 17:13:38 GMT", "version": "6.13.0", diff --git a/packages/nimble-tokens/CHANGELOG.md b/packages/nimble-tokens/CHANGELOG.md index def2a83a56..3eb9526e4c 100644 --- a/packages/nimble-tokens/CHANGELOG.md +++ b/packages/nimble-tokens/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @ni/nimble-tokens -This log was last generated on Thu, 21 Mar 2024 17:13:38 GMT and should not be manually modified. +This log was last generated on Tue, 26 Mar 2024 20:45:41 GMT and should not be manually modified. <!-- Start content --> +## 6.13.1 + +Tue, 26 Mar 2024 20:45:41 GMT + +### Patches + +- Fix value of DigitalGreenDark ([ni/nimble@594ac22](https://github.com/ni/nimble/commit/594ac221124cc1b52cd28113714bb8ff71e5820b)) + ## 6.13.0 Thu, 21 Mar 2024 17:13:38 GMT diff --git a/packages/nimble-tokens/package.json b/packages/nimble-tokens/package.json index afefbfb147..04efb09bb2 100644 --- a/packages/nimble-tokens/package.json +++ b/packages/nimble-tokens/package.json @@ -1,6 +1,6 @@ { "name": "@ni/nimble-tokens", - "version": "6.13.0", + "version": "6.13.1", "description": "Design tokens for the NI Nimble Design System", "scripts": { "build": "npm run build:svg-to-ts && npm run build:ts && npm run build:svg-to-ico && npm run build:generate-font-scss && npm run build:style-dictionary",