Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
30c5cb5
Add code quality tools, lint configs, node deps, and PHP requirement
mike-sheppard May 1, 2026
e867003
Add support for icon sets/groupings + multiple theme path locations
mike-sheppard May 1, 2026
18790cc
Update README + move changelog to dedicated file and update it with l…
mike-sheppard May 1, 2026
ad686be
Add tests for all new methods
mike-sheppard May 1, 2026
2b8c42d
Use Mago + oxfmt for linting/formatting, much neater than WP rules
mike-sheppard May 1, 2026
0c5af06
Update Mago format, keep function/class braces same line
mike-sheppard May 1, 2026
302b96d
Update screenshot preview with groupings/sets
mike-sheppard May 1, 2026
47716f8
Bump phpstan to lvl 9 + fix issues
mike-sheppard May 1, 2026
d251416
Use PHPStan level 9 + fixes + update docs
mike-sheppard May 1, 2026
77416ed
Create css-customisation.md
mike-sheppard May 1, 2026
10aaaa5
Remove CSS customisation docs, not keen on support it across versions…
mike-sheppard May 1, 2026
6e83378
Drop dev-only version override; release version comes from git tag
mike-sheppard May 1, 2026
b845f43
Add ACF field option to limit to allowed icon sets
mike-sheppard May 1, 2026
bb0fbe0
Add tests + update changelog
mike-sheppard May 1, 2026
6e93953
Format tests as well
mike-sheppard May 1, 2026
b1f309c
Regenerate composer.lock + reformat mago.toml so CI checks pass
mike-sheppard May 1, 2026
292650c
Fixes for Copilot review: init guard, escape urls, sanitise keys, con…
mike-sheppard May 1, 2026
6509e3a
Pin platform PHP to 8.1 in composer config so the lock resolves to PH…
mike-sheppard May 1, 2026
b44cb1c
Add tearDown filter cleanup to keep tests isolated; drop the no-op re…
mike-sheppard May 1, 2026
64c2bff
Address Copilot review: fall back to aria-label when group has no hea…
mike-sheppard May 1, 2026
67a99ed
Title-case Allowed Groups field label
mike-sheppard May 1, 2026
4441494
Restyle picker grid with subtle border + shadow, label hidden until h…
mike-sheppard May 1, 2026
4190548
Fix sets slug collision, tidy js by moving templates out + bump to v5
mike-sheppard May 2, 2026
5462eb1
Fix code smells and remove v4 deprecations
mike-sheppard May 2, 2026
fd5b79b
Upgrade phpstan to v2 + level 10 + fix remaining issues
mike-sheppard May 2, 2026
27a10c5
Bump min PHP to 8.2, use Rector to tidy up, add 8.5 to tests
mike-sheppard May 2, 2026
6d32aac
Fix keyboard nav to respect cols
mike-sheppard May 2, 2026
a65c5b3
Add explicit missing state + show icon names in the UI
mike-sheppard May 5, 2026
d476bad
Tidy up docs
mike-sheppard May 5, 2026
cd0efe6
v5 code refactor + break-up + tidy
mike-sheppard May 5, 2026
25d3746
More performant filters/search + a11y keyboard fix
mike-sheppard May 5, 2026
51af268
Update project docs
mike-sheppard May 5, 2026
5488253
Tidy up our tooling configs
mike-sheppard May 5, 2026
0ed583e
Simplify CSS + nicer error state
mike-sheppard May 5, 2026
cc21225
Tidy spacing
mike-sheppard May 5, 2026
5fb3e87
Reset the missing-asset state
mike-sheppard May 5, 2026
17c1caf
Add array icon data return format
mike-sheppard May 5, 2026
d9793b6
Update docs
mike-sheppard May 5, 2026
e8a6bdc
Simplify/tidy codebase
mike-sheppard May 5, 2026
ba66d52
Update input.js
mike-sheppard May 5, 2026
b4c87c7
Update input.js
mike-sheppard May 5, 2026
51e5d51
Update README.md
mike-sheppard May 5, 2026
fda0210
Resolve PR comments
mike-sheppard May 5, 2026
10b8ceb
Enforce allowed_groups on render
mike-sheppard May 5, 2026
f44b2b4
Address PR comments
mike-sheppard May 5, 2026
9d38a69
Test cleanup
mike-sheppard May 5, 2026
17409e1
chore: Add mago.toml and package files to export-ignore in .gitattrib…
Levdbas May 6, 2026
06f44e6
fix: fix acf field class not available
Levdbas Jun 9, 2026
84b2ae5
feat: add POT file and added Dutch translation
Levdbas Jun 9, 2026
97e5dc5
chore: format package.json for consistency
Levdbas Jun 9, 2026
519d28f
chore: lint files
Levdbas Jun 9, 2026
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
73 changes: 73 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Code quality

