Skip to content

Commit e987b73

Browse files
Merge pull request #573 from universal-ember/nvp/572/extract-heading-utility
Extract the heading utility to its own package
2 parents 8485e72 + a4344e5 commit e987b73

File tree

26 files changed

+1001
-252
lines changed

26 files changed

+1001
-252
lines changed

.github/workflows/publish.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
- uses: actions/checkout@v5
2727
with:
2828
fetch-depth: 0
29-
ref: 'main'
29+
ref: "main"
3030
# This will only cause the `check-plan` job to have a result of `success`
3131
# when the .release-plan.json file was changed on the last commit. This
3232
# plus the fact that this action only runs on main will be enough of a guard
@@ -47,9 +47,9 @@ jobs:
4747
- uses: wyvox/action-setup-pnpm@v3
4848
with:
4949
# This creates an .npmrc that reads the NODE_AUTH_TOKEN environment variable
50-
node-registry-url: 'https://registry.npmjs.org'
50+
node-registry-url: "https://registry.npmjs.org"
51+
- run: npm install -g npm@latest # ensure that the globally installed npm is new enough to support OIDC
5152
- name: npm publish
52-
run: pnpm release-plan publish
53+
run: NPM_CONFIG_PROVENANCE=true pnpm release-plan publish
5354
env:
5455
GITHUB_AUTH: ${{ secrets.GITHUB_TOKEN }}
55-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

CONTRIBUTING.md

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,22 @@
11
# How To Contribute
22

3-
## Installation
3+
## Preparing for Dev
44

55
* `git clone <repository-url>`
66
* `cd ember-primitives`
77
* `pnpm install`
8+
* `pnpm build`
9+
- builds all libraries
10+
- if working in a specific library, each package will have its own build script so that you only need to build what you change
811

912
## Linting
1013

1114
* `pnpm lint`
1215
* `pnpm lint:fix`
1316

14-
## Building the addon
15-
16-
* `cd ember-primitives`
17-
* `pnpm build`
18-
1917
## Running tests
2018

