Commit Graph
38 Commits
Author SHA1 Message Date
Vinta ChenandClaude 77b1b70df5 fix: hide use-case and page tags that repeat the group heading
On section and subcategory pages, every row repeated its use case and current page as tags (and as the label under the name on phones), right under a heading that already said the same thing. They are now hidden in editorial order and shown again when a column sort flattens the groups.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-27 02:05:18 +08:00
Vinta ChenandClaude ef00fe3adb fix: restore hidden group headings when navigating to a jump link
After sorting by a column, or while a search hid a group, category page group headings stayed hidden, so the header's jump links (and any use-case heading link) pointed at a hidden element and did nothing.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-27 02:04:41 +08:00
Vinta ChenandClaude 62a4e7c4e5 fix: make tags link to category pages instead of filtering in place
Clicking a category or group tag filtered the homepage table in place while rewriting the address bar to the category URL, so one URL rendered two different pages and readers never reached category pages with their intros and guides; category pages also showed a redundant self-referential filter bar.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-27 00:34:07 +08:00
Vinta ChenandClaude 2b9469c0ae feat: group category page rows by use case, restructure intro
Category pages sorted rows by downloads, which buried editorial leads (the Django ORM showed as row 7 of 7, tkinter as 14 of 14) against CONTRIBUTING.md's "position is the marker"; the full intro in the hero pushed the table 2.5 screens down on a phone; and every page repeated the same "Search every project in one place" H2.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-26 23:33:57 +08:00
Vinta ChenandClaude d3fec1f7fa feat: default-sort the website table by downloads per month
Entries with a download count now sort first (descending), with
stars, then Built-in, then name as fallback tiers for entries that
lack a count. main.js mirrors this in its default activeSort, clean
URL check, and third-click reset target. Sorting by stars remains one
header click away.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 19:15:21 +08:00
Vinta ChenandClaude cc804b1de2 feat: add Downloads/Month column to website table
Sourced from website/data/pypi_downloads.tsv the same way
github_stars.json feeds the stars column. The new sortable column
sits between GitHub Stars and Last Commit on the homepage and
category pages, formatted with thousands separators like stars, with
an em dash when no PyPI data exists. Rows are matched by normalized
README display name; Built-in entries never show counts since
same-named PyPI packages are stdlib backports (e.g. the asyncio
package).

Below 960px the column hides and the count moves into the expand
row, mirroring the existing Last Commit treatment. main.js gains the
downloads sort branch and URL param.

The deploy workflow fetches the TSV via the new
make fetch_pypi_downloads target with a daily actions/cache
fallback, mirroring the stars fetch, but non-fatal: the column
degrades to dashes when the fetch fails, unlike stars which the
build requires.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 17:52:04 +08:00
Vinta ChenandClaude 9de86ea785 feat(website): append #library-index to tag links on non-index pages
Tag clicks on category/other pages now land with the results section
scrolled into view.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 18:45:09 +08:00
Vinta ChenandClaude fc8d1ba35e feat(website): show desc-row on index page when a filter is active
On category pages desc-rows are always visible. On the index page they
were always hidden. Now they become visible whenever a tag/category
filter is applied, giving filtered results the same richness as category
pages.

Also tightens two related CSS rules: border-bottom suppression only
fires when the adjacent desc-row is actually visible, and the expand-row
description is hidden while the desc-row is already showing to avoid
duplicate text.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 13:08:27 +08:00
Vinta ChenandClaude 1468ae78ff feat(website): show project description as always-visible desc-row on category pages
Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 12:47:17 +08:00
Vinta ChenandClaude ee01a0bade refactor(website): extract render_category, replace slugify filter with filter_urls map
- Extract render_category() helper to deduplicate the three category/group/builtin
  rendering blocks in build.py
- Replace synthetic dict literals with synthetic_category() helper
- Rewrite subcategory rendering to avoid O(n²) loop using precomputed dicts
- Pass filter_urls (not just JSON) to templates so Jinja can look up group URLs
  directly instead of applying the slugify filter at render time