on:
push:
branches:
- main
pull_request:
branches:
- main
types:
- opened
- synchronize
- ready_for_review

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

jobs:
phpstan:
name: PHPStan (level 9)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
tools: composer:v2

- uses: ramsey/composer-install@v4

- name: Run PHPStan
run: composer phpstan

mago-format:
name: Mago format check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.1"
tools: composer:v2

- uses: ramsey/composer-install@v4

- name: Run Mago format check
run: composer format:check

oxc:
name: Oxfmt + Oxlint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Run Oxfmt format check
run: npm run format -- --check

- name: Run Oxlint
run: npm run lint
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
vendor
wp-content
node_modules
.phpunit.result.cache
.DS_Store
17 changes: 17 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"singleQuote": true,
"sortPackageJson": false,
"ignorePatterns": [
"vendor/**",
"node_modules/**",
"wp-content/**",
"tests/assets/**",
".github/**",
"**/*.php",
"**/*.svg",
"**/*.md",
"composer.lock",
"package-lock.json"
]
}
24 changes: 0 additions & 24 deletions .phpcs.xml.dist

This file was deleted.

172 changes: 172 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Changelog

All notable changes to this project are documented here.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [4.4.0] — 2026-05-01

### Added

- **Multiple icon locations** — `acf_svg_icon_picker_custom_location` now accepts a list of `{ path, url, name?, key? }` arrays. Locations render as named groups in the picker UI. Single `{ path, url }` shape remains supported (back-compatible).
- **Auto-grouping by subdirectory** — set `'group_by_subdir' => true` on a single location to expose each top-level subfolder as its own group (subfolder name becomes the heading).
- **Per-field group filter** — closes [#32](https://github.com/smithfield-studio/acf-svg-icon-picker/issues/32). New `allowed_groups` field setting (rendered as a checkbox group of available group keys) restricts the picker to a chosen subset of groups for that specific field. Empty / unset = show all (back-compatible).
- **Arrow-key navigation** in the icon grid (Left/Right step one tile, Up/Down jump a row, Home/End jump to ends) with roving tabindex.
- **Subtle scale-up transition** on icon tile hover and keyboard focus, with `prefers-reduced-motion` opt-out.
- New helper `resolve_icon_in_location()` for resolving an icon within a single location config (honours subdir mode).
- New internal helper `normalize_custom_locations()` shared between the field class and helper functions.
- New public property `$plugin->groups` exposing the grouping metadata.
- Editor JS exposes `acfSvgIconPicker.groups` alongside the existing `svgs` data.
- [Oxfmt](https://github.com/oxc-project/oxc) + [Oxlint](https://github.com/oxc-project/oxc) for JS / CSS / JSON formatting and JS linting (Rust-based, sub-second). Replaces ESLint + Stylelint.
- [Mago](https://github.com/carthage-software/mago) (`carthage-software/mago`) for PHP formatting. Replaces PHPCS.
- New `.github/workflows/code-quality.yml` running PHPStan, Mago format check, Oxfmt format check, and Oxlint on every push to `main` and PR (in addition to the existing PHPUnit workflow).
- **PHPStan strictness raised from level 5 → level 9** (max for PHPStan 1.x). Required adding precise array shape types (`array{path: string, url: string, name?: string, key?: string, group_by_subdir?: bool}`) to the location-config contract, narrowing `mixed` filter inputs with explicit `is_string` checks, and handling the `false` return from `file_get_contents`/`scandir`.
- **WP admin colour scheme integration** — the picker's focus ring now pulls from `--wp-admin-theme-color`, so it matches the user's chosen admin colour scheme out of the box.
- **RTL support** — block-axis margins, paddings, and borders use logical properties (`margin-block-end`, `padding-inline`, `border-block-end`, `min-inline-size`) so right-to-left languages render correctly.

### Changed

- **Picker popup is now a native `<dialog>` element.** Browser provides focus trap, Escape-to-close, focus restoration, and inert background page automatically. Removes the manual focus-trap and overlay JS.
- **Vanilla JS picker code.** Removed jQuery from the picker's own logic — only the ACF integration point still touches jQuery (because `acf.get_fields()` returns a jQuery collection). All DOM work now uses native `addEventListener`, `closest`, `classList`, `dispatchEvent`, etc.
- **Icon tiles are real `<button>` elements** (`<li><button data-svg>`), not clickable list items. They're focusable, keyboard-activatable, and have `aria-label` for screen readers.
- Picker grid uses CSS `grid-template-columns: repeat(auto-fill, minmax(120px, 1fr))` so columns reflow with the popup width. Tiles are `aspect-ratio: 1` for a uniform grid; icons normalised via `width: 50%; aspect-ratio: 1; object-fit: contain`.
- Popup sizing is responsive: `clamp(320px, 75vw, 1200px) × clamp(400px, 75vh, 900px)` with a 95v* viewport cap.
- Popup header is a single compact row: title, search input (flex-grow), close button.
- Trigger selector enlarged from 50px → 70px circle; remove button now centres beneath the trigger via a flex-column wrapper.
- Group headings render whenever the filter returns a list of locations (or a single location with `group_by_subdir`), even if only one ends up populated. Empty groups are silently hidden.
- `acf_svg_icon_picker_custom_location` filter callbacks may use the new optional `name` / `key` / `group_by_subdir` keys per location.
- Composer `composer.json` now declares `"require": { "php": ">=8.1" }` so installation enforces the same minimum the plugin header advertises.

### Fixed

- **Pressing Enter anywhere in the admin opening the icon picker** — fixes [#34](https://github.com/smithfield-studio/acf-svg-icon-picker/issues/34). The trigger and remove buttons in the field view template were missing `type="button"`, so they defaulted to `type="submit"` and intercepted Enter-key form submissions inside Flexible Content (and any other form context). Both now have explicit `type="button"`.
- `get_svg_icon_uri()` now returns the URL of the matching custom location instead of always falling back to `get_theme_file_uri()`. Pre-fix the helper returned theme-relative URLs even when icons were stored elsewhere via the custom-location filter — those URLs typically 404'd.
- Numerous a11y issues with the picker popup: missing dialog role, no focus trap, no Escape handler, no focus restoration, unlabelled search input, unlabelled close button, list items not keyboard-focusable.
- Pre-existing `@var strin` typo on `$path_suffix` corrected to `string`.

### Removed

- `.acf-svg-icon-picker__popup-overlay` wrapper element (replaced by native `<dialog>` + `::backdrop`). The previous z-index workaround is no longer necessary because dialogs opened with `showModal()` live in the browser's top-layer.
- Internal `$path` and `$url` private properties on the field class — they were write-only after the multi-location refactor and provided no external value.
- PHPCS, the 10up PHPCS ruleset, WPCS, and `phpcompatibility/php-compatibility` dev dependencies — replaced by Mago for PHP formatting.
- ESLint and Stylelint dev dependencies — replaced by Oxfmt + Oxlint.
- `.phpcs.xml.dist`, `.eslintrc.json`, and `.stylelintrc.json` config files (no longer used).

### Compatibility notes

- **DOM hooks for the picker UI changed.** If you target `.acf-svg-icon-picker__popup-overlay` or `.acf-svg-icon-picker__popup ul li[data-svg]` in custom CSS, replace them with `.acf-svg-icon-picker__popup` and `.acf-svg-icon-picker__option` respectively.
- **Browser baseline implicitly raised** by the move to native `<dialog>`: Chrome 37+, Firefox 98+ (Mar 2022), Safari 15.4+ (Mar 2022).

## [4.3.1]

- fix: Increase z-index of SVG icon picker overlay so it sits above the block-editor extended view, co-authored by @adambichler in #38.
- chore: Update GitHub Actions workflows to use latest PHP versions.
- chore: Code formatting pass.

## [4.3.0]

- Change action hook for field type registration by @EarthmanWeb in #37.
- Update GitHub Actions workflows to use latest PHP versions.

## [4.2.0]

- `get_svg_icon_path()` helper function now returns the correct path when using the custom location filter.

## [4.1.0]

- Add ability to return the icon markup directly from the field via `'return_format' => 'icon'`.
- Enhance markup of the icon picker modal and field.
- Update hook docs in README, by @huubl in #29.
- Add tests for the new return format.
- Run PHPCS on PRs.

## [4.0.1]

- Fix version numbers in constant.
- Add files to export ignore.

## [4.0.0]

- Remove/deprecate legacy filters; refactor and simplify icon path filters, by [@Levdbas](https://github.com/Levdbas) in [#25](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/25).
- Add unit tests, PHPStan, and return types, by [@Levdbas](https://github.com/Levdbas) in [#25](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/25).
- Better support for hashed assets, by [@mike-sheppard](https://github.com/mike-sheppard) in [#26](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/26).

## [3.1.4]

- Fix filter on filenames with diacritical marks, by [@Rvervuurt](https://github.com/Rvervuurt) in [#21](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/21).

## [3.1.3]

- Added MutationObserver, by [@chrisbakr](https://github.com/chrisbakr) in [#20](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/20).

## [3.1.2]

- Add debounce to improve filter performance, by [@stefanmomm](https://github.com/stefanmomm) in [#17](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/17).

## [3.1.1]

- Optimize css, by [@stefanmomm](https://github.com/stefanmomm) in [#16](https://github.com/smithfield-studio/acf-svg-icon-picker/pull/16).

## [3.1.0]

- Changed name of field to `svg_icon_picker` to avoid conflicts with vanilla ACF Icon Picker field.

## [3.0.0]

- Revert to original ACF field name, quick tidy + README updates.

## [2.0.0]

- Fix for ACF 6.3 which now has an official icon-picker field, plus merged open PRs from [@Levdbas](https://github.com/Levdbas) in [#38](https://github.com/houke/acf-icon-picker/pull/38) and [@phschmanau](https://github.com/phschmanau) in [#37](https://github.com/houke/acf-icon-picker/pull/37).

---

**Forked from [houke/acf-icon-picker](https://github.com/houke/acf-icon-picker).** Pre-fork history below.

---

## [1.9.1]

- ACF 6 compatibility fix, by [@idflood](https://github.com/idflood) in [#30](https://github.com/houke/acf-icon-picker/pull/30).

## [1.9.0]

- Fix issue with Gutenberg preview not updating when removing, by [@cherbst](https://github.com/cherbst) in [#23](https://github.com/houke/acf-icon-picker/pull/23).

## [1.8.0]

- Fix issue with Gutenberg not saving icon, by [@tlewap](https://github.com/tlewap) in [#17](https://github.com/houke/acf-icon-picker/pull/17).

## [1.7.0]

- 2 new filters for more control over icon path, by [@benjibee](https://github.com/benjibee) in [#11](https://github.com/houke/acf-icon-picker/pull/11).

## [1.6.0]

- Performance fix with lots of icons, by [@idflood](https://github.com/idflood) in [#9](https://github.com/houke/acf-icon-picker/pull/9).

## [1.5.0]

- Fix issue where searching for icons would break preview if icon name has space.

## [1.4.0]

- Add filter to change folder where svg icons are stored.

## [1.3.0]

- Adding close option on modal.

## [1.2.0]

- Adding search filter input to filter through icons by name.

## [1.1.0]

- Add button to remove the selected icon when the field is not required.

## [1.0.0]

- First release.
Loading
Loading