21-
* `cd test-app`
22-
* `pnpm test` – Runs the test suite on the current Ember version
23-
* `pnpm test:watch` – Runs the test suite in "watch mode"
24-
25-
## Running the test application
26-
2719
* `cd test-app`
2820
* `pnpm start`
29-
* Visit the test application at [http://localhost:4200](http://localhost:4200).
21+
* visit `/tests` at the printed URL in the terminal
3022

31-
For more information on using ember-cli, visit [https://cli.emberjs.com/release/](https://cli.emberjs.com/release/).

config/ember-cli-update.json

Lines changed: 0 additions & 20 deletions
This file was deleted.

docs-app/app/routes/application.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export default class Application extends Route {
6666
'ember-focus-trap/modifiers/focus-trap': import('ember-focus-trap/modifiers/focus-trap'),
6767
// @ts-expect-error - no types provided
6868
'ember-focus-trap': import('ember-focus-trap'),
69+
'ember-element-helper': import('ember-element-helper'),
70+
'which-heading-do-i-need': import('which-heading-do-i-need'),
6971

7072
// utility
7173
'@ember/test-waiters': import('@ember/test-waiters'),

docs-app/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"change-case": "^5.4.4",
3434
"content-tag": "^3.1.3",
3535
"decorator-transforms": "^2.3.0",
36+
"ember-element-helper": "^0.8.8",
3637
"ember-focus-trap": "^1.1.0",
3738
"ember-mobile-menu": "^5.1.0",
3839
"ember-modifier": "^4.2.2",
@@ -49,7 +50,8 @@
4950
"reactiveweb": "^1.8.0",
5051
"shiki": "^3.14.0",
5152
"should-handle-link": "^1.2.2",
52-
"tracked-built-ins": "^4.0.0"
53+
"tracked-built-ins": "^4.0.0",
54+
"which-heading-do-i-need": "workspace:*"
5355
},
5456
"dependenciesMeta": {
5557
"ember-primitives": {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"title": "Heading Level 📦"
3+
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Heading Level 📦
2+
3+
Used by the [`<Heading>`](/3-ui/heading.md) component, and available for use in all frameworks (React, Svelte, Ember, etc). `getSectionHeadingLevel` is the primary function exported by this utility library and correctly determines which of the `<h1>` through `<h6>` [Section Heading][mdn-h] elements to use, where the **level** is determined _automatically_ based on how the DOM has rendered.
4+
5+
This enables distributed teams to correctly produce appropriate section heading levels without knowledge of where their work will be rendered in the overall document -- and extra helpful for design systems teams where is _is not possible_ to know the appropriate heading level ahead of time.
6+
7+
[mdn-h]: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/Heading_Elements
8+
9+
## Install
10+
11+
```bash
12+
pnpm add which-heading-do-i-need
13+
```
14+
15+
## Usage
16+
17+
In your app, you can use any of `<section>`, `<article>`, and `<aside>` elements to denote when the [_Section Heading_][mdn-h] element should change its level.
18+
Note that this demo starts with `h3`, because this docs page already has an `h1`, and _this_ section (Usage) uses an `h2`.
19+
20+
In this example, we dynamically create a TextNode and Element, where, since the TextNode is rendered first, the Element can traverse from the TextNode up the existing DOM to determine which h-level to use. We expect an `h3` and `h4` in the demo, since this is the `Usage` section, which has a section heading of `h2`.
21+
22+
<section class="featured-demo">
23+
24+
```gjs live preview
25+
import Component from "@glimmer/component";
26+
import { element } from "ember-element-helper";
27+
import { getSectionHeadingLevel } from "which-heading-do-i-need";
28+
29+
class Heading extends Component {
30+
constructor(owner, args) {
31+
super(owner, args);
32+
33+
this.markerNode = document.createTextNode("");
34+
}
35+
36+
get hLevel() {
37+
return `h${getSectionHeadingLevel(this.markerNode)}`;
38+
}
39+
40+
<template>
41+
{{this.markerNode}}
42+
43+
{{#let (element this.hLevel) as |El|}}
44+
<El ...attributes>
45+
{{yield}}
46+
</El>
47+
{{/let}}
48+
</template>
49+
}
50+
51+
// Output for demo uses the above
52+
<template>
53+
<Heading>hello there</Heading>
54+
55+
<section>
56+
<Heading>hello there</Heading>
57+
58+
</section>
59+
60+
<style>
61+
h1, h2, h3, h4, h5, h6 { margin: 0; }
62+
63+
h1::before, h2::before, h3::before, h4::before, h5::before, h6::before {
64+
position: absolute;
65+
margin-left: -1.2em;
66+
font-size: 0.7em;
67+
text-align: right;
68+
opacity: 0.8;
69+
}
70+
71+
h1 { font-size: 2.5rem; }
72+
h2 { font-size: 2.25rem; }
73+
h3 { font-size: 2rem; }
74+
h4 { font-size: 1.5rem; }
75+
h5 { font-size: 1.25rem; }
76+
h6 { font-size: 1rem; }
77+
a { color: white; }
78+
79+
h1::before { content: 'h1'; }
80+
h2::before { content: 'h2'; }
81+
h3::before { content: 'h3'; }
82+
h4::before { content: 'h4'; }
83+
h5::before { content: 'h5'; }
84+
h6::before { content: 'h6'; }
85+
86+
article, section, aside, nav, main, footer {
87+
border: 1px dotted;
88+
padding: 0.25rem 1.5rem;
89+
padding-left: 2rem;
90+
padding-right: 0.5rem;
91+
position: relative;
92+
93+
&::before {
94+
position: absolute;
95+
right: 0.5rem;
96+
top: -1rem;
97+
font-size: 0.7rem;
98+
text-align: right;
99+
opacity: 0.8;
100+
}
101+
}
102+
103+
section, article {
104+
display: flex;
105+
flex-direction: column;
106+
gap: 0.75rem;
107+
}
108+
109+
article::before { content: '<article>'; }
110+
section::before { content: '<section>'; }
111+
aside::before { content: '<aside>'; }
112+
nav::before { content: '<nav>'; }
113+
main::before { content: '<main>'; }
114+
footer::before { content: '<footer>'; }
115+
116+
main {
117+
display: grid;
118+
gap: 2.5rem;
119+
grid-template-columns: max-content 1fr;
120+
grid-template-areas:
121+
"heading heading"
122+
"nav content"
123+
"nav content"
124+
"nav content";
125+
126+
}
127+
128+
>:first-child { grid-area: heading; }
129+
nav { grid-area: nav; }
130+
article { grid-area: content; }
131+
132+
</style>
133+
</template>
134+
```
135+
136+
</section>
137+
138+
## API Reference
139+
140+
```gjs live no-shadow
141+
import { APIDocs } from 'kolay';
142+
143+
<template>
144+
<APIDocs @package="which-heading-do-i-need" @module="declarations/index" @name="getSectionHeadingLevel" />
145+
</template>
146+
```

ember-primitives/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"form-data-utils": "^0.6.0",
4242
"reactiveweb": "^1.8.0",
4343
"should-handle-link": "^1.2.2",
44+
"which-heading-do-i-need": "workspace:*",
4445
"tabster": "^8.5.5",
4546
"tracked-built-ins": "^4.0.0",
4647
"tracked-toolbox": "^2.0.0"

0 commit comments

Comments
 (0)