Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Bug report
description: Something does not work, or does not work the way the docs say.
labels: ['bug']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time. You do not need to diagnose the problem — "I expected X and
got Y" is a complete report. Fill in what you know and leave the rest blank.

- type: textarea
id: what-happened
attributes:
label: What happened?
description: What did you expect, and what did you get instead?
placeholder: |
I set columnWidth="260" and expected four columns on a 1200px screen, but got three.
validations:
required: true

- type: input
id: reproduction
attributes:
label: Reproduction
description: >
A StackBlitz is the fastest way to get this fixed. Fork the starter and break it:
https://stackblitz.com/github/MeAkib/masonry-angular/tree/main/examples/stackblitz
If that is not practical, paste the relevant template and component code below instead.
placeholder: https://stackblitz.com/edit/...

- type: textarea
id: code
attributes:
label: Code
description: The template and options you used. Formatted automatically, no backticks needed.
render: html

- type: input
id: versions
attributes:
label: Versions
description: Output of `npx ng version`, or just the Angular and masonry-angular versions.
placeholder: Angular 19.2.0, masonry-angular 0.0.1
validations:
required: true

- type: input
id: browser
attributes:
label: Browser and OS
placeholder: Safari 26.4 on macOS, Chrome 141 on Windows, Chrome on Android 15

- type: checkboxes
id: context
attributes:
label: Anything that applies
options:
- label: It happens with server-side rendering (SSR)
- label: It happens only after items are added, removed or reordered
- label: It happens only at certain window sizes
- label: 'I am using `native: true`'
- label: I found a workaround (please describe it above — the workaround is a clue)
11 changes: 11 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
blank_issues_enabled: true
contact_links:
- name: Getting started guide
url: https://github.com/MeAkib/masonry-angular/blob/main/projects/masonry-angular/GETTING-STARTED.md
about: Install to a responsive gallery, with the common mistakes called out.
- name: Full reference
url: https://github.com/MeAkib/masonry-angular/blob/main/projects/masonry-angular/DOCS.md
about: Every option, spans, stamps, testing, and migrating from ngx-masonry.
- name: Try it in StackBlitz
url: https://stackblitz.com/github/MeAkib/masonry-angular/tree/main/examples/stackblitz
about: A running grid you can fork to reproduce a problem.
45 changes: 45 additions & 0 deletions .github/ISSUE_TEMPLATE/experience_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Experience report
description: You used it, or tested it somewhere new. Nothing is necessarily broken.
labels: ['feedback']
body:
- type: markdown
attributes:
value: |
At version 0.0.1 this is the most useful thing anyone can file. It does not have to be a
bug, and it does not have to be polished.

- type: textarea
id: what
attributes:
label: What did you build or test?
placeholder: |
A photo gallery in a side panel, Angular 20, Safari 26.4 on macOS.
validations:
required: true

- type: textarea
id: friction
attributes:
label: What was harder than it should have been?
description: >
Anything you had to read twice, guess at, or find by trial and error. Docs that did not
answer your question count. So does an option whose name did not mean what you assumed.

- type: textarea
id: worked
attributes:
label: What worked well? (optional)
description: Useful for knowing what not to change.

- type: checkboxes
id: coverage
attributes:
label: If you tested somewhere we have not, tick it
options:
- label: Safari
- label: Firefox
- label: A mobile browser
- label: Right-to-left layout
- label: Screen reader or keyboard-only navigation
- label: A low-end or older device
- label: 'Native CSS masonry (`display: grid-lanes`) in a browser that supports it'
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Feature request
description: Something the library cannot do yet.
labels: ['enhancement']
body:
- type: markdown
attributes:
value: |
Open one of these before writing code. Not for permission — sometimes the answer is
"that already works, here is how", which saves you the work.

- type: textarea
id: problem
attributes:
label: What are you trying to build?
description: >
Describe the situation rather than the API you have in mind. The underlying problem often
has a solution the requested feature would not have covered.
placeholder: |
I have a feed where new posts arrive at the top while the user is scrolled down, and ...
validations:
required: true

- type: textarea
id: workaround
attributes:
label: What have you tried?
description: Which options or approaches did you look at, and where did they fall short?

- type: textarea
id: proposal
attributes:
label: What would it look like? (optional)
description: An API sketch, if you have one in mind.
render: html

- type: markdown
attributes:
value: |
One thing worth knowing: every byte ships to everyone who installs this, so a new option
has to earn its size. A feature that can be built on top of the existing API, or lives in
your own code, is usually the better outcome — and if that is the answer, the issue will
explain how.
24 changes: 24 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!--
Thanks for this. Nothing below is mandatory — delete what does not apply.
A draft PR with a question attached is welcome too.
-->

## What does this change?

<!-- What problem does it solve, not only what the code does. -->

## How to see it

<!-- Steps to reproduce the old behaviour, or the example/test that covers the new one. -->

## Checks