- Remove slugify from env.filters (no longer used in templates)
- Replace isIndexPage() wrapper with isIndexDocument constant in main.js
- Fix: call applyFilters() on page load when activeFilter is set
- Remove dead else branch in tag click handler (category pages with no URL)
- Switch .hero-category-links from CSS columns to CSS grid for more even layout
- Remove max-width cap on .category-subtitle

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 11:38:22 +08:00
Vinta ChenandClaude b82a254a09 fix(website): clear filter lands at /#library-index on category pages
Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 09:03:25 +08:00
Vinta ChenandClaude d64b47b910 feat(website): mirror index layout on category pages
Add search input, filter chips, no-results block, and back-to-top
button to category/group/subcategory pages. Pass filter_urls_json to
all page types so tag-chip navigation works site-wide. Fix JS so
filter-clear and no-results-clear redirect to / on non-index pages
instead of trying to filter a non-existent local table. Remove the
now-redundant .category-results CSS overrides.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 08:26:37 +08:00
Vinta Chen 8e72e8af8f feat(website): strip #library-index from URL after All projects click
The "All projects" link in the category-page topbar pointed to
/#library-index so the browser would scroll to the library section on
arrival. The hash stayed in the URL, which looked like an internal anchor
state rather than a clean homepage URL.

On homepage load, if the hash is #library-index, scroll to the section
explicitly and use history.replaceState to drop the hash from the URL.
The scrollIntoView call covers the case where the script runs before the
browser's native anchor scroll, since replaceState removes the hash the
browser would have used.
2026-05-03 07:56:54 +08:00
Vinta ChenandClaude Opus 4.7 b0136ac266 feat(website): switch index filter URLs from querystring to path
Tag clicks on / pushState a category/group/subcategory path; on static
pages they fully navigate. Search and sort stay in querystring. Built-in
source tag has no data-url and stays as an in-page filter. The
isIndexDocument flag is captured at load time so toggling on the index
keeps working after pushState changes location.pathname.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:49:41 +08:00
Vinta Chen e11afd1730 feat(website): generate static category pages 2026-05-02 23:31:08 +08:00
Vinta ChenandClaude 9425ab5921 refactor(js): replace var with const for immutable bindings
Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:37:35 +08:00
Vinta ChenandClaude 7fdf6ab307 refactor(js): hoist repeated queries, drop stale comments, tighten collapseAll scope
- Hoist reducedMotion and sortHeaders to module scope to avoid repeated
  DOM queries on every call
