Skip to content

Commit

Permalink
Add spright packages
Browse files Browse the repository at this point in the history
  • Loading branch information
m-akinc committed Mar 1, 2024
1 parent 2abc445 commit 9f68e0a
Show file tree
Hide file tree
Showing 147 changed files with 4,184 additions and 5 deletions.
18 changes: 16 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ jobs:
with:
path: 'packages/site/dist'

# Publish to Chromatic (from any push)
- name: Publish to Chromatic
# Publish to Chromatic (from any push) - Nimble
- name: Publish to Chromatic (Nimble)
if: env.HAS_CHROMATIC_PROJECT_TOKEN == 'true' && github.event_name == 'push'
uses: chromaui/action@v1
with:
Expand All @@ -103,6 +103,20 @@ jobs:
exitOnceUploaded: true # Do not wait for test results
exitZeroOnChanges: true # Option to prevent the workflow from failing

# Publish to Chromatic (from any push) - Spright
- name: Publish to Chromatic (Spright)
if: env.HAS_CHROMATIC_PROJECT_TOKEN == 'true' && github.event_name == 'push'
uses: chromaui/action@v1
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
onlyChanged: "!startsWith(github.ref, 'refs/heads/main')" # Use TurboSnap for PR builds
workingDir: ./packages/spright-components
externals: |
- '.storybook/public/**'
storybookBuildDir: ../../packages/site/dist/storybook
exitOnceUploaded: true # Do not wait for test results
exitZeroOnChanges: true # Option to prevent the workflow from failing

# Lint
- run: npm run lint

Expand Down
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,19 @@ Some ways to make progress on an intermittent test tech debt issue are:

1. In a branch a developer can try and re-enable the test and reproduce the failure by including additional logging, etc. Creating a PR is not necessary to queue a build in nimble; every commit has an associated build and will re-run the tests.
2. If the failure is too intermittent to detect by manually queuing builds in a branch and needs additional logging and executions in main, then modify the test so that it will not fail the test suite and add the additional logging needed to make it run in main. Actively monitor the change and have a pre-defined date to disable the test and re-evaluate how to handle the issue.

## Contributing to Spright

The Spright packages, while part of the Nimble monorepo, have some differing contribution policies.

### Code ownership

Spright packages generally follow the inner source model. The Nimble team owns shared code and configuration, but the components, their tests, and their documentation are owned by the teams that created them. Bug fixes and new features should be contributed by the team that needs them.

### Code quality

Code should adhere to NI and Nimble standards for quality and test coverage. Spright components may choose to compromise on Nimble standards for aspects like visual design or API breadth, but should always have a level of quality suitable for use in production applications.

### Documentation

