diff --git a/.eslintignore b/.eslintignore index 630e909f..c1033aef 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,8 @@ node_modules/ declarations/ +dist/ +dist-typedoc/ *.yaml *.md docs-app/ -ui/ \ No newline at end of file +ui/ diff --git a/.gitignore b/.gitignore index bf8f0c7a..dae501b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ node_modules/ +dist/ +dist-typedoc/ declarations/ .turbo/ diff --git a/.prettierignore b/.prettierignore index 72f651f1..c1033aef 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,7 @@ node_modules/ declarations/ +dist/ +dist-typedoc/ *.yaml *.md docs-app/ diff --git a/docs-app/.template-lintrc.js b/docs-app/.template-lintrc.js index 9e274c75..cfca5a21 100644 --- a/docs-app/.template-lintrc.js +++ b/docs-app/.template-lintrc.js @@ -5,5 +5,7 @@ module.exports = { rules: { 'no-forbidden-elements': 'off', 'no-inline-styles': 'off', + // Let prettier maintain invis + 'no-whitespace-for-layout': 'off', }, }; diff --git a/docs-app/app/routes/application.ts b/docs-app/app/routes/application.ts index 70bcd061..e31d4bb7 100644 --- a/docs-app/app/routes/application.ts +++ b/docs-app/app/routes/application.ts @@ -25,6 +25,7 @@ export default class ApplicationRoute extends Route { import('shiki/langs/glimmer-js.mjs'), import('shiki/langs/glimmer-ts.mjs'), import('shiki/langs/handlebars.mjs'), + import('shiki/langs/jsonc.mjs'), ], langAlias: { gjs: 'glimmer-js', diff --git a/docs-app/app/styles/app.css b/docs-app/app/styles/app.css index acfca60b..c906285c 100644 --- a/docs-app/app/styles/app.css +++ b/docs-app/app/styles/app.css @@ -3,3 +3,22 @@ a.active { font-weight: bold; } + +pre.shiki { + white-space: pre-wrap; + /* overflow: hidden; */ +} +pre.shiki > code { + /* padding-right: 1rem; */ + /* overflow: auto; */ +} + +fieldset { + padding: 1rem; +} +fieldset summary { + font-weight: bold; + font-style: italic; + font-size: 1.2rem; + border-bottom: 1px solid #888; +} diff --git a/docs-app/app/templates/application.gts b/docs-app/app/templates/application.gts index 00ac79a5..6a40eedc 100644 --- a/docs-app/app/templates/application.gts +++ b/docs-app/app/templates/application.gts @@ -1,42 +1,127 @@ +import 'ember-mobile-menu/themes/android'; + +import { on } from '@ember/modifier'; + import { pascalCase, sentenceCase } from 'change-case'; import ENV from 'docs-app/config/environment'; +// @ts-expect-error no types for the mobile-menu +import MenuWrapper from 'ember-mobile-menu/components/mobile-menu-wrapper'; import { pageTitle } from 'ember-page-title'; import Route from 'ember-route-template'; import { GroupNav, PageNav } from 'kolay/components'; +import type { TOC } from '@ember/component/template-only'; import type { Page } from 'kolay'; +const Menu: TOC<{ Element: SVGElement }> = ; + +const SideNav: TOC<{ Element: HTMLElement }> = ; + export default Route( ); diff --git a/docs-app/app/templates/page.gjs b/docs-app/app/templates/page.gjs index 9646aacb..80cbb9c5 100644 --- a/docs-app/app/templates/page.gjs +++ b/docs-app/app/templates/page.gjs @@ -2,25 +2,25 @@ import Route from 'ember-route-template'; import { Page } from 'kolay/components'; function removeLoader() { - document.querySelector('#kolay__loading')?.remove(); + requestAnimationFrame(() => { + document.querySelector('#kolay__loading')?.remove(); + }); } export default Route( ); diff --git a/docs-app/ember-cli-build.js b/docs-app/ember-cli-build.js index b7d84add..14df3dcf 100644 --- a/docs-app/ember-cli-build.js +++ b/docs-app/ember-cli-build.js @@ -8,6 +8,9 @@ module.exports = async function (defaults) { 'ember-cli-babel': { enableTypeScriptTransform: true, }, + autoImport: { + watchedDependencies: ['kolay', '@universal-ember/kolay-ui'], + }, }); const { Webpack } = require('@embroider/webpack'); diff --git a/docs-app/package.json b/docs-app/package.json index a1f18189..f823bd4f 100644 --- a/docs-app/package.json +++ b/docs-app/package.json @@ -102,6 +102,7 @@ "change-case": "^5.4.3", "ember-async-data": "^1.0.3", "ember-cached-decorator-polyfill": "^1.0.2", + "ember-mobile-menu": "^5.1.0", "ember-repl": "^4.1.1", "ember-route-template": "^1.0.3", "kolay": "workspace:^", diff --git a/docs-app/public/docs/plugins/index.md b/docs-app/public/docs/plugins/index.md deleted file mode 100644 index b607884a..00000000 --- a/docs-app/public/docs/plugins/index.md +++ /dev/null @@ -1,9 +0,0 @@ -# Build Plugins - -Kolay requires some build-time static analysis to function. - -[`kolay(...)`][plugin-kolay] is the only required plugin. This generates the navigation and information about how Kolay's runtime code will fetch the markdown documents deployed with the app's static assets. Optionally, if a list of packages is provided, apiDocs will be generated from your library's type declarations. Rendering these api docs uses the [Signature Components][ui-signature] or [`APIDocs`][ui-apiDocs] components. - -[plugin-kolay]: /plugins/kolay.md -[ui-signature]: /Runtime/components/component-signature.md -[ui-apiDocs]: /Runtime/components/api-docs.md diff --git a/docs-app/public/docs/plugins/kolay.md b/docs-app/public/docs/plugins/kolay.md index 9d5645e8..6cdddec4 100644 --- a/docs-app/public/docs/plugins/kolay.md +++ b/docs-app/public/docs/plugins/kolay.md @@ -1,14 +1,38 @@ # `kolay(...)` -This is the main build plugin +Kolay requires some build-time static analysis to function. -## Config +`kolay(...)` is the only required plugin. This generates the navigation and information about how Kolay's runtime code will fetch the markdown documents deployed with the app's static assets. Optionally, if a list of packages is provided, apiDocs will be generated from your library's type declarations. Rendering these api docs uses the [Signature Components][ui-signature] or [`APIDocs`][ui-apiDocs] components. -either json or jsonc +[plugin-kolay]: /plugins/kolay.md +[ui-signature]: /Runtime/components/component-signature.md +[ui-apiDocs]: /Runtime/components/api-docs.md -- set order -- change name +Usage in embroider / webpack: + +```js +// ember-cli-build.js + +const { kolay } = await import("kolay/webpack"); + +return require("@embroider/compat").compatBuild(app, Webpack, { + /* ... */ + packagerOptions: { + webpackConfig: { + /* ... */ + plugins: [kolay(/* Options, see below */)], + }, + }, +}); +``` ```hbs live no-shadow - + ``` + +## Conventions + +There are a few ways you can collect docs: + +- using `src`, these are your main docs, but they could also be your only docs. If you have a small project, this will provide the best experience for working with documentation as changes to this directory are (especially if using the recommended `public/docs` value), will automatically reload when changes are made. +- The `groups` option are where more freedom is provided. This can point at a `docs` folder in another folder in your project, or it can point at a `components` folder and the plugin will pick up all markdown files it finds in there. This can be useful for co-locating docs with their implementations. diff --git a/docs-app/public/docs/usage/meta.jsonc b/docs-app/public/docs/usage/meta.jsonc new file mode 100644 index 00000000..711bf244 --- /dev/null +++ b/docs-app/public/docs/usage/meta.jsonc @@ -0,0 +1,4 @@ +{ + // This is in order of need-to-know + "order": ["setup", "rendering-pages", "ordering-pages"], +} diff --git a/docs-app/public/docs/usage/ordering-pages.md b/docs-app/public/docs/usage/ordering-pages.md new file mode 100644 index 00000000..5579f334 --- /dev/null +++ b/docs-app/public/docs/usage/ordering-pages.md @@ -0,0 +1,54 @@ +## Ordering + +At build time, the order of both pages and folders can be configured by providing a `meta.json` or `meta.jsonc` file as a sibling to the list of paths you want to sort. + +### Sorting folders + +For example, in this project, the docs are in folders in `public/docs`: + +``` +public/ + docs/ + plugins/ + usage/ +``` + +But we want `usage` to come before `plugins`, even though alphabetically, `plugins` comes before `usage`. + +We can create a `meta.jsonc` file at `public/docs/meta.jsonc`: + +```jsonc +{ + // We want usage to be first, which breaks the + // default sort order provided by the filesystem: Alphabetical + "order": ["usage", "plugins"], +} +``` + +With `jsonc`, we can have comments to explain our reasoning for having configuration at all, and now when rendering the navigation at runtime, we can have `Usage` rendered above `Plugins` without needing to implement any runtime code to do this for us. + +### Sorting pages + +For example, in this project, the pages under `usage` appear alphabetically in the filesystem like this: + +``` +public/ + docs/ + usage/ + ordering-pages.md + rendering-pages.md + setup.md +``` + +Alphabetical ordering in this case is backwards from how it is _useful_ to read about the information contained within these documents. + +To sort these pages, we can create a `meta.json` file at `public/docs/usage/meta.jsonc` with the following contents: + +```jsonc +{ + // This is in order of need-to-know + "order": ["setup", "rendering-pages", "ordering-pages"], +} +``` + +And then the order of these pages is adjusted so that at runtime, there is nothing to do! 🥳 diff --git a/docs-app/public/docs/usage/rendering-pages.md b/docs-app/public/docs/usage/rendering-pages.md index e16b3ee5..36ef95d1 100644 --- a/docs-app/public/docs/usage/rendering-pages.md +++ b/docs-app/public/docs/usage/rendering-pages.md @@ -15,22 +15,20 @@ function removeLoader() { export default Route( , ); ``` diff --git a/docs-app/tests/kolay/components/component-signature-test.gts b/docs-app/tests/kolay/components/component-signature-test.gts index 74d2af00..bfca696f 100644 --- a/docs-app/tests/kolay/components/component-signature-test.gts +++ b/docs-app/tests/kolay/components/component-signature-test.gts @@ -1,5 +1,5 @@ import { render } from '@ember/test-helpers'; -import { module, test } from 'qunit'; +import { module, skip, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { ComponentSignature } from 'kolay'; @@ -13,7 +13,7 @@ module('', function (hooks) { manifest: await import('kolay/manifest:virtual'), })); - test('it works', async function (assert) { + test('self', async function (assert) { await render( ); + assert.dom().doesNotContainText('Element'); assert.dom().containsText('Arguments'); assert.dom().containsText('@package'); + assert.dom().containsText('@module'); + assert.dom().containsText('@name'); + assert.dom().doesNotContainText('Blocks'); + }); + + test('interface', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().containsText('@foo'); + assert.dom().containsText('@bar'); + assert.dom().containsText('Blocks'); + assert.dom().containsText(':namedBlockA'); + assert.dom().containsText(':namedBlockB'); + }); + + test('class:inline', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().containsText('@foo'); + assert.dom().containsText('@bar'); + assert.dom().containsText('Blocks'); + assert.dom().containsText(':default'); + assert.dom().containsText(':namedBlockA'); + assert.dom().containsText(':namedBlockB'); + }); + + skip('class:reference', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().containsText('@foo'); + assert.dom().containsText('@bar'); + assert.dom().containsText('Blocks'); + assert.dom().containsText(':namedBlockA'); + assert.dom().containsText(':namedBlockB'); + }); + + skip('template-only:reference', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().containsText('@foo'); + assert.dom().containsText('@bar'); + assert.dom().containsText('Blocks'); + assert.dom().containsText(':namedBlockA'); + assert.dom().containsText(':namedBlockB'); + }); + + test('template-only:inline', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().containsText('@foo'); + assert.dom().containsText('@bar'); + assert.dom().containsText('Blocks'); + assert.dom().containsText(':default'); + assert.dom().containsText(':namedBlockA'); + assert.dom().containsText(':namedBlockB'); }); }); diff --git a/docs-app/tests/kolay/components/helper-signature-test.gts b/docs-app/tests/kolay/components/helper-signature-test.gts new file mode 100644 index 00000000..190a847f --- /dev/null +++ b/docs-app/tests/kolay/components/helper-signature-test.gts @@ -0,0 +1,129 @@ +import { render } from '@ember/test-helpers'; +import { module, skip, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; + +import { HelperSignature } from 'kolay'; + +import { setupKolay } from 'kolay/test-support'; + +module('', function (hooks) { + setupRenderingTest(hooks); + setupKolay(hooks, async () => ({ + apiDocs: await import('kolay/api-docs:virtual'), + manifest: await import('kolay/manifest:virtual'), + })); + + test('self', async function (assert) { + // This is not supported + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().doesNotContainText('Arguments'); + assert.dom().doesNotContainText('@package'); + assert.dom().doesNotContainText('@module'); + assert.dom().doesNotContainText('@name'); + assert.dom().doesNotContainText('Blocks'); + }); + + test('function', async function (assert) { + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('the first argument'); + assert.dom().containsText('the second argument'); + assert.dom().containsText('Return'); + }); + + test('function:cast:HelperLike', async function (assert) { + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('first'); + assert.dom().containsText('second'); + assert.dom().containsText('Named'); + assert.dom().containsText('optional'); + assert.dom().containsText('Return'); + }); + + test('function:typescript', async function (assert) { + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('a'); + assert.dom().containsText('b'); + assert.dom().containsText('options', 'has equiv of Named'); + assert.dom().containsText('optional'); + assert.dom().containsText('required'); + assert.dom().containsText('Return'); + }); + + skip('classic class:inline', async function (assert) { + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('optional'); + assert.dom().containsText('first'); + assert.dom().containsText('second'); + assert.dom().containsText('Named'); + assert.dom().containsText('Return'); + }); + + skip('classic class:reference', async function (assert) { + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('optional'); + assert.dom().containsText('first'); + assert.dom().containsText('second'); + assert.dom().containsText('Named'); + assert.dom().containsText('Return'); + }); +}); diff --git a/docs-app/tests/kolay/components/modifier-signature-test.gts b/docs-app/tests/kolay/components/modifier-signature-test.gts new file mode 100644 index 00000000..cb9a3b6d --- /dev/null +++ b/docs-app/tests/kolay/components/modifier-signature-test.gts @@ -0,0 +1,119 @@ +import { render } from '@ember/test-helpers'; +import { module, skip, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; + +import { ModifierSignature } from 'kolay'; + +import { setupKolay } from 'kolay/test-support'; + +module('', function (hooks) { + setupRenderingTest(hooks); + setupKolay(hooks, async () => ({ + apiDocs: await import('kolay/api-docs:virtual'), + manifest: await import('kolay/manifest:virtual'), + })); + + test('self', async function (assert) { + // This is not supported + await render( + + ); + + assert.dom().doesNotContainText('Element'); + assert.dom().containsText('Arguments', 'the signatures are similar on purpose'); + assert.dom().doesNotContainText('@package'); + assert.dom().doesNotContainText('@module'); + assert.dom().doesNotContainText('@name'); + assert.dom().doesNotContainText('Blocks'); + }); + + test('interface', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().doesNotContainText('Args'); + assert.dom().doesNotContainText('Positional'); + assert.dom().containsText('x'); + assert.dom().containsText('y'); + assert.dom().containsText('invert'); + }); + + skip('function:inline', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().doesNotContainText('Args'); + assert.dom().doesNotContainText('Positional'); + assert.dom().containsText('x'); + assert.dom().containsText('y'); + assert.dom().containsText('invert'); + }); + + skip('function:implicit', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().doesNotContainText('Args'); + assert.dom().doesNotContainText('Positional'); + assert.dom().containsText('x'); + assert.dom().containsText('y'); + assert.dom().containsText('invert'); + }); + + test('ModifierLike', async function (assert) { + await render( + + ); + + assert.dom().containsText('Element'); + assert.dom().containsText('HTMLDivElement'); + assert.dom().containsText('Arguments'); + assert.dom().doesNotContainText('Args'); + assert.dom().doesNotContainText('Positional'); + assert.dom().containsText('x'); + assert.dom().containsText('y'); + assert.dom().containsText('invert'); + }); +}); diff --git a/package.json b/package.json index 45cc887c..06cfa1b4 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,16 @@ }, "./build": { "types": "./declarations/plugins/index.d.ts", + "import": "./src/browser/virtual/empty.js" + }, + "./build/types": { + "types": "./declarations/plugins/types.d.ts", "import": "./src/plugins/index.js" }, + "./private/samples": { + "types": "./src/browser/private/samples.d.ts", + "default": "./src/browser/private/samples.js" + }, "./webpack": { "types": "./declarations/webpack.d.ts", "import": "./src/webpack.js" @@ -75,6 +83,7 @@ "build": "pnpm prepack", "build:declarations": "tsc --declaration", "_syncPnpm": "pnpm sync-dependencies-meta-injected", + "start:typedoc": "typedoc --options ./typedoc.config.json --watch", "test:node": "vitest --run" }, "dependencies": { @@ -103,6 +112,8 @@ "@tsconfig/node20": "^20.1.2", "@tsconfig/strictest": "^2.0.3", "@types/common-tags": "^1.8.4", + "@types/qunit": "^2.19.10", + "@types/rsvp": "^4.0.9", "@typescript-eslint/eslint-plugin": "^7.0.1", "@typescript-eslint/parser": "^7.0.1", "@universal-ember/kolay-ui": "workspace:^", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 27f3ca16..2eebdcd4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,7 +60,7 @@ importers: version: 1.3.0 '@nullvoxpopuli/eslint-configs': specifier: ^3.2.2 - version: 3.2.2(@babel/core@7.24.0)(@babel/eslint-parser@7.23.10)(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint-config-prettier@9.1.0)(eslint-plugin-ember@12.0.2)(eslint-plugin-qunit@8.1.1)(eslint@8.57.0)(prettier@3.2.5)(typescript@5.3.3) + version: 3.2.2(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(prettier@3.2.5)(typescript@5.3.3) '@tsconfig/node20': specifier: ^20.1.2 version: 20.1.2 @@ -70,6 +70,12 @@ importers: '@types/common-tags': specifier: ^1.8.4 version: 1.8.4 + '@types/qunit': + specifier: ^2.19.10 + version: 2.19.10 + '@types/rsvp': + specifier: ^4.0.9 + version: 4.0.9 '@typescript-eslint/eslint-plugin': specifier: ^7.0.1 version: 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3) @@ -157,6 +163,9 @@ importers: ember-cached-decorator-polyfill: specifier: ^1.0.2 version: 1.0.2(@babel/core@7.24.0)(@glint/template@1.3.0)(ember-source@5.7.0) + ember-mobile-menu: + specifier: ^5.1.0 + version: 5.1.0(@babel/core@7.24.0)(@ember/test-helpers@3.3.0)(@glint/template@1.3.0)(ember-source@5.7.0)(webpack@5.90.3) ember-repl: specifier: ^4.1.1 version: 4.2.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0)(reactiveweb@1.2.2) @@ -410,6 +419,9 @@ importers: concurrently: specifier: ^8.2.2 version: 8.2.2 + ember-modifier: + specifier: ^4.1.0 + version: 4.1.0(ember-source@5.7.0) ember-repl: specifier: ^4.1.1 version: 4.2.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0)(reactiveweb@1.2.2) @@ -438,8 +450,8 @@ importers: specifier: ^8.0.1 version: 8.0.1 fix-bad-declaration-output: - specifier: ^1.1.2 - version: 1.1.2 + specifier: ^1.1.4 + version: 1.1.4 prettier: specifier: ^3.1.1 version: 3.2.5 @@ -635,6 +647,27 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 + /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.0): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} @@ -704,7 +737,7 @@ packages: '@babel/core': optional: true dependencies: - '@babel/core': 7.24.0(supports-color@8.1.1) + '@babel/core': 7.24.0 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -749,6 +782,21 @@ packages: '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 + /@babel/helper-replace-supers@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} @@ -822,6 +870,14 @@ packages: dependencies: '@babel/types': 7.24.0 + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.0 + dev: true + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.24.0): resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} engines: {node: '>=6.9.0'} @@ -998,8 +1054,8 @@ packages: '@babel/core': 7.24.0 '@babel/helper-plugin-utils': 7.24.0 - /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0): - resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==} + /@babel/plugin-syntax-flow@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1263,6 +1319,20 @@ packages: '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0) '@babel/helper-plugin-utils': 7.24.0 + /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.24.0): resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} engines: {node: '>=6.9.0'} @@ -1385,8 +1455,8 @@ packages: '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0) - /@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.24.0): - resolution: {integrity: sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q==} + /@babel/plugin-transform-flow-strip-types@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1396,7 +1466,7 @@ packages: dependencies: '@babel/core': 7.24.0 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0) + '@babel/plugin-syntax-flow': 7.24.1(@babel/core@7.24.0) dev: true /@babel/plugin-transform-for-of@7.23.6(@babel/core@7.24.0): @@ -1503,6 +1573,21 @@ packages: '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-simple-access': 7.22.5 + /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-simple-access': 7.22.5 + dev: true + /@babel/plugin-transform-modules-systemjs@7.23.9(@babel/core@7.24.0): resolution: {integrity: sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==} engines: {node: '>=6.9.0'} @@ -1569,6 +1654,20 @@ packages: '@babel/helper-plugin-utils': 7.24.0 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) + /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) + dev: true + /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.24.0): resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} engines: {node: '>=6.9.0'} @@ -1638,6 +1737,21 @@ packages: '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) + /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.24.0 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) + dev: true + /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.24.0): resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} engines: {node: '>=6.9.0'} @@ -1663,6 +1777,20 @@ packages: '@babel/helper-create-class-features-plugin': 7.24.0(@babel/core@7.24.0) '@babel/helper-plugin-utils': 7.24.0 + /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.24.0): resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} engines: {node: '>=6.9.0'} @@ -1987,8 +2115,8 @@ packages: transitivePeerDependencies: - supports-color - /@babel/preset-flow@7.24.0(@babel/core@7.24.0): - resolution: {integrity: sha512-cum/nSi82cDaSJ21I4PgLTVlj0OXovFk6GRguJYe/IKg6y6JHLTbJhybtX4k35WT9wdeJfEVjycTixMhBHd0Dg==} + /@babel/preset-flow@7.24.1(@babel/core@7.24.0): + resolution: {integrity: sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -1999,7 +2127,7 @@ packages: '@babel/core': 7.24.0 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-transform-flow-strip-types': 7.23.3(@babel/core@7.24.0) + '@babel/plugin-transform-flow-strip-types': 7.24.1(@babel/core@7.24.0) dev: true /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.0): @@ -2233,6 +2361,26 @@ packages: - supports-color dev: true + /@ember/render-modifiers@2.1.0(@babel/core@7.24.0)(@glint/template@1.3.0)(ember-source@5.7.0): + resolution: {integrity: sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ==} + engines: {node: 12.* || 14.* || >= 16} + peerDependencies: + '@glint/template': ^1.0.2 + ember-source: ^3.8 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + '@glint/template': + optional: true + dependencies: + '@embroider/macros': 1.15.0(@glint/template@1.3.0) + '@glint/template': 1.3.0 + ember-cli-babel: 7.26.11 + ember-modifier-manager-polyfill: 1.2.0(@babel/core@7.24.0) + ember-source: 5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: false + /@ember/string@3.1.1: resolution: {integrity: sha512-UbXJ+k3QOrYN4SRPHgXCqYIJ+yWWUg1+vr0H4DhdQPTy8LJfyqwZ2tc5uqpSSnEXE+/1KopHBE5J8GDagAg5cg==} engines: {node: 12.* || 14.* || >= 16} @@ -3487,6 +3635,55 @@ packages: - typescript dev: true + /@nullvoxpopuli/eslint-configs@3.2.2(@typescript-eslint/eslint-plugin@7.1.0)(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(prettier@3.2.5)(typescript@5.3.3): + resolution: {integrity: sha512-Qm7TR7K+kb5emAoddPsoznmAgUptL7YWUOdtaBq2T4pgkEyr7JTS1v4TPg07LusfYi2He2nKJBdTcD++hrsNdw==} + engines: {node: '>= v16.0.0'} + peerDependencies: + '@babel/core': ^7.22.10 + '@babel/eslint-parser': ^7.22.10 + '@typescript-eslint/eslint-plugin': ^5.62.0 || >= 6.0.0 + '@typescript-eslint/parser': ^5.62.0 || >= 6.0.0 + eslint: ^7.0.0 || ^8.0.0 + eslint-plugin-ember: '>= 11.10.0' + eslint-plugin-qunit: '>= 8.0.0' + prettier: ^2.8.8 || >= 3.0.0 + peerDependenciesMeta: + '@babel/core': + optional: true + '@babel/eslint-parser': + optional: true + '@typescript-eslint/eslint-plugin': + optional: true + '@typescript-eslint/parser': + optional: true + eslint-plugin-ember: + optional: true + eslint-plugin-qunit: + optional: true + prettier: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 7.1.0(@typescript-eslint/parser@7.1.0)(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.3.3) + cosmiconfig: 8.3.6(typescript@5.3.3) + eslint: 8.57.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-decorator-position: 5.0.2(@babel/eslint-parser@7.23.10)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-json: 3.1.0 + eslint-plugin-n: 16.6.2(eslint@8.57.0) + eslint-plugin-prettier: 4.2.1(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) + eslint-plugin-simple-import-sort: 10.0.0(eslint@8.57.0) + prettier: 3.2.5 + prettier-plugin-ember-template-tag: 1.1.0(prettier@3.2.5) + transitivePeerDependencies: + - eslint-config-prettier + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + - typescript + dev: true + /@octokit/auth-token@3.0.4: resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==} engines: {node: '>= 14'} @@ -4454,6 +4651,10 @@ packages: '@types/glob': 8.1.0 '@types/node': 20.11.24 + /@types/rsvp@4.0.9: + resolution: {integrity: sha512-F6vaN5mbxw2MBCu/AD9fSKwrhnto2pE77dyUsi415qz9IP9ni9ZOWXHxnXfsM4NW9UjW+it189jvvqnhv37Z7Q==} + dev: true + /@types/semver@7.5.8: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true @@ -4928,9 +5129,6 @@ packages: /ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependenciesMeta: - ajv: - optional: true dependencies: ajv: 8.12.0 @@ -8260,6 +8458,14 @@ packages: transitivePeerDependencies: - supports-color + /ember-cli-version-checker@2.2.0: + resolution: {integrity: sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==} + engines: {node: '>= 4'} + dependencies: + resolve: 1.22.8 + semver: 5.7.2 + dev: false + /ember-cli-version-checker@3.1.3: resolution: {integrity: sha512-PZNSvpzwWgv68hcXxyjREpj3WWb81A7rtYNQq1lLEgrWIchF8ApKJjWP3NBpHjaatwILkZAV8klair5WFlXAKg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -8448,6 +8654,26 @@ packages: - '@babel/core' - supports-color + /ember-concurrency@4.0.1(@babel/core@7.24.0)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0): + resolution: {integrity: sha512-U6tEmQRPJg+qUAFM2Ub1pSSqa2AtaGZreCB6bsR3IkpiMPn19HpeebOwOIqgdE+10eUHYTXHgcsopWmPyYkHnA==} + engines: {node: 16.* || >= 18} + peerDependencies: + '@glimmer/tracking': ^1.1.2 + '@glint/template': '>= 1.0.0' + ember-source: ^3.28.0 || ^4.0.0 || >=5.0.0 + dependencies: + '@babel/helper-plugin-utils': 7.24.0 + '@babel/types': 7.24.0 + '@embroider/addon-shim': 1.8.7 + '@glimmer/tracking': 1.1.2 + '@glint/template': 1.3.0 + decorator-transforms: 1.1.0(@babel/core@7.24.0) + ember-source: 5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: false + /ember-element-helper@0.8.6(@glint/environment-ember-loose@1.3.0)(@glint/template@1.3.0)(ember-source@5.7.0): resolution: {integrity: sha512-WcbkJKgBZypRGwujeiPrQfZRhETVFLR0wvH2UxDaNBhLWncapt6KK+M/2i/eODoAQwgGxziejhXC6Cbqa9zA8g==} engines: {node: 14.* || 16.* || >= 18} @@ -8499,6 +8725,23 @@ packages: transitivePeerDependencies: - supports-color + /ember-gesture-modifiers@6.0.1(@ember/test-helpers@3.3.0)(ember-source@5.7.0): + resolution: {integrity: sha512-CQCM05eqpZx77HZqbPAgb1SVkTvXIpPY9SOmlReU4TdigHL0+BcaMD94kcAvE/4SIaxQ+/nOIp0kUmVfqUg1IQ==} + peerDependencies: + '@ember/test-helpers': '>=3.0.0' + ember-source: '>=3.28.0' + peerDependenciesMeta: + '@ember/test-helpers': + optional: true + dependencies: + '@ember/test-helpers': 3.3.0(@glint/template@1.3.0)(ember-source@5.7.0)(webpack@5.90.3) + '@embroider/addon-shim': 1.8.7 + ember-modifier: 4.1.0(ember-source@5.7.0) + ember-source: 5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3) + transitivePeerDependencies: + - supports-color + dev: false + /ember-load-initializers@2.1.2(@babel/core@7.24.0): resolution: {integrity: sha512-CYR+U/wRxLbrfYN3dh+0Tb6mFaxJKfdyz+wNql6cqTrA0BBi9k6J3AaKXj273TqvEpyyXegQFFkZEiuZdYtgJw==} engines: {node: 6.* || 8.* || >= 10.*} @@ -8510,6 +8753,45 @@ packages: - supports-color dev: true + /ember-mobile-menu@5.1.0(@babel/core@7.24.0)(@ember/test-helpers@3.3.0)(@glint/template@1.3.0)(ember-source@5.7.0)(webpack@5.90.3): + resolution: {integrity: sha512-iE+dydJ8EVaiOIZyxPe0QZsUClaUCaX8a20GvW0iTOCu1FeKrRI5HA9u9p+ELZPSw54gP/w3V53KK3pjMuDl+Q==} + peerDependencies: + ember-source: '>=3.28.0' + dependencies: + '@ember/render-modifiers': 2.1.0(@babel/core@7.24.0)(@glint/template@1.3.0)(ember-source@5.7.0) + '@ember/test-waiters': 3.1.0 + '@embroider/addon-shim': 1.8.7 + '@glimmer/component': 1.1.2(@babel/core@7.24.0) + '@glimmer/tracking': 1.1.2 + ember-concurrency: 4.0.1(@babel/core@7.24.0)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0) + ember-gesture-modifiers: 6.0.1(@ember/test-helpers@3.3.0)(ember-source@5.7.0) + ember-modify-based-class-resource: 1.1.0(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-resources@7.0.0)(ember-source@5.7.0) + ember-on-resize-modifier: 2.0.2(@glint/template@1.3.0)(ember-source@5.7.0)(webpack@5.90.3) + ember-resources: 7.0.0(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0) + ember-set-body-class: 1.0.2 + ember-source: 5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3) + tracked-built-ins: 3.3.0 + wobble: 1.5.1 + transitivePeerDependencies: + - '@babel/core' + - '@ember/test-helpers' + - '@glint/template' + - supports-color + - webpack + dev: false + + /ember-modifier-manager-polyfill@1.2.0(@babel/core@7.24.0): + resolution: {integrity: sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA==} + engines: {node: 6.* || 8.* || >= 10.*} + dependencies: + ember-cli-babel: 7.26.11 + ember-cli-version-checker: 2.2.0 + ember-compatibility-helpers: 1.2.7(@babel/core@7.24.0) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: false + /ember-modifier@4.1.0(ember-source@5.7.0): resolution: {integrity: sha512-YFCNpEYj6jdyy3EjslRb2ehNiDvaOrXTilR9+ngq+iUqSHYto2zKV0rleiA1XJQ27ELM1q8RihT29U6Lq5EyqQ==} peerDependencies: @@ -8525,6 +8807,45 @@ packages: transitivePeerDependencies: - supports-color + /ember-modify-based-class-resource@1.1.0(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-resources@7.0.0)(ember-source@5.7.0): + resolution: {integrity: sha512-35PqPA6XFncpJkePr1Zs5aR/bANpsCEa8X7fXkA0EkTyuILqP3ycqtlfK0VxkADz62lk86BR8biGsTz0jgdZUQ==} + peerDependencies: + '@glimmer/component': ^1.1.2 + '@glimmer/tracking': ^1.1.2 + ember-resources: '>= 6.4.0' + ember-source: ^3.28.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + '@glimmer/component': + optional: true + dependencies: + '@babel/runtime': 7.24.0 + '@embroider/addon-shim': 1.8.7 + '@embroider/macros': 1.15.0(@glint/template@1.3.0) + '@glimmer/component': 1.1.2(@babel/core@7.24.0) + '@glimmer/tracking': 1.1.2 + ember-resources: 7.0.0(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(@glint/template@1.3.0)(ember-source@5.7.0) + ember-source: 5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3) + transitivePeerDependencies: + - '@glint/template' + - supports-color + dev: false + + /ember-on-resize-modifier@2.0.2(@glint/template@1.3.0)(ember-source@5.7.0)(webpack@5.90.3): + resolution: {integrity: sha512-7mcD7CNbiCaZEIASWlRz/Wmn47afCMSFTdQJSSUe0WCgnXxn9DVoqZ39B7ZuddTHa0V6otTFrV/lIRYpggQ+eg==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + ember-auto-import: 2.7.2(@glint/template@1.3.0)(webpack@5.90.3) + ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 5.7.2 + ember-modifier: 4.1.0(ember-source@5.7.0) + ember-resize-observer-service: 1.1.0 + transitivePeerDependencies: + - '@glint/template' + - ember-source + - supports-color + - webpack + dev: false + /ember-page-title@8.2.2(ember-source@5.7.0): resolution: {integrity: sha512-DpIVgDaYstMSvHuhjG8QRnyfFD+E9/uy9GXO35kzmHaCg2hGB4e5Z6jcfitk8qh/lp5VRX8Tpl4HTBX+CKwMWw==} engines: {node: 16.* || >= 18} @@ -8646,6 +8967,16 @@ packages: - '@glimmer/tracking' - supports-color + /ember-resize-observer-service@1.1.0: + resolution: {integrity: sha512-/vbfxtHSyOGSNdjPKL8X3SyvUnYo3z88sJtD/bLJ0ZGhqVPaXCmtSkLyr/Fh75ckJDixRFxK4i4zEUSlrbk0PA==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 5.7.2 + transitivePeerDependencies: + - supports-color + dev: false + /ember-resolver@11.0.1(ember-source@5.7.0): resolution: {integrity: sha512-ucBk3oM+PR+AfYoSUXeQh8cDQS1sSiEKp4Pcgbew5cFMSqPxJfqd1zyZsfQKNTuyubeGmWxBOyMVSTvX2LeCyg==} engines: {node: 14.* || 16.* || >= 18} @@ -8702,6 +9033,15 @@ packages: transitivePeerDependencies: - supports-color + /ember-set-body-class@1.0.2: + resolution: {integrity: sha512-SEsTwFp9SHTg4LgebhkUuLgYWg1VZD7I1QcrV2sTY583wu216OThoSs5szvS/KgSc1xD1Z22TFvOb848t2hGfw==} + engines: {node: 10.* || 12.* || >= 14.*} + dependencies: + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color + dev: false + /ember-source@5.7.0(@babel/core@7.24.0)(@glimmer/component@1.1.2)(@glint/template@1.3.0)(webpack@5.90.3): resolution: {integrity: sha512-iOZVyxLBzGewEThDDsNRZ9y02SNH42PWSPC9U4O94pew7ktld3IpIODCDjLCtKWn2zAGM9DhWTMrXz27HI1UKw==} engines: {node: '>= 16.*'} @@ -10029,8 +10369,8 @@ packages: minimatch: 3.1.2 dev: true - /fix-bad-declaration-output@1.1.2: - resolution: {integrity: sha512-6Sj2LWVXdn5I/yykw57V7S0xeHh3WqeCPtrjwCFxI5CVa8h6yKgmzBh5QPLzKMDZ1izVjso4F9TFIJSjYPAOCw==} + /fix-bad-declaration-output@1.1.4: + resolution: {integrity: sha512-gK1foQT1cxE5GqYgyD4VVY1WCS72M+MbKUIZMRaPCx7HPWnsXKG9bqwo7aNsZiaK5gzlXNtdcg7PnQ8yoGrjZQ==} hasBin: true dependencies: fs-extra: 11.2.0 @@ -10099,8 +10439,8 @@ packages: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: true - /flow-parser@0.229.2: - resolution: {integrity: sha512-T72XV2Izvl7yV6dhHhLaJ630Y6vOZJl6dnOS6dN0bPW9ExuREu7xGAf3omtcxX76POTuux9TJPu9ZpS48a/rdw==} + /flow-parser@0.231.0: + resolution: {integrity: sha512-WVzuqwq7ZnvBceCG0DGeTQebZE+iIU0mlk5PmJgYj9DDrt+0isGC2m1ezW9vxL4V+HERJJo9ExppOnwKH2op6Q==} engines: {node: '>=0.4.0'} dev: true @@ -11606,23 +11946,23 @@ packages: optional: true dependencies: '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 - '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.24.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.24.0) - '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.24.0) - '@babel/preset-flow': 7.24.0(@babel/core@7.24.0) + '@babel/parser': 7.24.1 + '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.0) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.0) + '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.0) + '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.0) + '@babel/preset-flow': 7.24.1(@babel/core@7.24.0) '@babel/preset-typescript': 7.23.3(@babel/core@7.24.0) '@babel/register': 7.23.7(@babel/core@7.24.0) babel-core: 7.0.0-bridge.0(@babel/core@7.24.0) chalk: 4.1.2 - flow-parser: 0.229.2 + flow-parser: 0.231.0 graceful-fs: 4.2.11 micromatch: 4.0.5 neo-async: 2.6.2 node-dir: 0.1.17 - recast: 0.23.5 + recast: 0.23.6 temp: 0.8.4 write-file-atomic: 2.4.3 transitivePeerDependencies: @@ -14208,8 +14548,8 @@ packages: private: 0.1.8 source-map: 0.6.1 - /recast@0.23.5: - resolution: {integrity: sha512-M67zIddJiwXdfPQRYKJ0qZO1SLdH1I0hYeb0wzxA+pNOvAZiQHulWzuk+fYsEWRQ8VfZrgjyucqsCOtCyM01/A==} + /recast@0.23.6: + resolution: {integrity: sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==} engines: {node: '>= 4'} dependencies: ast-types: 0.16.1 @@ -17061,6 +17401,10 @@ packages: string-width: 4.2.3 dev: true + /wobble@1.5.1: + resolution: {integrity: sha512-vQD1uu0yXhZWfQJKVf2UVNb3AVnD0qXAbcIqG6Aw02ABLVm77xz6KcLuduWSwOiOMNh8TjZqouZsHTJWTdLwVQ==} + dev: false + /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} diff --git a/src/browser/private/samples.d.ts b/src/browser/private/samples.d.ts new file mode 100644 index 00000000..805ed9eb --- /dev/null +++ b/src/browser/private/samples.d.ts @@ -0,0 +1 @@ +export * from '@universal-ember/kolay-ui/samples/-private/index'; diff --git a/src/browser/private/samples.js b/src/browser/private/samples.js new file mode 100644 index 00000000..805ed9eb --- /dev/null +++ b/src/browser/private/samples.js @@ -0,0 +1 @@ +export * from '@universal-ember/kolay-ui/samples/-private/index'; diff --git a/src/browser/test-support.d.ts b/src/browser/test-support.d.ts index 3e715cca..ab075cd0 100644 --- a/src/browser/test-support.d.ts +++ b/src/browser/test-support.d.ts @@ -5,6 +5,6 @@ type Options = Parameters[1]; type NestedHooks = Parameters[1]>>[0]; -export function setupKolay(hooks: NestedHooks, config: () => Promise); +export function setupKolay(hooks: NestedHooks, config: () => Promise): void; export function selectGroup(context: object, groupName: string): void; diff --git a/src/browser/virtual/setup.d.ts b/src/browser/virtual/setup.d.ts index ec57f8c5..d52e59d9 100644 --- a/src/browser/virtual/setup.d.ts +++ b/src/browser/virtual/setup.d.ts @@ -1,3 +1,5 @@ +import type { Manifest } from '@universal-ember/kolay-ui'; + export function setupKolay( context: object, options: { diff --git a/src/plugins/api-docs/index.js b/src/plugins/api-docs/index.js index 3d255f66..af0c9f7c 100644 --- a/src/plugins/api-docs/index.js +++ b/src/plugins/api-docs/index.js @@ -35,7 +35,7 @@ export const apiDocs = (options) => { * @param {string} pkgName */ function getDest(pkgName) { - return `${options.dest ?? 'docs'}/${pkgName}.json`; + return `${options.dest ?? 'docs'}/${pkgName.replace('/', '__')}.json`; } return { diff --git a/src/plugins/api-docs/typedoc.js b/src/plugins/api-docs/typedoc.js index 729a8802..1ea3f3ea 100644 --- a/src/plugins/api-docs/typedoc.js +++ b/src/plugins/api-docs/typedoc.js @@ -1,7 +1,7 @@ import assert from 'node:assert'; import { writeFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; -import { join } from 'node:path'; +import { dirname, join } from 'node:path'; import { globby } from 'globby'; @@ -31,15 +31,24 @@ export async function generateTypeDocJSON({ packageName }) { const absoluteResolved = resolvedEntries.map((entry) => join(typeInfo.dir, entry)); const typedoc = await import('typedoc'); - const tmpTSConfigPath = `/tmp/kolay-typedoc-${packageName}.json`; + const tmpTSConfigPath = `/tmp/kolay-typedoc-${packageName.replace('/', '__').replace('@', 'at__')}.json`; const extendsTsConfig = require.resolve('@tsconfig/ember/tsconfig.json'); + const home = process.cwd(); + + const homeRequire = createRequire(home); + const tsConfig = { extends: extendsTsConfig, - include: [join(typeInfo.dir, '**/*')], + // include: [join(typeInfo.dir, '**/*')], + include: absoluteResolved.map((entry) => dirname(entry)), compilerOptions: { baseUrl: typeInfo.dir, noEmitOnError: false, + types: [ + homeRequire.resolve('ember-source/types/stable/index.d.ts'), + homeRequire.resolve('ember-modifier/index.d.ts'), + ], }, }; diff --git a/src/plugins/api-docs/types.ts b/src/plugins/api-docs/types.ts index ca04bc29..fe91acc7 100644 --- a/src/plugins/api-docs/types.ts +++ b/src/plugins/api-docs/types.ts @@ -1,12 +1,4 @@ export interface APIDocsOptions { - /** - * List of packages to generate api docs for - */ packages: string[]; - - /** - * Destination folder to place the api docs json files in. - * Defaults to "docs" - */ dest?: string | undefined; } diff --git a/src/plugins/combined.js b/src/plugins/combined.js index d88f6e53..71104388 100644 --- a/src/plugins/combined.js +++ b/src/plugins/combined.js @@ -4,13 +4,20 @@ import { apiDocs } from './api-docs/index.js'; import { markdownPages } from './markdown-pages/index.js'; import { setup } from './setup.js'; -export const combined = /* #__PURE__ */ createUnplugin( - /** - * @param {Parameters[0] & Parameters[0]} options - */ - (options) => [ +/** + * @typedef {import('./types.ts').Options} Options + */ + +/** + * + * @param {Options} options + */ +export function combinedPlugins(options) { + return [ setup(), apiDocs({ packages: options.packages, dest: options.dest }), markdownPages({ src: options.src, groups: options.groups, dest: options.dest }), - ] -); + ]; +} + +export const combined = /* #__PURE__ */ createUnplugin(combinedPlugins); diff --git a/src/plugins/index.d.ts b/src/plugins/index.d.ts new file mode 100644 index 00000000..2e7d3bf1 --- /dev/null +++ b/src/plugins/index.d.ts @@ -0,0 +1,4 @@ +export { combined as kolay } from './combined.js'; +export { gitRef } from './git-ref.js'; +export * as helpers from './helpers.js'; +export type { APIDocsOptions, MarkdownPagesOptions } from './types.ts'; diff --git a/src/plugins/markdown-pages/types.ts b/src/plugins/markdown-pages/types.ts index 75d998b0..1f068b07 100644 --- a/src/plugins/markdown-pages/types.ts +++ b/src/plugins/markdown-pages/types.ts @@ -6,38 +6,10 @@ export type Node = Page | Collection; export type GatheredDocs = Array<{ mdPath: string; config?: object }>; export interface MarkdownPagesOptions { - /** - * The source directory for where to look for files to include in the build and create the manifest from. - * This is relative to the CWD. - * Note that only md, json, and jsonc files are used. - * - * This option is the same as the one in `groups`, but is a shorthand for if - * you only have one set of docs with no configuration needed. - */ src?: string | undefined; - - /** - * Additional markdown sources to include - * These will be copied into your dist directory, and will be grouped by each entry's "name" property - */ groups: { - /** - * The name of the group - */ name: string; - /** - * The source directory for where to look for files to include in the build and create the manifest from. - * This is relative to the CWD. - * Note that only md, json, and jsonc files are used. - */ src: string; - - /** - * Only generate a manifest of directories. - * This ignores all of the files on disk, useful if you have many - * convention-based file names and some other means of enforcing that they all exist. - * (such as runtime testing) - */ onlyDirectories?: boolean; /** @@ -55,14 +27,6 @@ export interface MarkdownPagesOptions { exclude?: string[]; }[]; - /** - * The name of the file that is written. - * Defaults to 'manifest.json' - */ name?: string | undefined; - /** - * Where to place the manifest - * Defaults to 'docs' - */ dest?: string | undefined; } diff --git a/src/plugins/types.ts b/src/plugins/types.ts index 579c25f7..27611269 100644 --- a/src/plugins/types.ts +++ b/src/plugins/types.ts @@ -1,2 +1,52 @@ -export type { APIDocsOptions } from './api-docs/types.js'; -export type { MarkdownPagesOptions as CreateManifestOptions } from './markdown-pages/types.js'; +export interface Options { + /** + * The source directory for where to look for files to include in the build and create the manifest from. + * This is relative to the CWD. + * Note that only md, json, and jsonc files are used. + * + * This option is the same as the one in `groups`, but is a shorthand for if + * you only have one set of docs with no configuration needed. + */ + src?: string | undefined; + + /** + * Additional markdown sources to include + * These will be copied into your dist directory, and will be grouped by each entry's "name" property + */ + groups: { + /** + * The name of the group + */ + name: string; + /** + * The source directory for where to look for files to include in the build and create the manifest from. + * This is relative to the CWD. + * Note that only md, json, and jsonc files are used. + */ + src: string; + + /** + * Only generate a manifest of directories. + * This ignores all of the files on disk, useful if you have many + * convention-based file names and some other means of enforcing that they all exist. + * (such as runtime testing) + */ + onlyDirectories?: boolean; + }[]; + + /** + * List of packages to generate api docs for + */ + packages: string[]; + + /** + * The name of the file that is written. + * Defaults to 'manifest.json' + */ + name?: string | undefined; + /** + * Where to place the manifest + * Defaults to 'docs' + */ + dest?: string | undefined; +} diff --git a/tsconfig.json b/tsconfig.json index feee8e82..a055b388 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "extends": ["@tsconfig/strictest", "@tsconfig/node20"], - "include": ["src"], + "include": ["src/**/*"], "exclude": ["docs-app", "declarations", "ui"], "compilerOptions": { "allowImportingTsExtensions": true, diff --git a/tsconfig.typedoc.json b/tsconfig.typedoc.json new file mode 100644 index 00000000..d6141a2e --- /dev/null +++ b/tsconfig.typedoc.json @@ -0,0 +1,11 @@ +{ + "extends": "@tsconfig/ember", + "include": ["./declarations/**/*", "./src/browser/**/*"], + "compilerOptions": { + "baseUrl": ".", + "skipLibCheck": true, + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": false, + "types": ["ember-source/types"] + } +} diff --git a/typedoc.config.json b/typedoc.config.json new file mode 100644 index 00000000..f695d9c0 --- /dev/null +++ b/typedoc.config.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "tsconfig": "./tsconfig.typedoc.json", + "entryPoints": [ + "./declarations/index.d.ts", + "./declarations/vite.d.ts", + "./declarations/webpack.d.ts", + "./declarations/plugins/index.d.ts", + "./declarations/plugins/types.d.ts", + "./src/browser/components.d.ts", + "./src/browser/test-support.d.ts", + "./src/browser/private/samples.d.ts" + ], + "exclude": ["node_modules"], + "cleanOutputDir": true, + "compilerOptions": { + "noEmitOnError": false + }, + "out": "./dist-typedoc", + "json": "./dist-typedoc/typedoc.json", + "pretty": true, + "excludeInternal": false, + "skipErrorChecking": true, + "plugin": ["@zamiell/typedoc-plugin-not-exported"] +} diff --git a/ui/docs/docs/component-signature.md b/ui/docs/docs/component-signature.md index 1d7a3077..cf64ce40 100644 --- a/ui/docs/docs/component-signature.md +++ b/ui/docs/docs/component-signature.md @@ -6,12 +6,130 @@ This, along with the other API doc-related components, are powered by [TypeDoc]( ## API Reference -API Reference generated via: - -```hbs live no-shadow preview below +```hbs live no-shadow ``` + +## Supported Signatures + +
+ Separate Interface + +```gts +export interface SignatureA { + Element: HTMLDivElement; + Args: { + foo: number; + bar: string; + }; + Blocks: { + default: [first: number, second: string]; + namedBlockA: [first: typeof ClassA]; + namedBlockB: [boolean]; + }; +} +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ Inline + +```gts +export class ClassA extends Component<{ + Element: HTMLDivElement; + Args: { + foo: number; + bar: string; + }; + Blocks: { + default: [first: number, second: string]; + namedBlockA: [first: typeof ClassA]; + namedBlockB: [boolean]; + }; +}> {} +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ Reference (not currently supported) + +```gts +export class ClassB extends Component {} +``` + +```hbs live no-shadow + +``` + +
+ +
+ TemplateOnly w/ Reference (not currently supported) + +```gts +export const TemplateOnlyC: TOC = ; +``` + +```hbs live no-shadow + +``` + +
+ +
+ TemplateOnly w/ Inline + +```gts +export const TemplateOnlyD: TOC<{ + Element: HTMLDivElement; + Args: { + foo: number; + bar: string; + }; + Blocks: { + default: [first: number, second: string]; + namedBlockA: [first: typeof ClassA]; + namedBlockB: [boolean]; + }; +}> = ; +``` + +```hbs live no-shadow preview below + +``` + +
diff --git a/ui/docs/docs/helper-signature.md b/ui/docs/docs/helper-signature.md new file mode 100644 index 00000000..1ce3ed23 --- /dev/null +++ b/ui/docs/docs/helper-signature.md @@ -0,0 +1,144 @@ +# `` + +Render the docs generated from Comments, [JSDoc](https://jsdoc.app/), etc, specialized specifically for helpers and plain functions, which have a known signature format, consisting of `Args`, and `Return`. + +This, along with the other API doc-related components, are powered by [TypeDoc](https://typedoc.org/) and generated from declarations. + +## API Reference + +```hbs live no-shadow + +``` + +## Supported Signatures + +
+ Plain Function, JSDoc + +```ts +/** + * @param {number} first - the first argument + * @param {number} second - the second argument + * @return {number} the sum of the two values + */ +export function plainHelperA(first: number, second: number): number { + return first + second; +} +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ Plain Function, cast as HelperLike + +```ts +import type { HelperLike } from '@glint/template'; + +export const helperLikeB = ((...args: unknown[]) => { + /* ... */ +}) as unknown as HelperLike<{ + Args: { + Named: { optional?: boolean }; + Positional: [first: string, second?: string]; + }; + Return: string; +}>; +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ Plain Function, typescript + +```ts +export const plainHelperC = ( + a: number, + b: number, + options?: { optional?: boolean; required: boolean }, +) => { + /* ... */ + console.log(a, b, options); +}; +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ class-based classic Helper, inline Signature (not currently supported) + +```ts +export class ClassHelperD extends Helper<{ + Args: { + Named: { optional?: boolean }; + Positional: [first: string, second?: string]; + }; + Return: string; +}> { + /* ... */ +} +``` + +```hbs live no-shadow + +``` + +
+ +
+ class-based classic Helper, referenced Signature (not currently supported) + +```ts +interface ESignature { + Args: { + Named: { optional?: boolean }; + Positional: [first: string, second?: string]; + }; + Return: string; +} + +export class classHelperE extends Helper { + /* ... */ +} +``` + +```hbs live no-shadow + +``` + +
diff --git a/ui/docs/docs/modifier-signature.md b/ui/docs/docs/modifier-signature.md new file mode 100644 index 00000000..f5452f0b --- /dev/null +++ b/ui/docs/docs/modifier-signature.md @@ -0,0 +1,129 @@ +# `` + +Render the docs generated from Comments, [JSDoc](https://jsdoc.app/), etc, specialized specifically for element modifiers, which have a known signature format, consisting of `Args`, and `Element`. + +This, along with the other API doc-related components, are powered by [TypeDoc](https://typedoc.org/) and generated from declarations. + +## API Reference + +```hbs live no-shadow + +``` + +## Supported Signatures + +
+ Direct Interface + +```ts +export interface ModifierSignatureA { + Element: HTMLDivElement; + Args: { + Positional: [x: number, y: number]; + Named: { invert?: boolean }; + }; +} +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ function modifier, ModifierLike + +```ts +import { ModifierLike } from '@glint/template'; + +export const functionModifierC: ModifierLike<{ + Element: HTMLDivElement; + Args: { + Positional: [x: number, y: number]; + Named: { invert?: boolean }; + }; +}> = modifier( + ( + element: HTMLDivElement, + positional: [x: number, y: number], + named: { invert?: boolean }, + ) => { + /* ... */ + }, +); +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ function modifier, inline signature (not currently supported) + +```ts +export const functionModifierA = modifier<{ + Element: HTMLDivElement; + Args: { + Positional: [x: number, y: number]; + Named: { invert?: boolean }; + }; +}>( + ( + element: HTMLDivElement, + positional: [x: number, y: number], + named: { invert?: boolean }, + ) => { + /* ... */ + }, +); +``` + +```hbs live no-shadow preview below + +``` + +
+ +
+ function modifier, implicit signature (not currentnly supported) + +```ts +export const functionModifierB = modifier( + ( + element: HTMLDivElement, + positional: [x: number, y: number], + named: { invert?: boolean }, + ) => { + /* ... */ + }, +); +``` + +```hbs live no-shadow preview below + +``` + +
diff --git a/ui/package.json b/ui/package.json index 1bc87ee4..66372d8c 100644 --- a/ui/package.json +++ b/ui/package.json @@ -62,6 +62,7 @@ "@types/qunit": "^2.19.10", "babel-plugin-ember-template-compilation": "^2.2.1", "concurrently": "^8.2.2", + "ember-modifier": "^4.1.0", "ember-repl": "^4.1.1", "ember-source": "~5.7.0", "ember-template-lint": "^5.13.0", @@ -71,7 +72,7 @@ "eslint-plugin-n": "^16.4.0", "eslint-plugin-prettier": "^5.0.1", "execa": "^8.0.1", - "fix-bad-declaration-output": "^1.1.2", + "fix-bad-declaration-output": "^1.1.4", "prettier": "^3.1.1", "prettier-plugin-ember-template-tag": "^2.0.0", "qunit": "^2.20.0", diff --git a/ui/src/components/page-nav.gts b/ui/src/components/page-nav.gts index 1cd906fa..174ac4c8 100644 --- a/ui/src/components/page-nav.gts +++ b/ui/src/components/page-nav.gts @@ -29,7 +29,7 @@ export class PageNav extends Component<{ * ```gjs * import { PageNav } from 'kolay/components'; * - * function toSentenceCase(name) { /* ... \*\/ } + * function toSentenceCase(name) { /* ... *\/ } * *