;\n }> {\n const fixture = TestBed.createComponent(DemoComponent);\n const loader = TestbedHarnessEnvironment.loader(fixture);\n\n const lookupHarness = await (\n await loader.getHarness(\n SkyInputBoxHarness.with({ dataSkyId: 'favorite-names-field' }),\n )\n ).queryHarness(SkyLookupHarness);\n\n return { lookupHarness, fixture };\n }\n\n beforeEach(() => {\n // Create a mock search service. In a real-world application, the search\n // service would make a web request which should be avoided in unit tests.\n mockSvc = jasmine.createSpyObj('DemoService', ['search']);\n\n TestBed.configureTestingModule({\n imports: [DemoComponent, NoopAnimationsModule],\n providers: [\n {\n provide: DemoService,\n useValue: mockSvc,\n },\n ],\n });\n });\n\n it('should set the expected initial value', async () => {\n const { lookupHarness } = await setupTest();\n\n await expectAsync(lookupHarness?.getSelectionsText()).toBeResolvedTo([\n 'Shirley',\n ]);\n });\n\n it('should update the form control when a favorite name is selected', async () => {\n const { lookupHarness, fixture } = await setupTest();\n\n mockSvc.search.and.callFake((searchText) =>\n of({\n hasMore: false,\n people:\n searchText === 'b'\n ? [\n {\n id: '21',\n name: 'Bernard',\n },\n ]\n : [],\n totalCount: 1,\n }),\n );\n\n await lookupHarness?.enterText('b');\n await lookupHarness?.selectSearchResult({\n text: 'Bernard',\n });\n\n expect(fixture.componentInstance.favoritesForm.value.favoriteNames).toEqual(\n [\n { id: '16', name: 'Shirley' },\n { id: '21', name: 'Bernard' },\n ],\n );\n });\n\n it('should respect the selection descriptor', async () => {\n const { lookupHarness } = await setupTest();\n\n mockSvc.search.and.callFake(() =>\n of({\n hasMore: false,\n people: [\n {\n id: '21',\n name: 'Bernard',\n },\n ],\n totalCount: 1,\n }),\n );\n\n await lookupHarness?.clickShowMoreButton();\n\n const picker = await lookupHarness?.getShowMorePicker();\n\n await expectAsync(picker?.getSearchAriaLabel()).toBeResolvedTo(\n 'Search names',\n );\n await expectAsync(picker?.getSaveButtonAriaLabel()).toBeResolvedTo(\n 'Select names',\n );\n });\n});\n"
+ },
+ {
+ "fileName": "demo.component.scss",
+ "filePath": "/projects/lookup/documentation/code-examples/lookup/add-item/demo.component.scss",
+ "rawContents": ".lookup-demo-alert {\n padding: 10px;\n margin-bottom: 10px;\n border: 1px solid #cdcfd2;\n border-radius: 3px;\n}\n\n.lookup-demo-alert pre {\n margin: 0;\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/lookup/add-item/demo.component.html",
+ "rawContents": "\n"
+ },
+ {
+ "fileName": "add-item-modal.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/lookup/add-item/add-item-modal.component.ts",
+ "rawContents": "import { Component, inject } from '@angular/core';\nimport {\n FormBuilder,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { SkyInputBoxModule } from '@skyux/forms';\nimport { SkyModalInstance, SkyModalModule } from '@skyux/modals';\n\nlet nextId = 21;\n\n@Component({\n standalone: true,\n selector: 'app-add-item-modal',\n templateUrl: './add-item-modal.component.html',\n imports: [\n FormsModule,\n ReactiveFormsModule,\n SkyInputBoxModule,\n SkyModalModule,\n ],\n})\nexport class AddItemModalComponent {\n protected readonly formGroup: FormGroup;\n\n readonly #modal = inject(SkyModalInstance);\n\n constructor() {\n this.formGroup = inject(FormBuilder).group({\n id: [`${nextId++}`],\n name: ['', Validators.required],\n });\n }\n\n protected close(): void {\n this.#modal.close();\n }\n\n protected save(): void {\n if (this.formGroup.valid) {\n this.#modal.close(this.formGroup.value, 'save');\n } else {\n this.formGroup.markAllAsTouched();\n }\n }\n}\n"
+ },
+ {
+ "fileName": "add-item-modal.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/lookup/add-item/add-item-modal.component.html",
+ "rawContents": "\n \n Add Item
\n \n \n \n \n \n \n \n \n\n"
+ },
+ {
+ "fileName": "demo.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/country-field/basic/demo.component.ts",
+ "rawContents": "import { CommonModule } from '@angular/common';\nimport { Component } from '@angular/core';\nimport {\n FormControl,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n Validators,\n} from '@angular/forms';\nimport { SkyInputBoxModule } from '@skyux/forms';\nimport { SkyCountryFieldModule } from '@skyux/lookup';\n\n@Component({\n standalone: true,\n selector: 'app-demo',\n templateUrl: './demo.component.html',\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n SkyCountryFieldModule,\n SkyInputBoxModule,\n ],\n})\nexport class DemoComponent {\n protected countryControl: FormControl;\n protected countryForm: FormGroup;\n protected labelText = 'Country';\n\n constructor() {\n this.countryControl = new FormControl();\n\n this.countryControl.setValue({\n name: 'Australia',\n iso2: 'au',\n });\n\n this.countryForm = new FormGroup({\n countryControl: this.countryControl,\n });\n\n this.countryControl.setValidators([Validators.required]);\n }\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/country-field/basic/demo.component.html",
+ "rawContents": "\n"
+ },
+ {
+ "fileName": "demo.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/search-filters/demo.component.ts",
+ "rawContents": "import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport {\n FormBuilder,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { SkyIdModule } from '@skyux/core';\nimport {\n SkyAutocompleteModule,\n SkyAutocompleteSearchFunctionFilter,\n} from '@skyux/lookup';\n\n@Component({\n standalone: true,\n selector: 'app-demo',\n templateUrl: './demo.component.html',\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n SkyAutocompleteModule,\n SkyIdModule,\n ],\n})\nexport class DemoComponent {\n protected colors: { name: string }[] = [\n { name: 'Red' },\n { name: 'Blue' },\n { name: 'Green' },\n { name: 'Orange' },\n { name: 'Pink' },\n { name: 'Purple' },\n { name: 'Yellow' },\n { name: 'Brown' },\n { name: 'Turquoise' },\n { name: 'White' },\n { name: 'Black' },\n ];\n\n protected formGroup: FormGroup;\n\n protected searchFilters: SkyAutocompleteSearchFunctionFilter[] = [\n (searchText: string, item: { name: string }): boolean => {\n return item.name !== 'Red';\n },\n ];\n\n constructor() {\n this.formGroup = inject(FormBuilder).group({\n favoriteColor: undefined,\n });\n }\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/search-filters/demo.component.html",
+ "rawContents": "\n"
+ },
+ {
+ "fileName": "ocean.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/custom-search/ocean.ts",
+ "rawContents": "export interface Ocean {\n id: number;\n title: string;\n}\n"
+ },
+ {
+ "fileName": "demo.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/custom-search/demo.component.ts",
+ "rawContents": "import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport {\n FormBuilder,\n FormControl,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { SkyIdModule } from '@skyux/core';\nimport { SkyIconModule } from '@skyux/indicators';\nimport {\n SkyAutocompleteModule,\n SkyAutocompleteSearchFunction,\n SkyAutocompleteSearchFunctionResponse,\n} from '@skyux/lookup';\n\nimport { Ocean } from './ocean';\n\n@Component({\n standalone: true,\n selector: 'app-demo',\n templateUrl: './demo.component.html',\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n SkyAutocompleteModule,\n SkyIconModule,\n SkyIdModule,\n ],\n})\nexport class DemoComponent {\n protected formGroup: FormGroup;\n protected largestOcean: FormControl;\n\n protected oceans: Ocean[] = [\n { title: 'Arctic', id: 1 },\n { title: 'Atlantic', id: 2 },\n { title: 'Indian', id: 3 },\n { title: 'Pacific', id: 4 },\n ];\n\n readonly #formBuilder = inject(FormBuilder);\n\n constructor() {\n this.largestOcean = this.#formBuilder.control({ title: 'Arctic', id: 1 });\n this.formGroup = this.#formBuilder.group({\n largestOcean: this.largestOcean,\n });\n }\n\n protected getOceanSearchFunction(): SkyAutocompleteSearchFunction {\n const searchFunction = (\n searchText: string,\n oceans: Ocean[],\n ): SkyAutocompleteSearchFunctionResponse => {\n return new Promise((resolve) => {\n const searchTextLower = searchText.toLowerCase();\n\n const results = oceans.filter((ocean: Ocean) => {\n const val = ocean.title;\n const isMatch =\n val && val.toString().toLowerCase().indexOf(searchTextLower) > -1;\n return isMatch;\n });\n\n // Simulate an async request.\n setTimeout(() => {\n resolve(results);\n }, 500);\n });\n };\n\n return searchFunction;\n }\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/custom-search/demo.component.html",
+ "rawContents": "\n\n\n \n {{ item.title }} • ID {{ item.id }}\n\n"
+ },
+ {
+ "fileName": "demo.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/basic/demo.component.ts",
+ "rawContents": "import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport {\n FormBuilder,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { SkyIdModule } from '@skyux/core';\nimport { SkyAutocompleteModule } from '@skyux/lookup';\n\n@Component({\n standalone: true,\n selector: 'app-demo',\n templateUrl: './demo.component.html',\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n SkyAutocompleteModule,\n SkyIdModule,\n ],\n})\nexport class DemoComponent {\n public colors: { name: string }[] = [\n { name: 'Red' },\n { name: 'Blue' },\n { name: 'Green' },\n { name: 'Orange' },\n { name: 'Pink' },\n { name: 'Purple' },\n { name: 'Yellow' },\n { name: 'Brown' },\n { name: 'Turquoise' },\n { name: 'White' },\n { name: 'Black' },\n ];\n\n protected formGroup: FormGroup;\n\n constructor() {\n this.formGroup = inject(FormBuilder).group({\n favoriteColor: undefined,\n });\n }\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/basic/demo.component.html",
+ "rawContents": "\n"
+ },
+ {
+ "fileName": "planet.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/advanced/planet.ts",
+ "rawContents": "export interface Planet {\n name?: string;\n description?: string;\n}\n"
+ },
+ {
+ "fileName": "demo.component.ts",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/advanced/demo.component.ts",
+ "rawContents": "import { CommonModule } from '@angular/common';\nimport { Component, inject } from '@angular/core';\nimport {\n FormBuilder,\n FormControl,\n FormGroup,\n FormsModule,\n ReactiveFormsModule,\n} from '@angular/forms';\nimport { SkyIdModule } from '@skyux/core';\nimport {\n SkyAutocompleteModule,\n SkyAutocompleteSearchFunctionFilter,\n SkyAutocompleteSelectionChange,\n} from '@skyux/lookup';\n\nimport { Planet } from './planet';\n\n@Component({\n standalone: true,\n selector: 'app-demo',\n templateUrl: './demo.component.html',\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n SkyAutocompleteModule,\n SkyIdModule,\n ],\n})\nexport class DemoComponent {\n protected farthestPlanet: FormControl;\n protected formGroup: FormGroup;\n\n protected planets: Planet[] = [\n {\n name: 'Mercury',\n description: 'Mercury is a planet in our solar system.',\n },\n { name: 'Venus', description: 'Venus is a planet in our solar system.' },\n { name: 'Earth', description: 'Earth is a planet in our solar system.' },\n { name: 'Mars', description: 'Mars is a planet in our solar system.' },\n {\n name: 'Jupiter',\n description: 'Jupiter is a planet in our solar system.',\n },\n { name: 'Saturn', description: 'Saturn is a planet in our solar system.' },\n { name: 'Uranus', description: 'Uranus is a planet in our solar system.' },\n {\n name: 'Neptune',\n description: 'Neptune is a planet in our solar system.',\n },\n ];\n\n protected searchFilters: SkyAutocompleteSearchFunctionFilter[] = [\n (searchText: string, item: Planet): boolean => {\n return item.name !== 'Red';\n },\n ];\n\n readonly #formBuilder = inject(FormBuilder);\n\n constructor() {\n this.farthestPlanet = this.#formBuilder.control({});\n this.formGroup = this.#formBuilder.group({\n farthestPlanet: this.farthestPlanet,\n });\n }\n\n protected onPlanetSelection(args: SkyAutocompleteSelectionChange): void {\n alert(`You selected ${args.selectedItem.name}`);\n }\n}\n"
+ },
+ {
+ "fileName": "demo.component.html",
+ "filePath": "/projects/lookup/documentation/code-examples/autocomplete/advanced/demo.component.html",
+ "rawContents": "\n\n\n \n {{ item.name }}\n \n
\n {{ item.description }}\n\n"
+ }
+ ],
+ "codeExampleDependencies": {
+ "/projects/lookup/documentation/code-examples/selection-modal/basic": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/selection-modal/add-item": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/search/basic": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/single-select": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/result-templates": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/multi-select": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/custom-picker": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/async": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/lookup/add-item": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/forms/testing": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/lookup/testing": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/country-field/basic": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/autocomplete/search-filters": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/autocomplete/custom-search": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/autocomplete/basic": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
+ },
+ "/projects/lookup/documentation/code-examples/autocomplete/advanced": {
+ "@angular/animations": "16.2.9",
+ "@angular/cdk": "16.2.8",
+ "@angular/common": "16.2.9",
+ "@angular/core": "16.2.9",
+ "@angular/forms": "16.2.9",
+ "@angular/platform-browser": "16.2.9",
+ "@skyux/core": "9.21.3",
+ "@skyux/forms": "9.21.3",
+ "@skyux/i18n": "9.21.3",
+ "@skyux/indicators": "9.21.3",
+ "@skyux/layout": "9.21.3",
+ "@skyux/lists": "9.21.3",
+ "@skyux/lookup": "9.21.3",
+ "@skyux/modals": "9.21.3",
+ "@skyux/theme": "9.21.3",
+ "intl-tel-input": "18.2.1",
+ "rxjs": "7.8.1",
+ "tslib": "2.6.2",
+ "zone.js": "0.13.3"
}
- ]
+ }
}
diff --git a/projects/docs-tools/package.json b/projects/docs-tools/package.json
index e6b58416..86d8ec77 100644
--- a/projects/docs-tools/package.json
+++ b/projects/docs-tools/package.json
@@ -2,25 +2,25 @@
"name": "@skyux/docs-tools",
"version": "9.1.5",
"peerDependencies": {
- "@angular/common": "^16.2.5",
- "@angular/core": "^16.2.5",
- "@angular/forms": "^16.2.5",
- "@angular/platform-browser": "^16.2.5",
+ "@angular/common": "^16.2.12",
+ "@angular/core": "^16.2.12",
+ "@angular/forms": "^16.2.12",
+ "@angular/platform-browser": "^16.2.12",
"@blackbaud/skyux-lib-code-block": "^9.0.0",
"@blackbaud/skyux-lib-clipboard": "^9.0.0",
"@blackbaud/skyux-lib-media": "^9.0.0",
"@blackbaud/skyux-lib-stache": "^9.0.0",
- "@skyux/core": "^9.2.1",
- "@skyux/forms": "^9.2.1",
- "@skyux/http": "^9.2.1",
- "@skyux/i18n": "^9.2.1",
- "@skyux/icons": "^6.3.0",
- "@skyux/indicators": "^9.2.1",
- "@skyux/layout": "^9.2.1",
- "@skyux/lists": "^9.2.1",
- "@skyux/popovers": "^9.2.1",
- "@skyux/tabs": "^9.2.1",
- "@skyux/theme": "^9.2.1"
+ "@skyux/core": "^9.21.3",
+ "@skyux/forms": "^9.21.3",
+ "@skyux/http": "^9.21.3",
+ "@skyux/i18n": "^9.21.3",
+ "@skyux/icons": "^6.8.1",
+ "@skyux/indicators": "^9.21.3",
+ "@skyux/layout": "^9.21.3",
+ "@skyux/lists": "^9.21.3",
+ "@skyux/popovers": "^9.21.3",
+ "@skyux/tabs": "^9.21.3",
+ "@skyux/theme": "^9.21.3"
},
"dependencies": {
"@stackblitz/sdk": "1.9.0",
diff --git a/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.spec.ts b/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.spec.ts
index 5c722a8b..bd9667fc 100644
--- a/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.spec.ts
+++ b/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.spec.ts
@@ -250,6 +250,12 @@ describe('Code examples editor service', () => {
it('should add standalone components from code example to app.module.ts', () => {
moduleImports.push('DemoComponent');
service.launchEditor(codeExampleWithStandaloneComponent);
+ codeExampleWithStandaloneComponent.sourceCode.push({
+ fileName: 'demo.component.html',
+ filePath: './',
+ rawContents: 'hello world
',
+ });
+ service.launchEditor(codeExampleWithStandaloneComponent);
const spyArgs = stackblitzSpy.calls.mostRecent().args;
const appModuleContents = spyArgs[0].files['src/app/app.module.ts'];
@@ -332,7 +338,7 @@ describe('Code examples editor service', () => {
service.launchEditor(codeExample);
- const angularVersion = `^${ANGULAR_VERSION.major}`;
+ const angularVersion = `^${ANGULAR_VERSION.major}.${ANGULAR_VERSION.minor}.0`;
const skyuxVersion = `^${SKY_UX_VERSION.full}`;
expect(stackblitzSpy.calls.mostRecent().args[0].dependencies).toEqual({
@@ -364,7 +370,6 @@ describe('Code examples editor service', () => {
'@skyux/router': skyuxVersion,
'@skyux/theme': skyuxVersion,
'@types/jasmine': '~4.3.1',
- 'ng2-dragula': '^5.0.1',
rxjs: '^7',
tslib: '^2.5.0',
typescript: '~5.1.6',
diff --git a/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.ts b/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.ts
index f416fbe8..d1e8b904 100644
--- a/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.ts
+++ b/projects/docs-tools/src/modules/code-examples/code-examples-editor.service.ts
@@ -22,13 +22,21 @@ import { SkyDocsCodeExampleTheme } from './code-example-theme';
export class SkyDocsCodeExamplesEditorService {
public launchEditor(codeExample: SkyDocsCodeExample): void {
const project = this.#getPayload(codeExample);
- const options: StackBlitzOpenOptions = {};
+ const openFile: string[] = [];
+ if (project.files['src/app/demo.component.html']) {
+ openFile.push('src/app/demo.component.html');
+ } else if (project.files['src/app/demo.component.ts']) {
+ openFile.push('src/app/demo.component.ts');
+ }
+ const options: StackBlitzOpenOptions = {
+ openFile,
+ };
StackBlitzSDK.openProject(project, options);
}
#getPayload(codeExample: SkyDocsCodeExample): StackBlitzProject {
- const angularVersion = `^${ANGULAR_VERSION.major}`;
+ const angularVersion = `^${ANGULAR_VERSION.major}.${ANGULAR_VERSION.minor}.0`;
const skyuxVersion = `^${SKY_UX_VERSION.full}`;
const defaultDependencies: SkyDocsCodeExampleModuleDependencies = {
@@ -60,18 +68,23 @@ export class SkyDocsCodeExamplesEditorService {
'@skyux/router': skyuxVersion,
'@skyux/theme': skyuxVersion,
'@types/jasmine': '~4.3.1',
- 'ng2-dragula': '^5.0.1',
rxjs: '^7',
tslib: '^2.5.0',
typescript: '~5.1.6',
'zone.js': '~0.13.1',
};
- const mergedDependencies = Object.assign(
+ let mergedDependencies = Object.assign(
{},
- defaultDependencies,
- codeExample.packageDependencies
+ codeExample.packageDependencies,
+ defaultDependencies
);
+ mergedDependencies = Object.keys(mergedDependencies)
+ .sort()
+ .reduce((sorted, key) => {
+ sorted[key] = mergedDependencies[key];
+ return sorted;
+ }, {});
// Ensure any @skyux dependencies list the correct version of SKY UX.
// e.g. `"@skyux/core": "*"` --> `"@skyux/core": "5.0.0"`
@@ -100,6 +113,7 @@ export class SkyDocsCodeExamplesEditorService {
title: 'SKY UX Demo',
description: 'SKY UX Demo',
template: 'angular-cli',
+ // template: 'node', // web-container
dependencies: mergedDependencies,
settings: {
compile: {
@@ -292,13 +306,13 @@ platformBrowserDynamic()
`;
- files[`${srcPath}styles.scss`] = `@import '@skyux/theme/css/sky';
-@import '@skyux/theme/css/themes/modern/styles';
+ files[`${srcPath}styles.scss`] = `@import '@skyux/theme/css/sky.css';
+@import '@skyux/theme/css/themes/modern/styles.css';
body {
background-color: #fff;
margin: 15px;
-}`;
+}\n`;
stylesheets.push('src/styles.scss');
@@ -318,6 +332,7 @@ body {
options: {
index: 'src/index.html',
main: 'src/main.ts',
+ outputPath: 'dist/demo',
tsConfig: 'tsconfig.app.json',
inlineStyleLanguage: 'scss',
styles: stylesheets,
diff --git a/projects/docs-tools/src/modules/code-examples/code-examples.component.spec.ts b/projects/docs-tools/src/modules/code-examples/code-examples.component.spec.ts
index 4dda0af2..7a7d3518 100644
--- a/projects/docs-tools/src/modules/code-examples/code-examples.component.spec.ts
+++ b/projects/docs-tools/src/modules/code-examples/code-examples.component.spec.ts
@@ -7,6 +7,7 @@ import { CodeExamplesFixtureComponent } from './fixtures/code-examples-fixture.c
import { CodeExampleFixturesModule } from './fixtures/code-example-fixtures.module';
import { SkyDocsCodeExamplesEditorService } from './code-examples-editor.service';
import { SkyDocsCodeExampleTheme } from './code-example-theme';
+import { SkySourceCodeDependencies } from '../source-code/source-code-dependencies';
const MOCK_SOURCE_CODE = [
{
@@ -34,6 +35,12 @@ class MockSourceCodeService {
return [];
}
+
+ public getSourceCodeDependencies(
+ filePath: string
+ ): SkySourceCodeDependencies {
+ return { '@example/foo': '1.0.1' };
+ }
}
describe('Code example component', () => {
@@ -72,7 +79,7 @@ describe('Code example component', () => {
expect(editorService.launchEditor).toHaveBeenCalledWith({
heading: 'Basic',
- packageDependencies: {},
+ packageDependencies: { '@example/foo': '1.0.1' },
sourceCode: MOCK_SOURCE_CODE,
theme: SkyDocsCodeExampleTheme.Default,
stylesheets: undefined,
@@ -90,6 +97,7 @@ describe('Code example component', () => {
heading: 'Basic',
packageDependencies: {
foobar: 'latest',
+ '@example/foo': '1.0.1',
},
sourceCode: MOCK_SOURCE_CODE,
theme: SkyDocsCodeExampleTheme.Default,
@@ -106,7 +114,9 @@ describe('Code example component', () => {
expect(editorService.launchEditor).toHaveBeenCalledWith({
heading: 'Basic',
- packageDependencies: {},
+ packageDependencies: {
+ '@example/foo': '1.0.1',
+ },
sourceCode: MOCK_SOURCE_CODE,
theme: SkyDocsCodeExampleTheme.Default,
stylesheets: ['styles.css'],
diff --git a/projects/docs-tools/src/modules/code-examples/code-examples.component.ts b/projects/docs-tools/src/modules/code-examples/code-examples.component.ts
index d0b6bce0..f3e42329 100644
--- a/projects/docs-tools/src/modules/code-examples/code-examples.component.ts
+++ b/projects/docs-tools/src/modules/code-examples/code-examples.component.ts
@@ -84,9 +84,20 @@ export class SkyDocsCodeExamplesComponent implements AfterContentInit {
return;
}
+ let packageDependencies = {
+ ...this.packageDependencies,
+ ...this.sourceCodeService.getSourceCodeDependencies(sourceCodePath),
+ };
+ packageDependencies = Object.keys(packageDependencies)
+ .sort()
+ .reduce((sorted, key) => {
+ sorted[key] = packageDependencies[key];
+ return sorted;
+ }, {});
+
this.codeExamples.push({
heading: component.heading,
- packageDependencies: this.packageDependencies,
+ packageDependencies,
sourceCode,
stylesheets: this.stylesheets,
theme: component.theme,
diff --git a/projects/docs-tools/src/modules/source-code/source-code-dependencies.ts b/projects/docs-tools/src/modules/source-code/source-code-dependencies.ts
new file mode 100644
index 00000000..528cd9af
--- /dev/null
+++ b/projects/docs-tools/src/modules/source-code/source-code-dependencies.ts
@@ -0,0 +1 @@
+export type SkySourceCodeDependencies = { [packageName: string]: string };
diff --git a/projects/docs-tools/src/modules/source-code/source-code-provider.ts b/projects/docs-tools/src/modules/source-code/source-code-provider.ts
index ddf18c2f..6939d3c7 100644
--- a/projects/docs-tools/src/modules/source-code/source-code-provider.ts
+++ b/projects/docs-tools/src/modules/source-code/source-code-provider.ts
@@ -1,8 +1,12 @@
import { Injectable } from '@angular/core';
+import { SkySourceCodeDependencies } from './source-code-dependencies';
@Injectable({
providedIn: 'any',
})
export class SkyDocsSourceCodeProvider {
public readonly sourceCode: any[];
+ public readonly dependencies: {
+ [examplePath: string]: SkySourceCodeDependencies;
+ } = {};
}
diff --git a/projects/docs-tools/src/modules/source-code/source-code.service.spec.ts b/projects/docs-tools/src/modules/source-code/source-code.service.spec.ts
index f834966d..7bbbc997 100644
--- a/projects/docs-tools/src/modules/source-code/source-code.service.spec.ts
+++ b/projects/docs-tools/src/modules/source-code/source-code.service.spec.ts
@@ -1,6 +1,7 @@
import { SkyDocsSourceCodeProvider } from './source-code-provider';
import { SkyDocsSourceCodeService } from './source-code.service';
+import { TestBed } from '@angular/core/testing';
describe('Source code service', () => {
let service: SkyDocsSourceCodeService;
@@ -15,6 +16,7 @@ describe('Source code service', () => {
rawContents: '',
},
],
+ dependencies: {},
};
service = new SkyDocsSourceCodeService(mockSourceCodeProvider);
expect(service.getSourceCode(path)[0].rawContents).toEqual('');
@@ -29,6 +31,7 @@ describe('Source code service', () => {
rawContents: '%3Cbaz%3E%3C/baz%3E',
},
],
+ dependencies: {},
};
service = new SkyDocsSourceCodeService(mockSourceCodeProvider);
expect(service.getSourceCode(path)[0].rawContents).toEqual('');
@@ -43,10 +46,41 @@ describe('Source code service', () => {
rawContents: '',
},
],
+ dependencies: {},
};
service = new SkyDocsSourceCodeService(mockSourceCodeProvider);
expect(service.getSourceCode(path)[0].rawContents).toEqual(
''
);
});
+
+ it('getSourceCode should handle no match', () => {
+ const mockSourceCodeProvider: SkyDocsSourceCodeProvider = {
+ sourceCode: [],
+ dependencies: {},
+ };
+ service = new SkyDocsSourceCodeService(mockSourceCodeProvider);
+ expect(service.getSourceCode(path)).toEqual([]);
+ });
+
+ it('getSourceCodeDependencies should get dependencies', () => {
+ const mockSourceCodeProvider: SkyDocsSourceCodeProvider = {
+ sourceCode: [],
+ dependencies: {
+ 'foo/bar': { pkg1: '1.0.0', pkg2: '2.0.0' },
+ },
+ };
+ service = new SkyDocsSourceCodeService(mockSourceCodeProvider);
+ expect(service.getSourceCodeDependencies(path)).toEqual({
+ pkg1: '1.0.0',
+ pkg2: '2.0.0',
+ });
+ expect(service.getSourceCodeDependencies('other')).toEqual({});
+ });
+
+ it('should use provider', () => {
+ const sourceCodeProvider = TestBed.inject(SkyDocsSourceCodeProvider);
+ expect(sourceCodeProvider).toBeTruthy();
+ expect(sourceCodeProvider.dependencies).toEqual({});
+ });
});
diff --git a/projects/docs-tools/src/modules/source-code/source-code.service.ts b/projects/docs-tools/src/modules/source-code/source-code.service.ts
index d1a65d69..dbe36ce5 100644
--- a/projects/docs-tools/src/modules/source-code/source-code.service.ts
+++ b/projects/docs-tools/src/modules/source-code/source-code.service.ts
@@ -3,6 +3,7 @@ import { Injectable } from '@angular/core';
import { SkyDocsSourceCodeFile } from './source-code-file';
import { SkyDocsSourceCodeProvider } from './source-code-provider';
+import { SkySourceCodeDependencies } from './source-code-dependencies';
@Injectable({
providedIn: 'any',
@@ -10,6 +11,10 @@ import { SkyDocsSourceCodeProvider } from './source-code-provider';
export class SkyDocsSourceCodeService {
constructor(private sourceCodeProvider: SkyDocsSourceCodeProvider) {}
+ public getSourceCodeDependencies(path: string): SkySourceCodeDependencies {
+ return this.sourceCodeProvider.dependencies[path.replace(/\/$/, '')] || {};
+ }
+
public getSourceCode(path: string): SkyDocsSourceCodeFile[] {
const sourceCode = this.sourceCodeProvider.sourceCode;
if (!sourceCode || !sourceCode.length) {