- collapseAll now queries within tbody instead of the full document
- Replace indexOf with includes for tag filtering
- Remove null check on activeSort (always initialized)
- Drop inline section comments that just restate the code

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:34:20 +08:00
Vinta ChenandClaude 57a5b432f6 fix(js): drop legacy category/group URL param aliases for filter
Only the canonical 'filter' query param is supported. The 'category'
and 'group' aliases were never documented and silently accepted wrong
spellings; removing them prevents hidden coupling to old URL shapes.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:19:42 +08:00
Vinta ChenandClaude d7a7e68475 refactor(js): simplify filter state to a plain string
Replace the { type, value } filter object with a plain string value.
Merge data-cats and data-groups row attributes into a single data-tags
attribute. Drop data-type from tag buttons. Consolidate category/group
URL params into a single filter param, keeping backward-compat fallback.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:18:26 +08:00
Vinta ChenandClaude 3b69697504 refactor(js): extract getScrollBehavior() helper to deduplicate prefers-reduced-motion check
The same matchMedia query was inlined twice (hero scroll and back-to-top).
Extracted into a shared helper. Also renamed loop variable and reformatted
a chained querySelector call for readability. No behavior change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:12:10 +08:00
Vinta ChenandClaude eb5b37daf5 feat(ux): smooth-scroll hero CTA without updating URL hash
Add a data-scroll-to attribute to the hero 'Browse the List' anchor
and a JS handler that calls scrollIntoView instead of letting the
browser follow the href, so the URL hash is never written.
Respects prefers-reduced-motion.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 13:08:22 +08:00
Vinta ChenandClaude 7df2e36334 feat(mobile): show last commit date in expand row on mobile
Add an expand-commit span inside the expand row that displays the last
commit date. Hidden on desktop, visible only on mobile (max-width: 960px)
via media query, mirroring the commit column that appears in the full
table. Relative time formatting is applied via JS on page load.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 12:56:04 +08:00
Vinta ChenandClaude d58c915a0b fix(a11y): respect prefers-reduced-motion in back-to-top scroll
Swap the hardcoded 'smooth' scroll behavior for a runtime check so users
who have enabled reduced-motion in their OS get instant (auto) scrolling
instead of the animated kind.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-24 12:37:36 +08:00
Vinta ChenandClaude 028c642a8e refactor(js): replace var with let/const and use double quotes
Modernize variable declarations and string literals in main.js for
consistency and to signal immutability intent. Pure style change with
no behavioral differences.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-23 01:34:33 +08:00
Vinta ChenandClaude 80a5596b11 perf(hero): pause animations when hero scrolls out of view
Uses IntersectionObserver to toggle an .offscreen class on the hero
element, which sets animation-play-state: paused on the sheen, noise,
and scroll-cue animations. Avoids unnecessary GPU work while the hero
is not visible.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 16:13:08 +08:00
Vinta ChenandClaude 4bb9c1240b fix(website): accessibility and defensive layout improvements
- Add aria-sort attributes to table header on sort state changes
- Replace .table-wrap:focus outline:none with focus-visible outline
- Move noscript message above the fold into main, before content
- Upgrade hero-topbar div to nav with aria-label for landmark semantics
- Remove role=button from tr elements (invalid ARIA on native elements)
- Fix back-to-top button label and text (was labelled 'Back to search')
- Switch font-size from 16px to 100% to respect user browser preferences
- Add overflow-wrap and word-break to .col-name and description cells

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 16:10:14 +08:00
Vinta ChenandClaude 9d89df3e73 fix: back-to-top button scrolls to search input and focuses it
When results are visible, clicking the button previously scrolled to
the results section. It now targets the search input instead, scrolls
it into view centered, and focuses it so the user can immediately type
a new query. Button label updated from 'Top' to 'Search' to reflect
the new destination.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 15:31:04 +08:00
Vinta ChenandClaude 97f18d295f feat: add clear action to no-results message
When a search or filter yields no results, the message now includes
an inline button that resets both the search input and the active
filter. Improves discoverability and reduces dead-end frustration.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 15:28:25 +08:00
Vinta Chen 3e7ff12614 Fix sticky top button behavior 2026-03-22 14:17:17 +08:00
Vinta Chen 7d1d9e0af3 feat: redesign website homepage 2026-03-22 07:54:14 +08:00
Vinta ChenandClaude 49fafd3497 refactor(website): move back-to-top button into sticky table header
Replaces the fixed-position floating button with an inline button
inside the last column of the sticky table header. Removes the hidden
attribute toggle and float positioning in favour of opacity/pointer-
events toggling, keeping the visibility logic intact.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 02:28:16 +08:00
Vinta ChenandClaude Opus 4.6 1d05e98537 fix(website): make back-to-top scroll instant instead of smooth
The smooth scroll behavior felt sluggish on a 505-row page. Instant
jump is more responsive for a utility button.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 02:24:26 +08:00
Vinta ChenandClaude b6bcb2c7e3 feat(website): add entrance animations and CSS-based filter bar visibility
Replace hidden attribute on filter-bar with opacity/transform transition
driven by a .visible class, allowing smooth fade-in/slide-down when a
filter is active. Add staggered hero-in keyframe animations to the page
title, subtitle, action buttons, and search box. Polish sortable table
headers with color transition on hover and active states.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 02:22:07 +08:00
Vinta ChenandClaude 7aeb8fbb65 feat(website): add back-to-top button
Adds a fixed-position button that fades in after scrolling 600px and
smoothly scrolls back to the top on click. Hidden by default via the
HTML hidden attribute so noscript users never see it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 02:17:57 +08:00
Vinta ChenandClaude 3d9c2ae507 perf(website): cache sort values and batch DOM appends in sortRows
Calling getSortValue inside the comparator ran DOM queries on every
comparison (O(n log n) reads). Hoisting into a forEach beforehand reduces
that to O(n). Batching row appends through a DocumentFragment also avoids
repeated reflows during table reorder.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 01:32:21 +08:00
Vinta ChenandClaude 18011f86f3 feat: merge duplicate entries across multiple categories
Entries appearing in more than one category were previously emitted as
separate rows. They are now deduplicated in build.py by URL, collecting
all category and group names into lists.

The template encodes those lists as pipe-delimited data attributes
(data-cats, data-groups) and renders a tag button per category.
The JS filter is updated to split on '||' and check for membership,
so clicking any category tag correctly shows the merged row.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-20 17:02:22 +08:00
Vinta ChenandClaude 280f250ce0 feat: migrate README parser to markdown-it-py and refresh website
Switch readme_parser.py from regex-based parsing to markdown-it-py for
more robust and maintainable Markdown AST traversal. Update build pipeline,
templates, styles, and JS to support the new parser output. Refresh GitHub
stars data and update tests to match new parser behavior.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-18 20:33:36 +08:00
Vinta ChenandClaude 177183d9bd add custom website build system
Replaces MkDocs with a bespoke Python site generator using Jinja2 templates
and Markdown. Adds uv for dependency management, GitHub Actions workflow for
deployment, and Makefile targets for local development (fetch_stars, build,
preview, deploy).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-18 13:48:49 +08:00