Repository navigation
release: toolbelt v0.8.0, four new tools and guides - #272
Merged
Merged
Conversation
…188) * feat(color-converter): add color converter & contrast checker (#84) * fix(color-converter): address maintainer review feedback for #84 - switch registry accentVar to --fuchsia and accentHex to #F26DF0 - replace --violet styling in ColorConverterClient with --fuchsia - add peer-focus-visible styling to swatch labels on keyboard focus - remove conflicting btn btn-ghost classes from FG/BG buttons to match info pill - remove NAMED_COLORS, transparent support, and Named label - simplify wcagRating to return only normalText and largeText without overloads - add tests for 3-value space-separated rgb/hsl syntax - fix contrastRatio translucent alpha compositing order over white and add regression test
…178) HistoryPanel created its own useHistory(storageKey) copy of the same localStorage state, and useLocalStorage does not sync separate instances. The panel therefore never saw entries the tool had just pushed (they showed up only after a reload), and the tool's stale copy wrote removed entries back on its next push. The tools now own the single instance and pass it to the panel as a prop (HistoryApi), and the panel's own max default of 20 is gone, so the history size stays defined once per tool (15, as both tools already passed). Three files, +14/-6; lib/useLocalStorage.ts is unchanged.
* feat: add Unix timestamp converter * fix: address timestamp converter review feedback * fix: restore upstream files after review
…ith 3 updates (#198) Bumps the dev-dependencies group with 3 updates in the / directory: [postcss](https://github.com/postcss/postcss), [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) and [wrangler](https://github.com/cloudflare/workers-sdk/tree/HEAD/packages/wrangler). Updates `postcss` from 8.5.29 to 8.5.30 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.29...8.5.30) Updates `vitest` from 4.1.11 to 4.1.12 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.12/packages/vitest) Updates `wrangler` from 4.149.0 to 4.151.0 - [Release notes](https://github.com/cloudflare/workers-sdk/releases) - [Commits](https://github.com/cloudflare/workers-sdk/commits/wrangler@4.151.0/packages/wrangler) --- updated-dependencies: - dependency-name: postcss dependency-version: 8.5.30 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: vitest dependency-version: 4.1.12 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: dev-dependencies - dependency-name: wrangler dependency-version: 4.151.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: dev-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…locations (#181) * Fix: Update parseSyntaxError to use lossless-json for accurate error locations * Refactored: review feedback on fallback logic and test cases * Apply batched suggestions from code review Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com> * Apply batched suggestions from code review Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com> * style: apply formatting fix for else try catch block --------- Co-authored-by: Anurag Verma <78868769+anurag629@users.noreply.github.com>
* feat: add Text Case Converter tool Closes #81 * fix: address review feedback on case converter a11y - drop textarea aria-label (visible label already associated via htmlFor) - drop invalid aria-label from output pre elements - stop uppercasing output labels so casing stays readable --------- Co-authored-by: harshit-exe-dev <harshit-exe-dev@users.noreply.github.com>
…ds (#207) * fix: give the JWT decoder switch real tab semantics and name its fields The Decode/Encode switch looked like tabs but was two plain buttons, so screen reader users had no tab semantics and no arrow-key navigation. Follow the Base64 tool: a tablist with aria-label, role=tab on each button with aria-selected, aria-controls and a roving tabIndex, Arrow/Home/End handling with wraparound, and role=tabpanel with aria-labelledby on each panel. Also name the fields that had none: the token textarea, the Endpoint input (now tied to its label with htmlFor and id), the payload editor, the secret/key inputs and the JWKS URL. The decoding error block becomes role=alert, and the verification toggle gets aria-expanded and aria-controls. No className changes, so both themes look identical. * fix: point the verification toggle at the element it expands The toggle got aria-controls="jwt-verification-explained" but nothing carried that\nid, so the control referenced nothing. Give the explanation block the id it\nis pointed at.
Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com>
* preserve array structure in XML conversion Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> * Added test Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com> --------- Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com>
* fix: quote YAML 1.1 ambiguous strings * fix: handle YAML 1.1 numeric underscores
The invoice generator showed a small "Loading..." card until the working invoice was read from localStorage after mount. When the editor and preview then appeared, the FAQ and CTA sections below were pushed down by over a thousand pixels, giving a Cumulative Layout Shift of 0.57 on desktop and 0.47 on mobile. Render the real toolbar, editor and preview from the first paint, using a fixed placeholder invoice (no random ids or dates, so server and client HTML match), and swap in the seeded invoice after mount. While the placeholder is showing the sections are inert and marked aria-busy so nothing can be typed into it. Lighthouse (production build, median of runs): desktop CLS 0.567 -> 0.003, mobile CLS 0.465 -> 0.000. Closes #159 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local>
* fix: keep JSON Find focus and highlight full matches * fix: preserve JSON editor selection while Find is open
Co-authored-by: lb1192176991-lab <lb1192176991-lab@users.noreply.github.com>
…230) nextInvoiceNumber is meant to keep the prefix and zero padding of the highest saved invoice, but an empty prefix was replaced with "INV" and every number was padded to at least four digits, so 1001 became INV1002 and INV-07 became INV-0008. Keep the prefix exactly as saved, even when it is empty, and pad to the width of the highest number's own digits, so 1001 -> 1002, INV-07 -> INV-08, A1 -> A2 and 2026-001 -> 2026-002. A number that outgrows its width just gets longer (INV-99 -> INV-100). INV plus four digits is used only when no invoice has a number yet, so the list still starts at INV0001. Closes #220 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local>
Pasting text like password123, hello-world, 2024-01-15 or user_id_123 into the Base64 Text tab in Encode mode switched to Decode and showed "Decoded successfully but result is not valid UTF-8 text". detectBase64 says yes to anything of eight or more base64-alphabet characters with a digit, +, /, =, _ or -, and atob decodes all four, but not to text. Add detectBase64Text, which also requires the decoded bytes to be valid UTF-8, and use it in the paste handler. Real base64 of text such as SGVsbG8= and aGVsbG8gd29ybGQ still switches. With the gzip option on, gzipped base64 still switches too, as it did before. detectBase64 and its tests are unchanged. Closes #219 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local>
…the other identifier styles (#229) * fix(case-converter): drop punctuation from camelCase, snake_case and the other identifier styles * fix(case-converter): keep combining marks in the identifier styles
Signed-off-by: Anurag Yadav <anuragyadav2787@gmail.com>
…240) Look up standard claims and algorithms with Object.hasOwn so names such as __proto__, constructor and toString no longer match what every object inherits from Object.prototype. A token with a __proto__ claim or alg crashed the whole tool. Closes #232 Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…ead (#241) The JSON to YAML conversion wrote each number exactly as it appeared in the JSON. For an exponent that is wrong for YAML 1.1 parsers: PyYAML only reads a float that has a dot and a signed exponent, so 1e3, 1.5e3, 1E3, 2e+5, -1e3 and 1.0e3 loaded as strings, and a Python script reading the converted file got text where the JSON had a number. When a number has an exponent, add ".0" if the part before the "e" has no dot, and "+" if the exponent has no sign: 1e3 -> 1.0e+3, 1e-7 -> 1.0e-7, 1.5e3 -> 1.5e+3, 1E3 -> 1.0E+3, -1e3 -> -1.0e+3. The text of the number is edited as is, so long values keep every digit, and numbers without an exponent are unchanged. Checked with PyYAML 6.0, js-yaml and yaml. Closes #237 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local>
…and screen readers (#242)
Converts integers between binary, octal, decimal, hex and any base from 2 to 36, and shows the two's complement for 8, 16, 32 and 64 bits. - lib/number-base.ts: parseInteger, formatInteger, toTwosComplement and fromTwosComplement, all BigInt, so values above 2^53 stay exact. The parser reads the sign before a 0b/0o/0x prefix, ignores _ and spaces, and says which character is wrong and where. - /number-base-converter: one input with a base select, Copy buttons on the base 2, 8, 10 and 16 outputs, a custom output base, and a bit-width select for the two's complement. - Registry entry at the end of TOOLS, and the tool in the bug report dropdown. Closes #128
Six switches marked the selected button only with data-active, so a screen reader heard two plain buttons. Following the URL encoder's mode switch from #242, each wrapper is now a role="group" with an aria-label, and each button has type="button" and aria-pressed. data-active stays for the styling, so nothing changes visually. - Base64 Text tab: direction and Standard/URL-safe - Base64 File tab: line length - JWT verify panel: Secret/JWKS - JSON formatter: indent and Code/Tree Adds component tests for the Base64, JSON formatter and JWT switches. Closes #254
#249) (#260) The plain-text heuristic counted printable ASCII over the first 200 bytes, so any accented or non-Latin sentence whose multibyte UTF-8 encodings sit above 0x7F was labeled "Unknown / binary" with no preview and a decoded.bin download. Text detection now decodes the whole payload with the existing strict decodeUtf8Bytes and accepts it when it carries no control characters other than tab, line feed and carriage return. NUL stays a refusal (it is valid UTF-8), so the broken-ftyp test still gives null, and empty input still gives null as before. Co-authored-by: Rahul Ranjan <11793455+rahul05ranjan@users.noreply.github.com>
… theme (#262) The selected button's white overlay, rgba(255, 255, 255, 0.07), doesn't show on the light background, so only a faint outline was left. A light theme rule now gives it rgba(10, 11, 15, 0.08) instead, following the other [data-theme="light"] overrides. The dark theme is unchanged. Closes #259
The Base64 to File tab stripped a data:...;base64, prefix, but only when the media type was followed directly by ";base64,". A data URI can have ";name=value" parameters in between (RFC 2397), so data:text/plain;charset=utf-8;base64,... and data:application/json;charset=UTF-8;base64,... failed with "Invalid base64 string: illegal character ":" at position 4". Exported SVG and JSON files often carry ";charset=utf-8". Move the prefix parsing into parseBase64DataUri in lib/base64-utils.ts and allow parameters between the media type and ";base64,". Only the media type is used for the MIME fallback, and the notice now shows the whole prefix that was stripped. The scheme and "base64" match in any letter case, an empty media type (data:;base64,...) falls back to text/plain, and a data URI without ";base64" (data:text/plain,hello) is still not treated as base64. Closes #248 Co-authored-by: Saif Ullah jafri <saifullahjafri@Saifs-MacBook-Air.local>
The JSONPath panel parsed the input with JSON.parse, so large integers and high-precision decimals were rounded in the matches and in Copy matches. The expression still runs on the JSON.parse value, so filters behave as before, but each match is now read from a lossless-json parse of the same input at the match's JSON Pointer, and the panel prints the matches with lossless-json's stringify. A duplicate key is reported as an Invalid JSON error instead of crashing the tool. Closes #238 Claude-Session: https://claude.ai/code/session_01STJRQtEaEPSLfiWGMn8Syr Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
toolbelt-dev | f1ab01b | Oct 23 2026, 02:06 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four new tools, a guides section and a long list of fixes, almost all of them from this month's contributors.
New tools
Guides
/guideswith a first guide on formatting and validating JSON, each with its own metadata, share image and sitemap entry (thanks @bhushan4work, feat(guides): add typed guides registry and routing (#35) #269)JSON formatter
constructor(thanks @Pratham2511, fix(json-formatter): ignore inherited CSV cell values #257), and JSONPath keeps every digit of big numbers (thanks @arxh80, fix(json): keep every digit of numbers in JSONPath matches #265)Base64 and URL encoder
JWT decoder
__proto__claim no longer breaks the page (thanks @dbdefault, fix(jwt-decoder): treat inherited property names as ordinary claims #240), and every field and dropdown has a label (thanks @Pranitha06sri, fix: add accessible labels to JWT controls #267)Invoice generator
Everywhere else
New tools and a new section, so this is a minor release (v0.8.0).
Come hang out with us on Discord: https://discord.gg/mpGdJyjaRQ