- [ ] `npm test` passes
- [ ] `npm run format` run on the files I touched
- [ ] Added a test, if this fixes a bug — one that fails before the change and passes after
- [ ] `npm run verify:compat`, if I changed anything public (builds a real app on Angular 17–22)

<!--
If a box is unticked because you were not sure how, say so — that is a normal thing to
sort out in review, not a reason to hold the PR back.
-->
146 changes: 146 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: CI

# Everything here runs on every pull request, and must pass before merging.
# The slow Angular-version matrix lives in compat.yml, which does not run here.
on:
pull_request:
push:
branches: [main]

# A new push to a branch makes the previous run irrelevant.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# Formatting, unit tests, and both builds. Fast enough to be the gate.
verify:
name: Tests and build
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci

- name: Formatting
run: npx prettier --check "projects/**/*.{ts,html,css,json}"

- name: Unit tests
run: npm test

- name: Build the library
run: npm run build:lib

# Also exercises the command Vercel runs, and the llms.txt sync step.
- name: Build the demo
run: npm run build

- name: Bundle size
run: npm run size

# The server-rendering claim, checked on a real server rather than in jsdom —
# which defines `window` and so could never catch a stray browser call.
ssr:
name: Server rendering
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run verify:ssr

# Native CSS masonry in a real browser engine. Playwright is deliberately not
# a dependency of the package, so it is installed here instead.
native:
name: Native CSS masonry
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build:lib

# Both are needed: the npm package, which the script imports, and the
# browser binary. Installing only the browser leaves the script unable to
# import playwright — and it would then skip and exit 0.
- name: Install Playwright and Chromium
run: |
npm i --no-save playwright
npx playwright install --with-deps chromium

# The script exits 0 when it cannot run, which is right on a contributor's
# machine and wrong here: a skipped check that reports success is worse
# than no check. A missing browser is CI's fault and fails the job. A
# Chromium that simply has no masonry implementation is not, so that one
# only warns.
- name: Native CSS masonry
run: |
set -o pipefail
npm run verify:native 2>&1 | tee native.log
if grep -qE 'skipped: (playwright is not installed|could not launch)' native.log; then
echo "::error::verify:native could not run. CI must exercise the native path, not skip it."
exit 1
fi
if grep -q 'skipped:' native.log; then
echo "::warning::This Chromium has no masonry implementation, so the native path went unchecked."
fi

# Compiles the examples in the README, the getting-started guide and llms.txt.
# Two examples once shipped to npm that could not compile at all; this is what
# stops that happening again.
docs:
name: Documentation examples
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run verify:docs

# One check to require in the branch protection rule, so that adding or
# renaming a job above never means editing repository settings — and a job
# that silently stops running can never leave a rule waiting on a name that
# no longer reports.
#
# `always()` is what makes it work: without it this job would itself be
# skipped when something upstream fails, and a skipped required check blocks
# the pull request rather than failing it.
gate:
name: All checks passed
if: always()
needs: [verify, ssr, native, docs]
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- name: Check the results
run: |
echo "verify: ${{ needs.verify.result }}"
echo "ssr: ${{ needs.ssr.result }}"
echo "native: ${{ needs.native.result }}"
echo "docs: ${{ needs.docs.result }}"
if [ "${{ contains(needs.*.result, 'failure') }}" = "true" ] \
|| [ "${{ contains(needs.*.result, 'cancelled') }}" = "true" ] \
|| [ "${{ contains(needs.*.result, 'skipped') }}" = "true" ]; then
echo "::error::At least one check did not pass."
exit 1
fi
echo "All checks passed."
46 changes: 46 additions & 0 deletions .github/workflows/compat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Angular compatibility

# `npm run verify:compat` installs a full Angular toolchain and builds a real
# application once per supported major. That is minutes per version, which is
# too slow to sit in front of every pull request — but it is the only thing that
# actually tests the peer range, because the Angular linker runs during a
# consumer's build and nowhere else.
#
# So it runs when the promise itself could have changed, on a weekly schedule to
# catch a new Angular release breaking us, and on demand.
on:
pull_request:
paths:
- 'projects/masonry-angular/package.json' # the peer range itself
- 'projects/masonry-angular/src/**' # anything a consumer's build compiles
- 'scripts/verify-compat.mjs'
schedule:
- cron: '0 6 * * 1' # Mondays, 06:00 UTC
workflow_dispatch:
inputs:
majors:
description: 'Majors to check, space separated (blank = all)'
required: false
default: ''

concurrency:
group: compat-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
compat:
name: Build a real app on each supported major
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
with:
node-version: 24
cache: npm
- run: npm ci
- name: verify:compat
run: npm run verify:compat -- ${{ github.event.inputs.majors }}
2 changes: 1 addition & 1 deletion projects/demo/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ h3 {
/* ---- Shared example chrome ------------------------------------------------ */

.lede {
max-width: 68ch;
/* max-width: 68ch; */
margin: 0 0 22px;
color: var(--muted);
line-height: 1.6;
Expand Down
Loading