Storybook documentation for components should include a **Usage Guidance** section that explains what the component should and should not be used for. This could include information about feature gaps, guidance about when to use the component rather than a comparable Nimble component, and context about why the component is in Spright rather than Nimble.
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
[![Nimble Blazor Nuget version and repo link](https://img.shields.io/nuget/v/NimbleBlazor.svg?label=NimbleBlazor)](https://www.nuget.org/packages/NimbleBlazor)
[![Nimble Components NPM version and repo link](https://img.shields.io/npm/v/@ni/nimble-components.svg?label=@ni/nimble-components)](https://www.npmjs.com/package/@ni/nimble-components)
[![Nimble Tokens NPM version and repo link](https://img.shields.io/npm/v/@ni/nimble-tokens.svg?label=@ni/nimble-tokens)](https://www.npmjs.com/package/@ni/nimble-tokens)
[![Spright Angular NPM version and repo link](https://img.shields.io/npm/v/@ni/spright-angular.svg?label=@ni/spright-angular)](https://www.npmjs.com/package/@ni/spright-angular)
[![Spright Blazor Nuget version and repo link](https://img.shields.io/nuget/v/SprightBlazor.svg?label=SprightBlazor)](https://www.nuget.org/packages/SprightBlazor)
[![Spright Components NPM version and repo link](https://img.shields.io/npm/v/@ni/spright-components.svg?label=@ni/spright-components)](https://www.npmjs.com/package/@ni/spright-components)

The NI Nimble Design System: styled UI components for NI applications.

Expand All @@ -26,6 +29,9 @@ This repository contains the source for the following packages:
- **[`@ni/nimble-blazor`](/packages/nimble-blazor/)** - styled Blazor components for use in NI Blazor applications
- **[`@ni/nimble-components`](/packages/nimble-components/)** - styled web components for use in other applications (also used by `nimble-angular` and `nimble-blazor`)
- **[`@ni/nimble-tokens`](/packages/nimble-tokens/)** - design tokens used by the component packages
- **[`@ni/spright-angular`](/angular-workspace/projects/ni/spright-angular/)** - experimental, composite, or product-specific, styled Angular components for use in NI Angular applications
- **[`@ni/spright-blazor`](/packages/spright-blazor/)** - experimental, composite, or product-specific, styled Blazor components for use in NI Blazor applications
- **[`@ni/spright-components`](/packages/spright-components/)** - experimental, composite, or product-specific, styled web components for use in other applications (also used by `spright-angular` and `spright-blazor`)

And some additional utility packages:
- [`@ni/jasmine-parameterized`](/packages/jasmine-parameterized/) - a utility for writing [Jasmine](https://jasmine.github.io/) parameterized tests
Expand Down Expand Up @@ -59,4 +65,25 @@ See `Getting Started` in [`Contributing.md`](/CONTRIBUTING.md#getting-started) t

## Component Status

View status of components that are completed and on the roadmap in the [Component Status](https://ni.github.io/nimble/storybook/?path=/docs/component-status--docs) page.
View status of components that are completed and on the roadmap in the [Component Status](https://ni.github.io/nimble/storybook/?path=/docs/component-status--docs) page.

## Spright

`spright-components`, `spright-angular`, and `SprightBlazor` are counterparts of the Nimble packages for components that do not belong in the Nimble Design System.

### What are the different types of Spright components?

Examples include:
1. "Molecule" components which combine Nimble "atom" components. For example, a group of card buttons with a specific layout.
2. Product-specific components. For example, a configuration pane that uses product-specific terminology or connects to a product-specific data model.
3. Data-connected components. For example, a table that populates itself by making HTTP requests to a specific service.
4. Experimental components that are trying out new UX patterns to see if they should someday be promoted to Nimble.

### Why Spright?

"Spright" is an archaic variant of "sprite" that is the root of "sprightly"; think of it as a rapidly moving peer of Nimble.

This concept is inspired by the "recipes" concept in [Design System Pace Layers](https://bigmedium.com/ideas/design-system-pace-layers-slow-fast.html). The goals are:

1. Keep Nimble's core components at a high level of quality and reusability.
2. Allow innovative new contributions to follow Nimble's architecture, leverage its infrastructure, and start on a path to being part of Nimble without being unnecessarily slowed by the rigorous process needed to achieve the first goal.
41 changes: 41 additions & 0 deletions angular-workspace/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,47 @@
}
}
},
"@ni/spright-angular": {
"projectType": "library",
"root": "projects/ni/spright-angular",
"sourceRoot": "projects/ni/spright-angular",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
"options": {
"project": "projects/ni/spright-angular/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "projects/ni/spright-angular/tsconfig.lib.prod.json"
},
"development": {
"tsConfig": "projects/ni/spright-angular/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/ni/spright-angular/test.ts",
"tsConfig": "projects/ni/spright-angular/tsconfig.spec.json",
"karmaConfig": "projects/ni/spright-angular/karma.conf.js"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"projects/ni/spright-angular/**/*.ts",
"projects/ni/spright-angular/**/*.js",
"projects/ni/spright-angular/**/*.html"
]
}
}
}
},
"example-client-app": {
"projectType": "application",
"schematics": {
Expand Down
8 changes: 6 additions & 2 deletions angular-workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "npm run build:library && npm run build:application",
"build": "npm run build:library && npm run build:spright && npm run build:application",
"build:library": "npm run generate-icons && ng build @ni/nimble-angular",
"watch:library": "npm run generate-icons && ng build @ni/nimble-angular --watch",
"build:spright": "ng build @ni/spright-angular",
"watch:spright": "ng build @ni/spright-angular --watch",
"build:application": "ng build example-client-app",
"generate-icons": "npm run generate-icons:bundle && npm run generate-icons:run",
"generate-icons:bundle": "rollup --bundleConfigAsCjs --config projects/ni/nimble-angular/build/generate-icons/rollup.config.js",
"generate-icons:run": "node projects/ni/nimble-angular/build/generate-icons/dist/index.js",
"pack": "npm run pack:library && npm run pack:application",
"pack": "npm run pack:library && npm run pack:spright && npm run pack:application",
"pack:library": "cd dist/ni/nimble-angular && npm pack",
"pack:spright": "cd dist/ni/spright-angular && npm pack",
"pack:application": "cd dist/example-client-app && npm pack",
"performance": "lhci autorun",
"watch": "ng build --watch --configuration development",
Expand All @@ -31,6 +34,7 @@
"@angular/platform-browser-dynamic": "^15.2.10",
"@angular/router": "^15.2.10",
"@ni/nimble-components": "*",
"@ni/spright-components": "*",
"rxjs": "^7.3.0",
"tslib": "^2.2.0",
"zone.js": "^0.11.4"
Expand Down
15 changes: 15 additions & 0 deletions angular-workspace/projects/ni/spright-angular/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
extends: '../../../.eslintrc.js',
overrides: [
{
files: ['*.ts'],
parserOptions: {
project: [
'./tsconfig.lib.json',
'./tsconfig.spec.json'
],
tsconfigRootDir: __dirname
}
}
]
};
3 changes: 3 additions & 0 deletions angular-workspace/projects/ni/spright-angular/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Contributing to Spright Angular

Contributions should follow the same [guidelines](../nimble-angular/CONTRIBUTING.md) as the Nimble Angular project.
13 changes: 13 additions & 0 deletions angular-workspace/projects/ni/spright-angular/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div align="center">
<p><b>ni | spright | angular</b></p>
</div>

# Spright Angular

[![NPM Version](https://img.shields.io/npm/v/@ni/spright-angular.svg)](https://www.npmjs.com/package/@ni/spright-angular)

Spright components for [Angular](https://angular.io) applications

## Contributing

Follow the instructions in [CONTRIBUTING.md](CONTRIBUTING.md) to modify this library.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public-api.ts"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './spright-accordion.directive';
export * from './spright-accordion.module';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Directive } from '@angular/core';
import { type Accordion, accordionTag } from '@ni/spright-components/dist/esm/accordion';

export type { Accordion };
export { accordionTag };

/**
* Directive to provide Angular integration for the accordion.
*/
@Directive({
selector: 'spright-accordion'
})
export class SprightAccordionDirective { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SprightAccordionDirective } from './spright-accordion.directive';

import '@ni/spright-components/dist/esm/accordion';

@NgModule({
declarations: [SprightAccordionDirective],
imports: [CommonModule],
exports: [SprightAccordionDirective]
})
export class SprightAccordionModule { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { SprightAccordionModule } from '../spright-accordion.module';

describe('Spright accordion', () => {
describe('module', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [SprightAccordionModule]
});
});

it('custom element is defined', () => {
expect(customElements.get('spright-accordion')).not.toBeUndefined();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "../../../../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public-api.ts"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './template-value-helpers';
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Conversion helpers for values coming from template attributes or property bindings
*/

// Values assigned to directives can come from template attributes, ie <my-element my-number="4"></my-element>
// or from property bindings, ie <my-element [my-number]="someNumber"></my-element>
// So setters for our directives accept both string values from template attributes and
// the expected property type. This file has helpers for common property types.
// More context: https://v13.angular.io/guide/template-typecheck#input-setter-coercion

type BooleanAttribute = '' | null;
export type BooleanValueOrAttribute = boolean | BooleanAttribute;
export type NumberValueOrAttribute = number | string;

/**
* Converts values from templates (empty string or null) or boolean bindings to a boolean property representation
*/
export const toBooleanProperty = (value: BooleanValueOrAttribute): boolean => {
if (value === false || value === null) {
return false;
}
// For boolean attributes the empty string value is true
return true;
};

/**
* Converts values from templates (empty string or null) or boolean bindings to an Aria boolean
* attribute representation (the strings "true" or "false")
*/
export const toBooleanAriaAttribute = (value: BooleanValueOrAttribute): 'true' | 'false' => {
if (value === false || value === null) {
return 'false';
}
// For boolean attributes the empty string value is true
return 'true';
};

/**
* Converts values from templates (number representation as a string) or number bindings to a number property representation
*/
export const toNumberProperty = (value: NumberValueOrAttribute): number => {
// Angular: https://github.com/angular/angular/blob/2664bc2b3ef4ee5fd671f915828cfcc274a36c77/packages/forms/src/directives/number_value_accessor.ts#L67
// And Fast: https://github.com/microsoft/fast/blob/46bb6d9aab2c37105f4434db3795e176c2354a4f/packages/web-components/fast-element/src/components/attributes.ts#L100
// Handle numeric conversions from the view differently
// Since Number(val) https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number-constructor-number-value
// and val * 1 https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-applystringornumericbinaryoperator
// Are identical (use ToNumeric algorithm), went with Number() for clarity
return Number(value);
};

/**
* Converts values from templates (number representation as a string) or number bindings to a number property representation.
* The values of `null` and `undefined` are also supported, and they are not converted.
*/
export const toNullableNumberProperty = (value: NumberValueOrAttribute | null | undefined): number | null | undefined => {
if (value === undefined || value === null) {
return value;
}

return toNumberProperty(value);
};
53 changes: 53 additions & 0 deletions angular-workspace/projects/ni/spright-angular/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html

process.env.CHROME_BIN = require('playwright').chromium.executablePath();

Check failure on line 4 in angular-workspace/projects/ni/spright-angular/karma.conf.js

View workflow job for this annotation

GitHub Actions / build

'playwright' should be listed in the project's dependencies. Run 'npm i -S playwright' to add it
const karmaJasmine = require('karma-jasmine');

Check failure on line 5 in angular-workspace/projects/ni/spright-angular/karma.conf.js

View workflow job for this annotation

GitHub Actions / build

'karma-jasmine' should be listed in the project's dependencies. Run 'npm i -S karma-jasmine' to add it
const karmaChromeLauncher = require('karma-chrome-launcher');

Check failure on line 6 in angular-workspace/projects/ni/spright-angular/karma.conf.js

View workflow job for this annotation

GitHub Actions / build

'karma-chrome-launcher' should be listed in the project's dependencies. Run 'npm i -S karma-chrome-launcher' to add it
const karmaJasmineHtmlReporter = require('karma-jasmine-html-reporter');
const karmaCoverage = require('karma-coverage');
const karmaAngular = require('@angular-devkit/build-angular/plugins/karma');
const path = require('path');

module.exports = config => {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
karmaJasmine,
karmaChromeLauncher,
karmaJasmineHtmlReporter,
karmaCoverage,
karmaAngular
],
client: {
jasmine: {
// you can add configuration options for Jasmine here
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
// for example, you can disable the random execution with `random: false`
// or set a specific seed with `seed: 4321`
stopSpecOnExpectationFailure: false
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
jasmineHtmlReporter: {
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
dir: path.join(__dirname, '../../../coverage/ni/spright-angular-core'),
subdir: '.',
reporters: [
{ type: 'html' },
{ type: 'text-summary' }
]
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['ChromeHeadless'],
singleRun: false,
restartOnFileChange: true
});
};
Loading

0 comments on commit 9f68e0a

Please sign in to comment.