Showing preview only (249K chars total). Download the full file or copy to clipboard to get everything.
Repository: primer/octicons
Branch: main
Commit: b02e013361aa
Files: 134
Total size: 220.5 KB
Directory structure:
gitextract_5k8z2tga/
├── .changeset/
│ ├── README.md
│ └── config.json
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ ├── config.yml
│ │ └── feedback.md
│ ├── actions/
│ │ ├── build_node/
│ │ │ ├── Dockerfile
│ │ │ └── entrypoint.sh
│ │ ├── build_ruby/
│ │ │ ├── Dockerfile
│ │ │ └── entrypoint.sh
│ │ ├── python/
│ │ │ └── requirements.txt
│ │ └── version/
│ │ ├── Dockerfile
│ │ └── entrypoint.js
│ ├── dependabot.yml
│ └── workflows/
│ ├── add-to-inbox.yml
│ ├── check_for_changeset.yml
│ ├── ci.yml
│ ├── codeql.yml
│ ├── optimize.yml
│ ├── publish.yml
│ ├── release.yml
│ └── stale.yml
├── .gitignore
├── .npmrc
├── .rubocop.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── README.md
├── add-octicon-checklist.md
├── keywords.json
├── lib/
│ ├── octicons_gem/
│ │ ├── .npmignore
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── lib/
│ │ │ ├── octicons/
│ │ │ │ ├── octicon.rb
│ │ │ │ └── version.rb
│ │ │ └── octicons.rb
│ │ ├── octicons.gemspec
│ │ └── test/
│ │ ├── helper.rb
│ │ ├── octicon_test.rb
│ │ └── octicons_test.rb
│ ├── octicons_helper/
│ │ ├── .npmignore
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── lib/
│ │ │ ├── octicons_helper/
│ │ │ │ ├── helper.rb
│ │ │ │ ├── railtie.rb
│ │ │ │ └── version.rb
│ │ │ └── octicons_helper.rb
│ │ ├── octicons_helper.gemspec
│ │ └── test/
│ │ ├── helper.rb
│ │ └── octicons_helper_test.rb
│ ├── octicons_jekyll/
│ │ ├── .npmignore
│ │ ├── .rubocop.yml
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── jekyll-octicons.gemspec
│ │ ├── lib/
│ │ │ ├── jekyll-octicons/
│ │ │ │ └── version.rb
│ │ │ └── jekyll-octicons.rb
│ │ └── test/
│ │ ├── helper.rb
│ │ └── octicon_tag_test.rb
│ ├── octicons_node/
│ │ ├── .npmignore
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── index.scss
│ │ ├── package.json
│ │ ├── prettier.config.js
│ │ └── tests/
│ │ └── index.js
│ ├── octicons_react/
│ │ ├── .eslintignore
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── .nvmrc
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── __snapshots__/
│ │ │ │ └── public-api.test.js.snap
│ │ │ ├── public-api.test.js
│ │ │ └── tree-shaking.test.js
│ │ ├── babel.config.js
│ │ ├── jest.config.js
│ │ ├── next.config.mjs
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── _document.mjs
│ │ │ └── index.mjs
│ │ ├── prettier.config.js
│ │ ├── rollup.config.js
│ │ ├── script/
│ │ │ ├── .eslintrc.json
│ │ │ ├── build.js
│ │ │ └── types.js
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── .eslintrc.json
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── octicon.js.snap
│ │ │ │ └── octicon.js
│ │ │ ├── createIconComponent.js
│ │ │ ├── index.d.ts
│ │ │ └── index.js
│ │ └── ts-tests/
│ │ ├── index.tsx
│ │ └── tsconfig.json
│ └── octicons_styled/
│ ├── .babelrc
│ ├── .eslintignore
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .npmignore
│ ├── .nvmrc
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── prettier.config.js
│ ├── rollup.config.js
│ ├── script/
│ │ ├── .eslintrc.json
│ │ ├── build.js
│ │ └── copy.sh
│ ├── src/
│ │ ├── __tests__/
│ │ │ ├── .eslintrc.json
│ │ │ └── octicon.js
│ │ └── utils.js
│ └── ts-tests/
│ ├── index.tsx
│ └── tsconfig.json
├── package.json
├── prettier.config.js
├── script/
│ ├── build.js
│ ├── changeset-publish
│ └── version
├── svgo.config.js
└── tests/
├── build.js
├── index.js
└── snapshots/
├── build.js.md
└── build.js.snap
================================================
FILE CONTENTS
================================================
================================================
FILE: .changeset/README.md
================================================
# Changesets
Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in our repository](https://github.com/changesets/changesets)
We have a quick list of common questions to get you started engaging with this project in
[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
================================================
FILE: .changeset/config.json
================================================
{
"$schema": "https://unpkg.com/@changesets/config@1.6.1/schema.json",
"changelog": ["@changesets/changelog-github", {"repo": "primer/octicons"}],
"commit": false,
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
================================================
FILE: .github/CODEOWNERS
================================================
* @primer/engineer-reviewers
================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: 🐞 Bug report
about: Report a bug in Octicons
title: "[Bug] "
labels: "bug, octicon"
assignees: ''
---
<!-- Note: When including screenshots, images, and other visual media, please include alt text or, if there are several of them, a higher level written explanation of what's represented in the images. -->
### Describe the bug
_Include a clear and concise description of what the bug is._
### Steps to reproduce
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
### Expected behavior
_Include a clear and concise description of what you expected to happen if there was no bug._
### Screenshots
_Please add screenshots to help explain the problem._
### Device details
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
### Additional info
_Add any other information relevant to the problem here._
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
- name: Add to the Octicon library?
url: https://github.com/github/primer
about: Open an issue in github/primer (for GitHub staff only!)
================================================
FILE: .github/ISSUE_TEMPLATE/feedback.md
================================================
---
name: 💬 Feedback and ideas
about: Suggest improvements or give feedback on icon designs
title: "[Feedback] "
labels: "octicon, type: feedback"
assignees: ''
---
<!-- Note: When including screenshots, images, and other visual media, please include alt text or, if there are several of them, a higher level written explanation of what's represented in the images. -->
### Describe the topic
_You have an idea, feedback or suggestion for icons to add to Octicons, tell us all about it! Add as much detail as you can: what is your idea, why is it relevant, what should change, how will it improve the Octicons library?_
### Anything else?
_Include anything else you think may be relevant to understand the issue._
================================================
FILE: .github/actions/build_node/Dockerfile
================================================
FROM node:24-slim
RUN apt-get update && \
apt-get install --no-install-recommends -y \
jq && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
================================================
FILE: .github/actions/build_node/entrypoint.sh
================================================
#!/bin/bash -l
set -e
PACKAGE_VERSION=$(jq '.version' --raw-output ./package.json)
echo "************* Building v$PACKAGE_VERSION *************"
PUBLISH_TAG=latest
if [[ "$PACKAGE_VERSION" =~ ^0\.0\.0\- ]]
then
PUBLISH_TAG=canary
elif [[ "$PACKAGE_VERSION" =~ \-rc ]]
then
PUBLISH_TAG=next
fi
cd ./lib/"$*"
echo "**************** Copying assets files to build directory ****************"
cp -R ../build/ .
echo "**************** Installing ****************"
npm install --legacy-peer-deps
echo "**************** Building ****************"
npm run build
{
echo "**************** Publishing ****************"
npm version --allow-same-version "$PACKAGE_VERSION" && npm publish --tag $PUBLISH_TAG --access public
} || {
# Bail out of publishing
exit 0
}
================================================
FILE: .github/actions/build_ruby/Dockerfile
================================================
FROM ruby:3.0
RUN apt-get update && \
apt-get install --no-install-recommends -y \
jq && \
apt-get clean -y && \
rm -rf /var/lib/apt/lists/*
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
================================================
FILE: .github/actions/build_ruby/entrypoint.sh
================================================
#!/bin/bash -l
set -e
PACKAGE_VERSION=$(jq '.version' --raw-output ./package.json)
PACKAGE_VERSION=$(echo $PACKAGE_VERSION | sed -e 's/^0\.0\.0./0.0.0.pre./g')
PACKAGE_VERSION=$(echo $PACKAGE_VERSION | sed -e 's/-rc/.pre/g')
echo "************* Building v$PACKAGE_VERSION *************"
# Setup rubygems creds
mkdir -p ~/.gem
cat << EOF > ~/.gem/credentials
---
:rubygems_api_key: ${RUBYGEMS_TOKEN}
EOF
chmod 0600 ~/.gem/credentials
cd ./lib/$*
echo "**************** Copying assets files to build directory ****************"
cp -R ../build lib/
perl -pi -e "s/\"octicons\", \"[^\"]+\"/\"octicons\", \"${PACKAGE_VERSION}\"/" ./Gemfile ./*.gemspec
echo "**************** Installing ****************"
bundle install
echo "**************** Versioning ****************"
bundle exec rake version\["$PACKAGE_VERSION"\]
bundle update
echo "**************** Building ****************"
bundle exec rake build
GEM_PUSH_OUTPUT=$(gem push pkg/*.gem 2>&1) || {
echo "$GEM_PUSH_OUTPUT"
echo "$GEM_PUSH_OUTPUT" | grep -q "Repushing of gem versions is not allowed" || exit 1
}
================================================
FILE: .github/actions/python/requirements.txt
================================================
picosvg~=0.20.6
================================================
FILE: .github/actions/version/Dockerfile
================================================
FROM node:10-slim
WORKDIR /
COPY . /
RUN npm install
ENTRYPOINT [ "node", "/entrypoint.js" ]
================================================
FILE: .github/actions/version/entrypoint.js
================================================
const fs = require('fs')
const {
resolve
} = require('path')
const {
GITHUB_REF,
GITHUB_SHA
} = process.env
// Octicons package
const pkg = require(resolve(process.cwd(), 'package.json'))
// GitHub info
const branchName = GITHUB_REF.replace('refs/heads/', '')
const shortSha = GITHUB_SHA.slice(0,7)
let releaseMatch = null
const writePackageJson = () => {
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2), 'utf8')
}
// If it's a release branch
if (releaseMatch = branchName.match(/^release-([\d\.]+)/i)) {
console.log('Versioning release candidate')
console.log(`${pkg.version} => ${releaseMatch[1]}`)
pkg.version = `${releaseMatch[1]}-rc.${shortSha}`
writePackageJson()
}
// Otherwise
else if (branchName != 'main') {
const newVersion = `0.0.0-${shortSha}`
console.log('Versioning prerelease')
console.log(`${pkg.version} => ${newVersion}`)
pkg.version = newVersion
writePackageJson()
}
================================================
FILE: .github/dependabot.yml
================================================
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/docs" # Location of package manifests
schedule:
interval: "daily"
allow:
- dependency-name: "@primer/gatsby-theme-doctocat"
================================================
FILE: .github/workflows/add-to-inbox.yml
================================================
name: Add to Inbox 📥
on:
issues:
types: [opened, reopened]
jobs:
add-to-inbox:
if: ${{ github.repository == 'primer/behaviors' }}
runs-on: ubuntu-latest
env:
ISSUE_URL: ${{ github.event.issue.html_url }}
PROJECT_ID: 4503
steps:
- id: get-primer-access-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.PRIMER_ISSUE_TRIAGE_APP_ID }}
private-key: ${{ secrets.PRIMER_ISSUE_TRIAGE_APP_PRIVATE_KEY }}
- name: Add labels to issue
run: |
gh issue edit $ISSUE_URL --add-label 'rails,react'
env:
GH_TOKEN: ${{ steps.get-primer-access-token.outputs.token }}
- id: get-github-access-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ vars.PRIMER_ISSUE_TRIAGE_APP_ID_FOR_GITHUB }}
private-key: ${{ secrets.PRIMER_ISSUE_TRIAGE_APP_PRIVATE_KEY_FOR_GITHUB }}
owner: github
- name: Add issue to project
run: gh project item-add $PROJECT_ID --url $ISSUE_URL --owner github
env:
GH_TOKEN: ${{ steps.get-github-access-token.outputs.token }}
================================================
FILE: .github/workflows/check_for_changeset.yml
================================================
name: Check for changeset
on:
pull_request:
types:
# On by default if you specify no types.
- 'opened'
- 'reopened'
- 'synchronize'
# For `skip-label` only.
- 'labeled'
- 'unlabeled'
jobs:
check-for-changeset:
name: Check for changeset
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: 'Check for changeset'
uses: brettcannon/check-for-changed-files@v1
with:
file-pattern: '.changeset/*.md'
skip-label: 'skip-changeset'
failure-message: 'No changeset found. If these changes should not result in a new version, apply the ${skip-label} label to this pull request. If these changes should result in a version bump, please add a changeset https://git.io/J6QvQ'
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches:
- main
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: yarn
- name: Building
run: yarn build
- run: cp -r icons lib/build/svg
- uses: actions/upload-artifact@v4
with:
name: octicons-build
path: ./lib/build
main:
name: Main project
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- uses: actions/download-artifact@v4
with:
name: octicons-build
path: ./lib/build
- run: yarn
- name: Lint
run: yarn lint
- name: Test
run: yarn test
octicons_node:
name: 'npm:@primer/octicons'
needs: build
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./lib/octicons_node
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- uses: actions/download-artifact@v4
with:
name: octicons-build
path: ./lib/build
- run: yarn
- name: Building
run: yarn build
- name: Lint
run: yarn lint
- name: Test
run: yarn test
octicons_react:
name: 'npm:@primer/octicons-react'
needs: build
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./lib/octicons_react
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- uses: actions/download-artifact@v4
with:
name: octicons-build
path: ./lib/build
- run: yarn
- name: Building
run: yarn build
- name: Lint
run: yarn lint
- name: Test
run: yarn test
- name: Types
run: |
# Run @arethetypeswrong/cli
npx @arethetypeswrong/cli --pack .
# Run publint
npx publint@0.2.12 . --strict
octicons_gem:
name: 'gem:octicons'
needs: build
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./lib/octicons_gem
steps:
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- uses: actions/download-artifact@v4
with:
name: octicons-build
path: ./lib/octicons_gem/lib/build
- run: bundle install
- name: Linting
run: bundle exec rake lint
- name: Testing
run: bundle exec rake test
- name: Build
run: bundle exec rake build
- uses: actions/upload-artifact@v4
with:
name: octicons-gem
path: ./lib/octicons_gem/pkg
octicons_helper:
name: 'gem:octicons_helper'
needs: octicons_gem
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./lib/octicons_helper
steps:
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- uses: actions/download-artifact@v4
with:
name: octicons-gem
path: ./lib/octicons_helper/vendor/cache
- name: Run bundle install
run: bundle config set --local disable_checksum_validation true && bundle install
- name: Linting
run: bundle exec rake lint
- name: Testing
run: bundle exec rake test
octicons_jekyll:
name: 'gem:octicons_jekyll'
needs: octicons_gem
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./lib/octicons_jekyll
steps:
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3
bundler-cache: true
- uses: actions/download-artifact@v4
with:
name: octicons-gem
path: ./lib/octicons_jekyll/vendor/cache
- name: Run bundle install
run: bundle config set --local disable_checksum_validation true && bundle install
- name: Linting
run: bundle exec rake lint
- name: Testing
run: bundle exec rake test
================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '28 7 * * 3'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript', 'ruby' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
================================================
FILE: .github/workflows/optimize.yml
================================================
on:
push:
paths:
- 'icons/**'
- '.github/workflows/optimize.yml'
- '.github/actions/python/requirements.txt'
pull_request:
paths:
- 'icons/**'
- '.github/workflows/optimize.yml'
- '.github/actions/python/requirements.txt'
name: Optimize SVGs
jobs:
optimize:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: 'pip'
- run: pip install -r .github/actions/python/requirements.txt
- run: for icon in icons/*; do picosvg $icon --output_file $icon; done
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- run: npm run svgo
- uses: EndBug/add-and-commit@v4
with:
add: 'icons'
message: 'Optimize SVGs'
author_email: actions@github.com
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/publish.yml
================================================
on:
release:
types: [published]
workflow_dispatch:
permissions:
id-token: write # Required for OIDC
contents: read
checks: write
statuses: write
name: Octicons Publish
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/setup-node@v6
with:
node-version: 24
- run: npm install
- run: npm run build
- run: cp -r icons lib/build/svg
- uses: actions/upload-artifact@v4
with:
name: octicons
path: ./lib/build
gem:
runs-on: ubuntu-latest
needs: setup
steps:
- uses: actions/checkout@master
- uses: actions/download-artifact@v4
with:
name: octicons
path: ./lib/build
- uses: ./.github/actions/build_ruby
env:
RUBYGEMS_TOKEN: ${{ secrets.RUBYGEMS_TOKEN }}
with:
args: octicons_gem
- run: ls ./lib/octicons_gem/pkg
- uses: actions/upload-artifact@v4
with:
name: octicons_gem
path: ./lib/octicons_gem/pkg
helper:
runs-on: ubuntu-latest
needs: gem
steps:
- uses: actions/checkout@master
- uses: actions/download-artifact@v4
with:
name: octicons
path: ./lib/build
- uses: actions/download-artifact@v4
with:
name: octicons_gem
path: ./lib/octicons_helper/vendor/cache
- uses: ./.github/actions/build_ruby
env:
RUBYGEMS_TOKEN: ${{ secrets.RUBYGEMS_TOKEN }}
with:
args: octicons_helper
jekyll:
runs-on: ubuntu-latest
needs: gem
steps:
- uses: actions/checkout@master
- uses: actions/download-artifact@v4
with:
name: octicons
path: ./lib/build
- uses: actions/download-artifact@v4
with:
name: octicons_gem
path: ./lib/octicons_jekyll/vendor/cache
- uses: ./.github/actions/build_ruby
env:
RUBYGEMS_TOKEN: ${{ secrets.RUBYGEMS_TOKEN }}
with:
args: octicons_jekyll
node:
runs-on: ubuntu-latest
needs: setup
steps:
- uses: actions/checkout@master
- uses: actions/download-artifact@v4
with:
name: octicons
path: ./lib/build
- uses: ./.github/actions/build_node
with:
args: octicons_node
react:
runs-on: ubuntu-latest
needs: setup
steps:
- uses: actions/checkout@master
- uses: actions/download-artifact@v4
with:
name: octicons
path: ./lib/build
- name: Build @primer/octicons-react
uses: ./.github/actions/build_node
with:
args: octicons_react
- name: Build @primer/styled-octicons
uses: ./.github/actions/build_node
with:
args: octicons_styled
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
push:
branches:
- "main"
- "next_major"
jobs:
release:
name: Final
if: ${{ github.repository == 'primer/octicons' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
persist-credentials: false
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: Install dependencies
run: |
yarn
bundle install
- id: get-access-token
uses: camertron/github-app-installation-auth-action@v1
with:
app-id: ${{ vars.PRIMER_APP_ID_SHARED }}
private-key: ${{ secrets.PRIMER_APP_PRIVATE_KEY_SHARED }}
client-id: ${{ vars.PRIMER_APP_CLIENT_ID_SHARED }}
client-secret: ${{ secrets.PRIMER_APP_CLIENT_SECRET_SHARED }}
installation-id: ${{ vars.PRIMER_APP_INSTALLATION_ID_SHARED }}
- name: Create release pull request or publish to npm
id: changesets
uses: changesets/action@master
with:
title: Release Tracking
version: yarn changeset:version
publish: script/changeset-publish
env:
GITHUB_TOKEN: ${{ steps.get-access-token.outputs.access-token }}
================================================
FILE: .github/workflows/stale.yml
================================================
name: Stale
on:
schedule:
- cron: '0 * * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4
with:
# General settings
days-before-stale: 60
days-before-close: 7
enable-statistics: true
operations-per-run: 100
remove-stale-when-updated: true
# PR specific settings
delete-branch: true
stale-pr-message: "Hi! This pull request has been marked as stale because it has been open with no activity for 60 days. You can comment on the pull request or remove the stale label to keep it open. If you do nothing, this pull request will be closed in 7 days."
# Issue specific settings
days-before-issue-stale: 180
stale-issue-message: "Hi! This issue has been marked as stale because it has been open with no activity for 180 days. You can comment on the issue or remove the stale label to keep it open. If you do nothing, this issue will be closed in 7 days."
================================================
FILE: .gitignore
================================================
*.gem
/package-lock.json
*.log
.DS_Store
.bundle
.env
node_modules
vendor
Gemfile.lock
# Ignore build/export artifacts
lib/**/build/
# Gatsby
public
.cache
# Now
.now
================================================
FILE: .npmrc
================================================
save-exact=true
package-lock=false
================================================
FILE: .rubocop.yml
================================================
inherit_gem:
rubocop-github:
- config/default.yml
- config/rails.yml
AllCops:
NewCops: enable
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## 19.23.1
### Patch Changes
- [#1175](https://github.com/primer/octicons/pull/1175) [`ea8e6bb7`](https://github.com/primer/octicons/commit/ea8e6bb79894cc7e85564ee9b53d86b418738d04) Thanks [@kylewaynebenson](https://github.com/kylewaynebenson)! - - Remove set fill from svgs
## 19.23.0
### Minor Changes
- [#1165](https://github.com/primer/octicons/pull/1165) [`63bc8d01`](https://github.com/primer/octicons/commit/63bc8d01e4c51ebc34abdac1bdb861cf209f7cf0) Thanks [@kylewaynebenson](https://github.com/kylewaynebenson)! - - Addition of lockup icon
- adjustments to logo and mark
## 19.22.1
### Patch Changes
- [#1169](https://github.com/primer/octicons/pull/1169) [`6567d755`](https://github.com/primer/octicons/commit/6567d755f30c18e44d8fd069abb974cf078bd2d4) Thanks [@francinelucca](https://github.com/francinelucca)! - various dep updates
## 19.22.0
### Minor Changes
- [#1157](https://github.com/primer/octicons/pull/1157) [`18e3b9fd`](https://github.com/primer/octicons/commit/18e3b9fd74c4bc85b1add3624a082fc0f6fd36c2) Thanks [@janmaarten-a11y](https://github.com/janmaarten-a11y)! - Add book-locked icon
Add comment-locked icon
Add issue-locked icon
Add git-pull-request-locked icon
## 19.21.2
### Patch Changes
- [#1146](https://github.com/primer/octicons/pull/1146) [`41c78057`](https://github.com/primer/octicons/commit/41c780575654fe4fef3fc4e91a46c8c0e91b233b) Thanks [@rezrah](https://github.com/rezrah)! - Updated GitHub brand logos (`mark-github` and `logo-github`) to 2026 versions.
## 19.21.1
### Patch Changes
- [#1137](https://github.com/primer/octicons/pull/1137) [`97cefc9f`](https://github.com/primer/octicons/commit/97cefc9fcb19f91133cffd557cc1f308e384ffb2) Thanks [@dependabot](https://github.com/apps/dependabot)! - Bump js-yaml from 3.13.1 to 4.1.1
## 19.21.0
### Minor Changes
- [#1132](https://github.com/primer/octicons/pull/1132) [`c5411b04`](https://github.com/primer/octicons/commit/c5411b048090e13a0e6ffafaa10efdc24a8e05b5) Thanks [@mperrotti](https://github.com/mperrotti)! - Adds icons used for Copilot Loops
* [#1134](https://github.com/primer/octicons/pull/1134) [`131fbedc`](https://github.com/primer/octicons/commit/131fbedc579b6ebc07716dc02ed947a168c560f2) Thanks [@mperrotti](https://github.com/mperrotti)! - Adds icons used for Copilot Markdown text wrapping options
- [#1133](https://github.com/primer/octicons/pull/1133) [`94ceabb7`](https://github.com/primer/octicons/commit/94ceabb7e1371eefd8ba26ec8eb59cf6149e7a29) Thanks [@mperrotti](https://github.com/mperrotti)! - Adds icons used for feedback dialogs
### Patch Changes
- [#1135](https://github.com/primer/octicons/pull/1135) [`be5df35d`](https://github.com/primer/octicons/commit/be5df35d390439f972af3adbd9ec59d38ec4c624) Thanks [@mperrotti](https://github.com/mperrotti)! - Updates VS Code icon to closer match the real app icon
## 19.20.0
### Minor Changes
- [#1129](https://github.com/primer/octicons/pull/1129) [`68ebe53b`](https://github.com/primer/octicons/commit/68ebe53ba972e391fa2b60458e37348636e202ad) Thanks [@lukasoppermann](https://github.com/lukasoppermann)! - Added InboxFill icon
## 19.19.0
### Minor Changes
- [#1123](https://github.com/primer/octicons/pull/1123) [`1d346555`](https://github.com/primer/octicons/commit/1d34655547b0ae59211967af830d30ae919e0257) Thanks [@mperrotti](https://github.com/mperrotti)! - Adds an icon for AI chat
## 19.18.1
### Patch Changes
- [#1120](https://github.com/primer/octicons/pull/1120) [`370c72c8`](https://github.com/primer/octicons/commit/370c72c8cb511bceb4e096891ff2393e81f87fa3) Thanks [@langermank](https://github.com/langermank)! - Add vscode-32.svg, vscode-48.svg
* [#1122](https://github.com/primer/octicons/pull/1122) [`dcf14c81`](https://github.com/primer/octicons/commit/dcf14c81ca32e4f1cee017a2815c66458a26b2fa) Thanks [@langermank](https://github.com/langermank)! - Add 16 vscode
## 19.18.0
### Minor Changes
- [#1117](https://github.com/primer/octicons/pull/1117) [`13014409`](https://github.com/primer/octicons/commit/13014409ff2cc07191a0d98629d088a5f994a49a) Thanks [@arisacoba](https://github.com/arisacoba)! - Add checkbox-fill-16.svg and checkbox-fill-24.svg
## 19.17.0
### Minor Changes
- [#1115](https://github.com/primer/octicons/pull/1115) [`59a4abf4`](https://github.com/primer/octicons/commit/59a4abf40334cbab7ec76e323255b44fd4ea4a95) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Save mcp-16.svg, mcp-24.svg
## 19.16.0
### Minor Changes
- [#1107](https://github.com/primer/octicons/pull/1107) [`4073a521`](https://github.com/primer/octicons/commit/4073a52102527e8e894501314c38c6e100d4f5d0) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Add minimize-16.svg, maximize-16.svg, maximize-24.svg, minimize-24.svg
### Patch Changes
- [#1112](https://github.com/primer/octicons/pull/1112) [`36fd097f`](https://github.com/primer/octicons/commit/36fd097f885eb22118417458b6d7b5f4c8e8566c) Thanks [@lukasoppermann](https://github.com/lukasoppermann)! - Adjusted alignment of repo delete, locked and push icon in 16px and 24px
## 19.15.5
### Patch Changes
- [#1102](https://github.com/primer/octicons/pull/1102) [`02cdd0c2`](https://github.com/primer/octicons/commit/02cdd0c2229c5148380e64ae6fe9957efc9e06a2) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Update Loop icon for visual alignment
## 19.15.4
### Patch Changes
- [#1099](https://github.com/primer/octicons/pull/1099) [`239cdee1`](https://github.com/primer/octicons/commit/239cdee1b6a2b3ada569aa25e260bf5862b52621) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Add spaces, agents, loops, and adjust mention
## 19.15.3
### Patch Changes
- [#1097](https://github.com/primer/octicons/pull/1097) [`ce04eca0`](https://github.com/primer/octicons/commit/ce04eca0b9c33cbc3586abd57386e63d97bff7fa) Thanks [@TylerJDev](https://github.com/TylerJDev)! - Add outlined sparkle icon
## 19.15.2
### Patch Changes
- [#1070](https://github.com/primer/octicons/pull/1070) [`795101e3`](https://github.com/primer/octicons/commit/795101e3a46d6835fb2e091384033d8962ab08d1) Thanks [@smockle](https://github.com/smockle)! - Add `pause` icon
## 19.15.1
### Patch Changes
- [#1078](https://github.com/primer/octicons/pull/1078) [`8c9b6112`](https://github.com/primer/octicons/commit/8c9b611271805a436b306beebd8400b502f4f386) Thanks [@francinelucca](https://github.com/francinelucca)! - fix 24px id-badge asset [#1048](https://github.com/primer/octicons/pull/1048)
* [`818a40c5`](https://github.com/primer/octicons/commit/818a40c5d5dec81ad048f3257f092f660b7c8ee5) Thanks [@jonrohan](https://github.com/jonrohan)! - Update mark-github-24 sizing [#1050](https://github.com/primer/octicons/pull/1050)
## 19.15.0
### Minor Changes
- [#1063](https://github.com/primer/octicons/pull/1063) [`6481783a`](https://github.com/primer/octicons/commit/6481783a5a7258cc4d7981a0510de56be05a2dc3) Thanks [@dylanatsmith](https://github.com/dylanatsmith)! - Add square-circle icon
## 19.14.0
### Minor Changes
- [#1037](https://github.com/primer/octicons/pull/1037) [`7402e69c`](https://github.com/primer/octicons/commit/7402e69c4d928b12340cb2430bb942ae7d96c6ba) Thanks [@jonrohan](https://github.com/jonrohan)! - Update octicons-react to use presentational attributes over inline styles for base styles
* [#1047](https://github.com/primer/octicons/pull/1047) [`48198033`](https://github.com/primer/octicons/commit/481980330efce92501df9a388b27314a3f86f182) Thanks [@joshblack](https://github.com/joshblack)! - Add support for SVG props to base icons
## 19.13.0
### Minor Changes
- [#1041](https://github.com/primer/octicons/pull/1041) [`ef89a78f`](https://github.com/primer/octicons/commit/ef89a78f9c0b92a32b7476b5680c327bcd8a6d64) Thanks [@lukasoppermann](https://github.com/lukasoppermann)! - Adds sparkles icon (3 sparkles)
* [#1027](https://github.com/primer/octicons/pull/1027) [`12c6fb00`](https://github.com/primer/octicons/commit/12c6fb0033c8f9dd22b5e8f93ddf3dff9bb7acb1) Thanks [@joshblack](https://github.com/joshblack)! - Update the build output to reduce number of generated assets included in the package on npm
## 19.12.0
### Minor Changes
- [#1033](https://github.com/primer/octicons/pull/1033) [`7a5ac858`](https://github.com/primer/octicons/commit/7a5ac85800359eb1ee6c98c90533c5f344e6532d) Thanks [@colebemis](https://github.com/colebemis)! - Update `thumbsup` and `thumbsdown` icons
## 19.11.0
### Minor Changes
- [#1028](https://github.com/primer/octicons/pull/1028) [`d27ea2f6`](https://github.com/primer/octicons/commit/d27ea2f6b52c5d26d4118259c86e4c91e58cfd56) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Adding ai-model icon at 16 & 24px
## 19.10.0
### Minor Changes
- [#983](https://github.com/primer/octicons/pull/983) [`30be326a`](https://github.com/primer/octicons/commit/30be326ae23b108fd31decfd7823171150421bc4) Thanks [@lukasoppermann](https://github.com/lukasoppermann)! - Add multiple missing icons
### Patch Changes
- [#1020](https://github.com/primer/octicons/pull/1020) [`449d81f1`](https://github.com/primer/octicons/commit/449d81f1b09bcbc0752ebc35d175a8b729022b55) Thanks [@joshblack](https://github.com/joshblack)! - Update types for @primer/octicons-react to explicitly include extensions for different moduleResolution settings
## 19.9.0
### Minor Changes
- [#1008](https://github.com/primer/octicons/pull/1008) [`c5786ff2`](https://github.com/primer/octicons/commit/c5786ff2f3fb9ebca2405bb8d6cc53268b12674f) Thanks [@joshblack](https://github.com/joshblack)! - Update ESM import to use mjs extension when in parent CommonJS module
### Patch Changes
- [#1007](https://github.com/primer/octicons/pull/1007) [`79b93954`](https://github.com/primer/octicons/commit/79b93954c6857e81a685066c1b1205893e7161c5) Thanks [@joshblack](https://github.com/joshblack)! - Update octicons in React to no longer set `role="img"` if the icon is aria-hidden.
## 19.8.0
### Minor Changes
- [#976](https://github.com/primer/octicons/pull/976) [`15ea1e43`](https://github.com/primer/octicons/commit/15ea1e43510a55a5f77d4f4bc76f5033d6655997) Thanks [@UnicodeRogue](https://github.com/UnicodeRogue)! - Adds filter remove octicon
## 19.7.0
### Minor Changes
- [#980](https://github.com/primer/octicons/pull/980) [`5c207929`](https://github.com/primer/octicons/commit/5c207929bdda29e910f2c5b2f6df9de6ef902b84) Thanks [@gavinmn](https://github.com/gavinmn)! - Fix Feed icon alignment issue and name collision
## 19.6.0
### Minor Changes
- [#977](https://github.com/primer/octicons/pull/977) [`e2a0cbdb`](https://github.com/primer/octicons/commit/e2a0cbdbd0566301e295ea38ffb4367c4650c656) Thanks [@gavinmn](https://github.com/gavinmn)! - Add new Feed icons
## 19.5.0
### Minor Changes
- [#970](https://github.com/primer/octicons/pull/970) [`640441ee`](https://github.com/primer/octicons/commit/640441ee2935c85bb3e22022d4fb946be9b8d5c6) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Update repo-clone and repo-pull, add 24px versions
### Patch Changes
- [#966](https://github.com/primer/octicons/pull/966) [`b8a4b4dc`](https://github.com/primer/octicons/commit/b8a4b4dc47f734db7893fe50e93703f2b1d07a2a) Thanks [@gavinmn](https://github.com/gavinmn)! - Fix `pin-slash` bug
## 19.4.0
### Minor Changes
- [#962](https://github.com/primer/octicons/pull/962) [`5805622c`](https://github.com/primer/octicons/commit/5805622c1f9005a4c81a7e7fb09225f2a0e31af4) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Edited small details on `copilot-warning` and `copilot-error` to maintain consistency with the rest of the copilot icon set.
* [#961](https://github.com/primer/octicons/pull/961) [`e92cb36a`](https://github.com/primer/octicons/commit/e92cb36aedc3a9c28b8502733e8c30d01d716bb6) Thanks [@gavinmn](https://github.com/gavinmn)! - Save file-directory-symlink-16.svg, file-directory-symlink-24.svg
## 19.3.0
### Minor Changes
- [#953](https://github.com/primer/octicons/pull/953) [`d3cb9cd8`](https://github.com/primer/octicons/commit/d3cb9cd8b5186a05eb26159f9c97754bef9ea127) Thanks [@gavinmn](https://github.com/gavinmn)! - Add Tracked By states
## 19.2.0
### Minor Changes
- [#959](https://github.com/primer/octicons/pull/959) [`268b2021`](https://github.com/primer/octicons/commit/268b2021bed7b12ff878e999d8b532534b1e2dcc) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Add pivot-column icon
* [#932](https://github.com/primer/octicons/pull/932) [`ea81ec17`](https://github.com/primer/octicons/commit/ea81ec17f0d3d8e74d53e484f551166339af3a17) Thanks [@green6erry](https://github.com/green6erry)! - Add `id`, `title`, and `aria-labelledby` props to icon components
- [#957](https://github.com/primer/octicons/pull/957) [`ab786838`](https://github.com/primer/octicons/commit/ab786838f7ec93523b82c2905e37b9e0c8639e43) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Update copilot octicons for consistency
* [#956](https://github.com/primer/octicons/pull/956) [`16318b6b`](https://github.com/primer/octicons/commit/16318b6b7ba9abcf75c8a17f8ea2204128f9541a) Thanks [@gavinmn](https://github.com/gavinmn)! - Add undo / redo icons
## 19.1.0
### Minor Changes
- [#933](https://github.com/primer/octicons/pull/933) [`af6edab9`](https://github.com/primer/octicons/commit/af6edab99d51f31eac23395b016dd988e34ef05d) Thanks [@stvehayes](https://github.com/stvehayes)! - Add `devices` icon
* [#950](https://github.com/primer/octicons/pull/950) [`8f0edd9e`](https://github.com/primer/octicons/commit/8f0edd9e3aade3901a10d133e14f0561919c945d) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Updates the `pin` icon with a flipped composition, and adds `pin-slash`
- [#949](https://github.com/primer/octicons/pull/949) [`f6796914`](https://github.com/primer/octicons/commit/f6796914732ef96052585adbd8dcccb554bfb2d6) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Updating `move-to-top` and `move-to-bottom` to fix logic and alignment issues.
## 19.0.0
### Major Changes
- [#943](https://github.com/primer/octicons/pull/943) [`a38ae2d2`](https://github.com/primer/octicons/commit/a38ae2d2cf0b51259be0ab9bc19052c4ddc64a09) Thanks [@broccolinisoup](https://github.com/broccolinisoup)! - Remove support for `Octicon`
Update peer dependency React version to support >=16.3
Update icons to use React.forwardRef
### Minor Changes
- [#937](https://github.com/primer/octicons/pull/937) [`6c94e0e8`](https://github.com/primer/octicons/commit/6c94e0e851c5c5b30cb7ddf73899cde54bf8e205) Thanks [@gavinmn](https://github.com/gavinmn)! - Add 12px `×` icon
## 18.3.0
### Minor Changes
- [#934](https://github.com/primer/octicons/pull/934) [`3707c091`](https://github.com/primer/octicons/commit/3707c0917c53eb862457673ba5aa0dfc544be434) Thanks [@gavinmn](https://github.com/gavinmn)! - Add project-template-24.svg, project-template-16.svg
## 18.2.0
### Minor Changes
- [#928](https://github.com/primer/octicons/pull/928) [`4135bc38`](https://github.com/primer/octicons/commit/4135bc38f8592906cfbe2ac6f6772aae1fe049cf) Thanks [@gavinmn](https://github.com/gavinmn)! - Add discussion state Octicons
## 18.1.0
### Minor Changes
- [#927](https://github.com/primer/octicons/pull/927) [`ffd32dd6`](https://github.com/primer/octicons/commit/ffd32dd67e7599041e3e49867e16282e486b8f36) Thanks [@gavinmn](https://github.com/gavinmn)! - Add passkey-fill-24 and passkey-fill-16 octicons
## 18.0.0
### Major Changes
- [#914](https://github.com/primer/octicons/pull/914) [`4d558ed9`](https://github.com/primer/octicons/commit/4d558ed962593dedde3d294194dce7c9419ee355) Thanks [@omerbensaadon](https://github.com/omerbensaadon)! - Update icon naming conventions for Tracks and Tracked By:
- `issue-tracked-by` → `issue-tracks`
- `issue-tracked-in` → `issue-tracked-by`
### Minor Changes
- [#924](https://github.com/primer/octicons/pull/924) [`6b494dfe`](https://github.com/primer/octicons/commit/6b494dfe07735fd343889678bfb0d13561396dc8) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Added missing 24px version of shield-slash-24.svg
## 17.12.0
### Minor Changes
- [#904](https://github.com/primer/octicons/pull/904) [`ad0eb569`](https://github.com/primer/octicons/commit/ad0eb5699661138ee04baf8938fbb6f291f9f060) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Edit: Upload and download icons
Add: Move to start, end, top, and bottom icons
* [#918](https://github.com/primer/octicons/pull/918) [`082f722d`](https://github.com/primer/octicons/commit/082f722d1b49ce148830f0e396a5f0933afaaf2a) Thanks [@gavinmn](https://github.com/gavinmn)! - Add 24pt merge queue icon
- [#919](https://github.com/primer/octicons/pull/919) [`bbff0d13`](https://github.com/primer/octicons/commit/bbff0d13c08a0cebafed32d7787ae216c9b26778) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Save zoom-in-24.svg, zoom-out-24.svg, zoom-out-16.svg, zoom-in-16.svg
## 17.11.1
### Patch Changes
- [#905](https://github.com/primer/octicons/pull/905) [`cbbc519f`](https://github.com/primer/octicons/commit/cbbc519ffd31eaf38d5d5b1e068ad4506d0d1e27) Thanks [@gr2m](https://github.com/gr2m)! - prefix relative paths with `./` in ESM exports paths
## 17.11.0
### Minor Changes
- [#895](https://github.com/primer/octicons/pull/895) [`ce11fb3b`](https://github.com/primer/octicons/commit/ce11fb3b3c67b9c0f4f69bec14e5a962b189cba2) Thanks [@joshblack](https://github.com/joshblack)! - Update the npm package for `@primer/octicons-react` to include the `exports` field and explicitly list out files in `package.json`
* [#902](https://github.com/primer/octicons/pull/902) [`4cbc043a`](https://github.com/primer/octicons/commit/4cbc043a81f81ad23f5e5bbb5dc687fe9f550877) Thanks [@gavinmn](https://github.com/gavinmn)! - Save sparkle-fill-16.svg
- [#903](https://github.com/primer/octicons/pull/903) [`caf958be`](https://github.com/primer/octicons/commit/caf958be9c695ff9ee4381328a555f12b0d830fa) Thanks [@gavinmn](https://github.com/gavinmn)! - Save fiscal-host-16.svg
### Patch Changes
- [#894](https://github.com/primer/octicons/pull/894) [`410831bc`](https://github.com/primer/octicons/commit/410831bc3d3aee3b816fb4172031a470b7b1e38e) Thanks [@langermank](https://github.com/langermank)! - [Bug] up/down chevron alignment fix
## 17.10.2
### Patch Changes
- [#886](https://github.com/primer/octicons/pull/886) [`b5a1530f`](https://github.com/primer/octicons/commit/b5a1530f441e5b2f7b3c874fe669c5d0d1838d9c) Thanks [@eliperkins](https://github.com/eliperkins)! - Upgrade to latest version of SVG Optimizer to remove invalid SVG paths on iOS, macOS and other native Apple target platforms.
## 17.10.1
### Patch Changes
- [#882](https://github.com/primer/octicons/pull/882) [`503bafb9`](https://github.com/primer/octicons/commit/503bafb9578ea307fed3b261a1f8f9cbaea1c346) Thanks [@manuelpuyol](https://github.com/manuelpuyol)! - Use parameter defaults instead of defaultProps
* [#883](https://github.com/primer/octicons/pull/883) [`8a039a7b`](https://github.com/primer/octicons/commit/8a039a7befa6b542404f416fac3f5c9ec99099cc) Thanks [@eliperkins](https://github.com/eliperkins)! - Remove fill-rule from SVGs using picosvg as an optimization step
## 17.10.0
### Minor Changes
- [#874](https://github.com/primer/octicons/pull/874) [`3ff5aa6`](https://github.com/primer/octicons/commit/3ff5aa669d33a88048825d229656abfa459e4d64) Thanks [@gavinmn](https://github.com/gavinmn)! - Add rel-file-path-16.svg, rel-file-path-24.svg
* [#878](https://github.com/primer/octicons/pull/878) [`5797f85`](https://github.com/primer/octicons/commit/5797f859859df31cd769e102fbf518ccaf9a976f) Thanks [@CameronFoxly](https://github.com/CameronFoxly)! - Save unlink-16.svg, unlink-24.svg
- [#879](https://github.com/primer/octicons/pull/879) [`2fa8425`](https://github.com/primer/octicons/commit/2fa8425dab93346cd5d8b44bfc3709f0126e19fb) Thanks [@gavinmn](https://github.com/gavinmn)! - Save read-32.svg, unread-32.svg, read-48.svg, unread-48.svg
* [#873](https://github.com/primer/octicons/pull/873) [`0d1b1ff`](https://github.com/primer/octicons/commit/0d1b1ffca5334c6207cf975f69459153f1d1cbfd) Thanks [@gavinmn](https://github.com/gavinmn)! - Add Goal icons
- [#877](https://github.com/primer/octicons/pull/877) [`3916b29`](https://github.com/primer/octicons/commit/3916b29935d9845eec8726cc389b98281bc42b02) Thanks [@gavinmn](https://github.com/gavinmn)! - Save sponsor-tiers-16.svg, sponsor-tiers-24.svg
## 17.9.0
### Minor Changes
- [#862](https://github.com/primer/octicons/pull/862) [`e15fe00`](https://github.com/primer/octicons/commit/e15fe007224d2785878b78dec36821373c75cbf7) Thanks [@ashygee](https://github.com/ashygee)! - Add project-roadmap icons. Thanks @ohiosveryown and @gavinmn!
* [#861](https://github.com/primer/octicons/pull/861) [`1a6887d`](https://github.com/primer/octicons/commit/1a6887df3423ff539f6959d0fe8bb23c17dafa70) Thanks [@ashygee](https://github.com/ashygee)! - Add project-symlink icons. Thanks @peterloveland!
- [#860](https://github.com/primer/octicons/pull/860) [`8a98d2b`](https://github.com/primer/octicons/commit/8a98d2b727623aa089912721513a68e8d4c0fc3f) Thanks [@ashygee](https://github.com/ashygee)! - Save clock-fill-16.svg, clock-fill-24.svg, skip-fill-16.svg, skip-fil… Thanks @dylanatsmith!
## 17.8.0
### Minor Changes
- [#858](https://github.com/primer/octicons/pull/858) [`199f00e`](https://github.com/primer/octicons/commit/199f00e99e0fc3c5abb6e78f2255393a67c08fc6) Thanks [@heyamie](https://github.com/heyamie)! - Add diagonal arrows as 16px
* [#857](https://github.com/primer/octicons/pull/857) [`da2c78f`](https://github.com/primer/octicons/commit/da2c78f103bbfd65aa046ea763325380592581a7) Thanks [@gavinmn](https://github.com/gavinmn)! - Add `issue-tracked-in` and `issue-tracked-by` icons
## 17.7.0
### Minor Changes
- [#849](https://github.com/primer/octicons/pull/849) [`f6c8d2b`](https://github.com/primer/octicons/commit/f6c8d2b37a4f38d99d5f9279f793a88a020933cf) Thanks [@broccolinisoup](https://github.com/broccolinisoup)! - Add `tabIndex` prop to React icon components
## 17.6.0
### Minor Changes
- [#848](https://github.com/primer/octicons/pull/848) [`ed25e50`](https://github.com/primer/octicons/commit/ed25e501f614afe1b43aa09c11f344d8b47a233d) Thanks [@ashygee](https://github.com/ashygee)! - Add filled alert icons
- alert-fill-16
- alert-fill-24
* [#847](https://github.com/primer/octicons/pull/847) [`2f9b32e`](https://github.com/primer/octicons/commit/2f9b32e6b48cb58adac95552d6e7ddb2bf405a94) Thanks [@ashygee](https://github.com/ashygee)! - - add log-24.svg (TY @edokoa!)
### Patch Changes
- [#831](https://github.com/primer/octicons/pull/831) [`57f364a`](https://github.com/primer/octicons/commit/57f364a7e234080781355cd57fcf3bdd75b05af4) Thanks [@josepmartins](https://github.com/josepmartins)! - Adjust flex wrap in UI examples.Fixes #731
## 17.5.0
### Minor Changes
- [#827](https://github.com/primer/octicons/pull/827) [`f186ad3`](https://github.com/primer/octicons/commit/f186ad3a07bd30954088e9e63936f81dc735bbcd) Thanks [@edokoa](https://github.com/edokoa)! - Save `accessibility-inset` 16px icon
* [#828](https://github.com/primer/octicons/pull/828) [`6c0d207`](https://github.com/primer/octicons/commit/6c0d20761f62dad118db48e72d6e0b20210c38cb) Thanks [@edokoa](https://github.com/edokoa)! - Save `shield-slash` 16px icon
## 17.4.1
### Patch Changes
- [#815](https://github.com/primer/octicons/pull/815) [`41c088e`](https://github.com/primer/octicons/commit/41c088e11862a2f693c7670deb3a12daa7a04089) Thanks [@ashygee](https://github.com/ashygee)! - Correct alignment for search-24
## 17.4.0
### Minor Changes
- [#810](https://github.com/primer/octicons/pull/810) [`840f4eb`](https://github.com/primer/octicons/commit/840f4eb7d89020c36a8f8eeaa6f69042c67adc8e) Thanks [@ashygee](https://github.com/ashygee)! - - modifies tasklist icon proposed in https://github.com/github/primer/issues/746
- adds a new checkbox icon using metaphor from previous tasklist metaphor
* [#807](https://github.com/primer/octicons/pull/807) [`d280148`](https://github.com/primer/octicons/commit/d280148ffaa43f3260b06ed723a059f72fc0ee3b) Thanks [@edokoa](https://github.com/edokoa)! - Add `cache` 16px icon
- [#801](https://github.com/primer/octicons/pull/801) [`8e5dcfc`](https://github.com/primer/octicons/commit/8e5dcfcac8dda5c9d41ba8fb3d5b7d5d14ca3943) Thanks [@gavinmn](https://github.com/gavinmn)! - Save paperclip-16.svg, paperclip-24.svg
* [#806](https://github.com/primer/octicons/pull/806) [`27575d0`](https://github.com/primer/octicons/commit/27575d0e67eb0e6557856d18535b75550a364e66) Thanks [@ashygee](https://github.com/ashygee)! - Save git-merge-queue-16.svg
- [#811](https://github.com/primer/octicons/pull/811) [`a005869`](https://github.com/primer/octicons/commit/a0058690fc56e5740817e6f5060ecf0473c6fc46) Thanks [@ashygee](https://github.com/ashygee)! - Save command-palette-24.svg, command-palette-16.svg
### Patch Changes
- [#803](https://github.com/primer/octicons/pull/803) [`5090b7a`](https://github.com/primer/octicons/commit/5090b7acab73dc3f0f25936fceefdeb16bc19d2f) Thanks [@ashygee](https://github.com/ashygee)! - fix table icon
## 17.3.0
### Minor Changes
- [#794](https://github.com/primer/octicons/pull/794) [`608d639`](https://github.com/primer/octicons/commit/608d6399af450f8eda444c73069b59d7fc10eaa4) Thanks [@gavinmn](https://github.com/gavinmn)! - Add `copilot` icons
* [#766](https://github.com/primer/octicons/pull/766) [`8df01b5`](https://github.com/primer/octicons/commit/8df01b5031dac3bd1f11071bac9d7d699e69e4b5) Thanks [@edokoa](https://github.com/edokoa)! - Add 24px `repo-locked` icon
## 17.2.0
### Minor Changes
- [#789](https://github.com/primer/octicons/pull/789) [`d59a5e2`](https://github.com/primer/octicons/commit/d59a5e2095495c9f8a2d9ad10072782df3714522) Thanks [@ashygee](https://github.com/ashygee)! - Add file-added, file-removed, file-moved
Update file to be consistent in height with other file icons
### Patch Changes
- [#786](https://github.com/primer/octicons/pull/786) [`0dede7f`](https://github.com/primer/octicons/commit/0dede7f202645bde2294b354284ce0592c248815) Thanks [@ashygee](https://github.com/ashygee)! - recenter org icon
## 17.1.0
### Minor Changes
- [#756](https://github.com/primer/octicons/pull/756) [`2993d47`](https://github.com/primer/octicons/commit/2993d4733cbf3acdaf4286a1a5c17e0ced762967) Thanks [@Juliusschaeper](https://github.com/Juliusschaeper)! - Added `cloud` and `cloud-offline` icons
* [#762](https://github.com/primer/octicons/pull/762) [`57105bb`](https://github.com/primer/octicons/commit/57105bbaffeb38de1bb5f8bc33e125bb3968a554) Thanks [@edokoa](https://github.com/edokoa)! - Add 16px `file-directory-open-fill` icon
- [#783](https://github.com/primer/octicons/pull/783) [`47d3018`](https://github.com/primer/octicons/commit/47d30183a944383e1fb28651fe70e01f3a5dbe59) Thanks [@ashygee](https://github.com/ashygee)! - Save sliders-16.svg
## 17.0.0
### Major Changes
- [#736](https://github.com/primer/octicons/pull/736) [`ec8cab8`](https://github.com/primer/octicons/commit/ec8cab891426f759fe665a781e3129241d83de8a) Thanks [@edokoa](https://github.com/edokoa)! - This patch fixes two problems:
- We're adding a non-filled `file-directory` icon to the set.
- We're fixing a problem where the 16px and 24px versions of the `file-directory` icons were mismatched between `fill` and `non-fill` versions of the icon.
**THIS IS A BREAKING CHANGE** and will require re-linking all the `file-directory` icon references to `file-directory-fill`
### Minor Changes
- [#754](https://github.com/primer/octicons/pull/754) [`7a51cb7`](https://github.com/primer/octicons/commit/7a51cb71b108b21aeb9a1716d443df3f23deba28) Thanks [@edokoa](https://github.com/edokoa)! - Add trophy-16.svg, trophy-24.svg
* [#758](https://github.com/primer/octicons/pull/758) [`0d9000c`](https://github.com/primer/octicons/commit/0d9000c50255bac736eb0fbbc1ffee839130a708) Thanks [@edokoa](https://github.com/edokoa)! - Save repo-locked-16.svg
- [#755](https://github.com/primer/octicons/pull/755) [`a520a37`](https://github.com/primer/octicons/commit/a520a374a0a29f47504e1a758e5cbfa0a4033721) Thanks [@Juliusschaeper](https://github.com/Juliusschaeper)! - Second batch of feed icons: merged, forked and achievement
### Patch Changes
- [#751](https://github.com/primer/octicons/pull/751) [`4e768a5`](https://github.com/primer/octicons/commit/4e768a5e427684cd92c87c6b6a0ff5a5dab1e0a4) Thanks [@Crayon2000](https://github.com/Crayon2000)! - Fix typos in build.js
* [#734](https://github.com/primer/octicons/pull/734) [`afde0dd`](https://github.com/primer/octicons/commit/afde0dd4ee74ec32e6babde240b49e27d96f4d30) Thanks [@ashygee](https://github.com/ashygee)! - Modify upload-24.svg to mirror 16px version
## 16.3.1
### Patch Changes
- [#733](https://github.com/primer/octicons/pull/733) [`a57b9ca`](https://github.com/primer/octicons/commit/a57b9ca1361cde081ce2c84f15ca8999639e5792) Thanks [@edokoa](https://github.com/edokoa)! - Modify upload-24.svg to mirror 16px version
## 16.3.0
### Minor Changes
- [#715](https://github.com/primer/octicons/pull/715) [`ab991ab`](https://github.com/primer/octicons/commit/ab991ab318488efc3c02b747168a34e356fad059) Thanks [@edokoa](https://github.com/edokoa)! - Added new icons for:
- `accessibility`
- `apps`
- `id-badge`
- `log`
- `repo-deleted`
- `tab-external`
- `webhook`
* [#708](https://github.com/primer/octicons/pull/708) [`6933ac3`](https://github.com/primer/octicons/commit/6933ac32f87a2cb5efda4fb74b39d1e6199134ce) Thanks [@Juliusschaeper](https://github.com/Juliusschaeper)! - Added first batch of 16px feed icons:
- `feed-discussion`
- `feed-heart`
- `feed-person`
- `feed-repo`
- `feed-rocket`
- `feed-star`
- `feed-tag`
## 16.2.0
### Minor Changes
- [#706](https://github.com/primer/octicons/pull/706) [`2c43706`](https://github.com/primer/octicons/commit/2c4370658663817a216895ee7831a00d413f7d4e) Thanks [@Juliusschaeper](https://github.com/Juliusschaeper)! - Add `code-of-conduct` icon
### Patch Changes
- [#685](https://github.com/primer/octicons/pull/685) [`c59c097`](https://github.com/primer/octicons/commit/c59c097c23ccea6409c9e2f235b64a50b4d580dd) Thanks [@jonrohan](https://github.com/jonrohan)! - Formatting changes to the main readme file, including dark mode support.
## 16.1.1
### Patch Changes
- [#681](https://github.com/primer/octicons/pull/681) [`c394d9a`](https://github.com/primer/octicons/commit/c394d9a556666beed4912797fb78f34190796511) Thanks [@jonrohan](https://github.com/jonrohan)! - Adding changesets workflow to octicons for releasing.
* [#684](https://github.com/primer/octicons/pull/684) [`9ed6154`](https://github.com/primer/octicons/commit/9ed615464cc405d9264cb933d4fe5f05ff14a219) Thanks [@ashygee](https://github.com/ashygee)! - Add 12px usage guidelines
- [#677](https://github.com/primer/octicons/pull/677) [`777f229`](https://github.com/primer/octicons/commit/777f2290b4662f2d769096ac3c121e61e92a0ff2) Thanks [@benkoshy](https://github.com/benkoshy)! - update: installation instructions
## 16.1.0
### 🚀 New features
- Added first set of 12px filled icons https://github.com/primer/octicons/pull/676
### 🐛 Bug fix
- Adjusted 'no-entry' size to match other circle icons https://github.com/primer/octicons/pull/673
## 16.0.0
### 💥 Breaking changes
- Rename 16px `select-single` icon to `single-select` https://github.com/primer/octicons/pull/665
### 🚀 New features
- `iterations` https://github.com/primer/octicons/pull/667
### 🧽 Chores
- Bump dependencies
## 15.2.0
### 🚀 New features
- Add `stack` icons https://github.com/primer/octicons/pull/659
- Add `person-fill` and `telescope-fill` icons https://github.com/primer/octicons/pull/660
## 15.1.0
### 🚀 New features
- `bell-fill-16` https://github.com/primer/octicons/pull/657
## 15.0.1
### 🐛 Bug fix
- Modify `duplicate` icon to differentiate from `copy` https://github.com/primer/octicons/pull/647
## 15.0.0
### 💥 Breaking changes
- Rename `duplicate` icon to `copy` https://github.com/primer/octicons/pull/643
- Rename `clippy` icon to `paste` https://github.com/primer/octicons/pull/643
## 14.2.2
### 🐛 Bug fix
- Update `issue-reopened` https://github.com/primer/octicons/pull/633
## 14.2.1
### 🐛 Bug fix
- fix vectors for 24px sort icons https://github.com/primer/octicons/pull/627 (🙏 @metonym)
## 14.2.0
### 🚀 New features
- `key-asterisk-16` https://github.com/primer/octicons/pull/623
- `sort-asc` https://github.com/primer/octicons/pull/619
- `sort-desc` https://github.com/primer/octicons/pull/619
### 🧽 Chores
- Remove unused dependency on nokogiri https://github.com/primer/octicons/pull/609 (🙏 @cschlack)
## 14.1.0
### 🚀 New features
- `git-pull-request-draft` https://github.com/primer/octicons/pull/613
- `git-pull-request-closed` https://github.com/primer/octicons/pull/613
## 14.0.0
### 💥 Breaking changes
- Remove `octoface` https://github.com/primer/octicons/pull/611
- Rename `git-fork-24` to `repo-forked-24` https://github.com/primer/octicons/pull/593
### 🚀 New features
- `number` https://github.com/primer/octicons/pull/592
- `hash` (previously `number`) https://github.com/primer/octicons/pull/592
- `diamond` https://github.com/primer/octicons/pull/616
- `single-select` https://github.com/primer/octicons/pull/612
- `rows` https://github.com/primer/octicons/pull/617
- `columns` https://github.com/primer/octicons/pull/617
- `issue-draft` https://github.com/primer/octicons/pull/614
### 💅 Enhancements
- `issue-opened` https://github.com/primer/octicons/pull/614
- `issue-closed` https://github.com/primer/octicons/pull/614
### 🐛 Fixes
- Fix 24px `arrow-up` icon https://github.com/primer/octicons/pull/594
- Prevent clipping using `overflow: visible` https://github.com/primer/octicons/pull/607
## 13.0.0
### 🚀 New features
- `table` https://github.com/primer/octicons/pull/564
- `person-add` https://github.com/primer/octicons/pull/573
- `blocked` https://github.com/primer/octicons/pull/576
- `duplicate` https://github.com/primer/octicons/pull/576
- `dependabot`https://github.com/primer/octicons/pull/585
- `codescan` https://github.com/primer/octicons/pull/588
- `browser` https://github.com/primer/octicons/pull/575
- `sidebar` icons https://github.com/primer/octicons/pull/569
- `codespaces` https://github.com/primer/octicons/pull/587
### 💥 Breaking changes
- Remove 24px `insights` icon https://github.com/primer/octicons/pull/574
- Remove 24px `copy` icon https://github.com/primer/octicons/pull/586
### 💅 Enhancements
- Use more explicit dependencies for Rails helper https://github.com/primer/octicons/pull/565
### 🐛 Fixes
- Fix `megaphone-16` https://github.com/primer/octicons/pull/554
- Fix `circle` icon https://github.com/primer/octicons/pull/584
## 12.1.0
### React
### 💅 Enhancements
- Add icon-specific class names to each icon component https://github.com/primer/octicons/pull/453 @FloEdelmann
- Add `fill` prop to each icon component https://github.com/primer/octicons/pull/551 @macno
## 12.0.0
### 🚀 New features
- `bug` (https://github.com/primer/octicons/pull/543)
- `multi-select` (https://github.com/primer/octicons/pull/534)
### 💅 Enhancements
- Make octicon helper slightly faster (@jhawthorn & @seejohnrun) (#536)
### 💥 Breaking changes
- Rename 16px `trashcan` icon to `trash` (@fermion 🙇) (https://github.com/primer/octicons/pull/538)
### 🧽Chores
- Dependency updates (#525, #524, #523, #522, #520)
## 11.3.0
### 🚀 New features
- `number` (https://github.com/primer/octicons/pull/541)
- `video` (https://github.com/primer/octicons/pull/540)
### 🐛 Fixes
- Fix rendering of arrows in Safari (@aaronshekey https://github.com/primer/octicons/pull/527)
## 11.2.0
### 🚀 New features
- `strikethrough` (https://github.com/primer/octicons/pull/518)
### 🐛 Fixes
- Align `plus` and `dash` icon (https://github.com/primer/octicons/pull/447)
- Small edits in JS documentation (https://github.com/primer/octicons/pull/499)
### 🧽Chores
- Dependency updates
## 11.1.0
### 🚀 New features
- `container` (https://github.com/primer/octicons/pull/507)
- `squirrel` 24px icon (https://github.com/primer/octicons/pull/508)
### 🐛 Fixes
- Corrected stroke for 24px `smiley` (https://github.com/primer/octicons/pull/509)
## 11.0.0
### 💅 Enhancements
- Cache retrieval of Octicon SVG paths (https://github.com/primer/octicons/pull/491)
### 💥 Breaking changes
- Fix 24px icon names https://github.com/primer/octicons/pull/465 (@BenJetson 🙇)
- `unverifed-24.svg` → `unverified-24.svg`
- `file-symlink-24.svg` → `file-symlink-file-24.svg`
- `fire-24.svg` → `flame-24.svg`
- `eye-slash-24.svg` → `eye-closed-24.svg`
- Remove 24px `settings` icon. Use `gear` instead https://github.com/primer/octicons/pull/493
## 10.1.0
### 🚀 New features
- [`arrow-switch`](https://github.com/primer/octicons/pull/486)
- [`file-badge`](https://github.com/primer/octicons/pull/464)
- [`x-circle`, `x-circle-fill`, `circle`](https://github.com/primer/octicons/pull/455)
### 🐛 Fixes
- Corrected positioning for `triangle-down` [#459](https://github.com/primer/octicons/pull/459)
### 🧽Chores
- Dependency updates
## 10.0.0
### All packages
- We've given Octicons a new look ✨ Some icons have new names and some icons haven't been redesigned yet. The following table documents those changes. If you're using an octicon in v9.x that doesn't have an equivalent in v10.0 yet, let us know by [opening an issue](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D).
| v9.x | v10.0 | Notes |
| ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `arrow-small-down` | `arrow-down` | |
| `arrow-small-left` | `arrow-left` | |
| `arrow-small-right` | `arrow-right` | |
| `arrow-small-up` | `arrow-up` | |
| `browser` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `bug` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `circuit-board` | `cpu` | |
| `cloud-download` | `download` | |
| `cloud-upload` | `upload` | |
| `dashboard` | `meter` | |
| `dependent` | `package-dependents` | |
| `device-camera` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `file-pdf` | `file` | |
| `file-symlink-directory` | `file-submodule` | |
| `gist-secret` | `lock` | |
| `gist` | `code-square` | |
| `github-action` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `heart-outline` | `heart` | |
| `internal-repo` | `repo` | |
| `jersey` | `people` | |
| `keyboard` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `line-arrow-down` | `arrow-down` | |
| `line-arrow-left` | `arrow-left` | |
| `line-arrow-right` | `arrow-right` | |
| `line-arrow-up` | `arrow-up` | |
| `mail-read` | `mail` | |
| `no-newline` | `no-entry` | |
| `paintcan` | `paintbrush` | |
| `plus-small` | `plus` | |
| `primitive-dot-stroke` | `dot` | |
| `primitive-dot` | `dot-fill` | |
| `primitive-square` | `square-fill` | |
| `radio-tower` | `broadcast` | |
| `repo-clone` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `repo-force-push` | `repo-push` | |
| `repo-pull` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `repo-template-private` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
| `request-changes` | `diff` | |
| `saved` | `bookmark` | |
| `text-size` | `heading` or `typography` | |
| `unsaved` | `bookmark-slash` | |
| `watch` | `hourglass` | |
| `workflow-all` | | [Request this icon](https://github.com/primer/octicons/issues/new?assignees=&labels=icon+request&template=icon-request.md&title=%5BIcon+request%5D) |
- We designed a set of 24px icons—as well as 16px icons—to accommodate interfaces that need larger icons. All package implementations now choose which SVG to render based on the size passed in.
### React (@primer/octicons-react)
- Icon components (e.g. `AlertIcon`, `ArrowRightIcon`, etc.) now accept `size`, `ariaLabel`, `verticalAlign`, and `className` props and can be used on their own. No need to pass them to the `Octicon` component.
```jsx
<AlertIcon size={24} />
```
- Icon components will now choose the best SVG icon to render based on the `size` passed in.
- The `Octicon` component is deprecated. Use icon components on their own instead:
```diff
- <Octicon icon={AlertIcon} />
+ <AlertIcon />
```
#### BREAKING CHANGES 💥
- All icon component names now include `Icon` at the end (e.g. `Alert` → `AlertIcon`).
- In order to enable tree-shaking, we removed the `iconsByName` and `getIconByName` exports.
- `Octicon` no longer accepts `width` or `height` props. Use the `size` prop instead. In cases where the width and height of an icon are not equal (e.g. logos), the height will be set to the value of the `size` prop and the `width` will be scaled proportionally.
- We renamed the `ariaLabel` prop to `aria-label` to be consistent with React: https://reactjs.org/docs/accessibility.html#wai-aria
```diff
- <AlertIcon ariaLabel="alert">
+ <AlertIcon aria-label="alert">
```
- Setting `verticalAlign="top"` on the `Octicon` component or any icon component will now apply a `vertical-align: top;` style to the `<svg>`. Previously, we were translating "top" to "text-top." So setting `verticalAlign="top"` would apply a `vertical-align: text-top;` style to the `<svg>`. If you want a vertical alignment of "text-top," set the `verticalAlign` prop to `"text-top"`.
- Custom icon components passed to the `Octicon` component now need to render the entire `<svg>`, not just the `<path>`.
```diff
function CirclesIcon() {
return (
- <React.Fragment>
+ <svg viewBox="0 0 30 10" width="30" height="10">
<circle r={5} cx={5} cy={5}/>
<circle r={5} cx={15} cy={5}/>
<circle r={5} cx={25} cy={5}/>
- </React.Fragment>
+ </svg>
)
}
- CirclesIcon.size = [30, 10]
```
### JavaScript (@primer/octicons)
#### BREAKING CHANGES 💥
- The structure of each icon object has been updated to allow support multiple SVGs per icon:
##### Before
```js
octicons.alert
// {
// symbol: 'alert',
// keywords: ['warning', 'triangle', 'exclamation', 'point'],
// toSVG: [Function],
// width: 16,
// height: 16,
// path: '<path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/>',
// options: {
// version: '1.1',
// width: '16',
// height: '16',
// viewBox: '0 0 16 16',
// class: 'octicon octicon-alert',
// 'aria-hidden': 'true'
// },
// }
```
#### After
```js
octicons.alert
// {
// symbol: 'alert',
// keywords: ['warning', 'triangle', 'exclamation', 'point'],
// toSVG: [Function]
// heights: {
// 16: {
// width: 16,
// path: '<path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/>',
// options: {
// version: '1.1',
// width: '16',
// height: '16',
// viewBox: '0 0 16 16',
// class: 'octicon octicon-alert',
// 'aria-hidden': 'true'
// },
// },
// 24: ...
// }
// }
```
## 9.6.0
### features
- New icon `north-star` https://github.com/primer/octicons/pull/380
## 9.5.0
### features
- New icon `internal-repo` https://github.com/primer/octicons/pull/375
## 9.4.0
### features
- New icons `heart-outline` `infinity` `line-arrow-up` `line-arrow-down` `line-arrow-right` `line-arrow-left` https://github.com/primer/octicons/pull/365
### Chores
- Contributing docs updates and issue template updates #367
### Bugs
- Update `heart` glyphs removing extra points https://github.com/primer/octicons/pull/365
## 9.3.1
### Bugfix
- Workflow icon had a cutoff edge.
## 9.3.0
### 🚀 New features
- Workflow icons https://github.com/primer/octicons/pull/356 @ashygee
- Allow 'unset' value for verticalAlign property https://github.com/primer/octicons/pull/354 @Fs00
## 9.2.0
### 🚀 New features
- [x] New icons for save/unsave and primitive dot stroke https://github.com/primer/octicons/pull/351 @ashygee @colinkeany
### 🧽 Chores
- [x] Migrating to new yml actions syntax https://github.com/primer/octicons/pull/332 @max & @jonrohan
- [x] Update jekyll gemspec to support Jekyll 4.0 https://github.com/primer/octicons/pull/347 @ntotten
### 🐛 Bugs
- [x] Octicons react isn't including className https://github.com/primer/octicons/pull/271 @pocke
## 9.1.1
### 🐛 Bug Fix
- [x] renamed the original shield icon to `shield-lock` https://github.com/primer/octicons/issues/323 @ashygee
- [x] test for duplicate icons https://github.com/primer/octicons/pull/322 @jonrohan
## 9.1.0
### 🚀 New features
- [x] Adding skip icon https://github.com/primer/octicons/pull/318 @ashygee
## 9.0.0
### 💥 Breaking changes
- [x] Rename `octicons` to `@primer/octicons` https://github.com/primer/octicons/pull/311
- [x] Rename `@githubprimer/octicons-react` to `@primer/octicons-react` https://github.com/primer/octicons/pull/311
### 🚀 New features
- [x] Adding a shield icon https://github.com/primer/octicons/pull/310 @ashygee @donokuda
- [x] Adding new repo icons https://github.com/primer/octicons/issues/316 @superbryntendo
## 8.5.0
- a11y aria-hidden update from @muan https://github.com/primer/octicons/pull/295
- Verified icons poor rendering. @ashygee https://github.com/primer/octicons/pull/297
- Docs update for contributing @ashygee https://github.com/primer/octicons/pull/298
## 8.4.2
### 💅🏼 Enhancement
- Thumbs up/down icons needed some vector improvements. https://github.com/primer/octicons/pull/287
### 🐛 Bug Fix
- Node package missing `build/build.css` file. https://github.com/primer/octicons/pull/292
## 8.4.1
### 🐛 Bug Fix
- Rollup files missing from octicons react package https://github.com/primer/octicons/issues/282
## 8.4.0
### 🏠 Internal
- Using Actions to build and deploy Octicons https://github.com/primer/octicons/pull/276
#### Committers: 1
- Jon Rohan ([jonrohan](https://github.com/jonrohan))
## 8.3.0
- New "changes requested" icon https://github.com/primer/octicons/pull/267
- Contrib Doc Updates https://github.com/primer/octicons/pull/256
- Updating licenses to 2019 https://github.com/primer/octicons/pull/272
## 8.2.0
- Add `fold-up` and `fold-down` icons, courtesy of @pmarsceill
## 8.1.3
- Add `eye-closed` icon, courtesy of @colinkeany
## 8.1.2
- Patch release for failed 8.1.1 release
## 8.1.1
- Fix for `list-ordered` icon https://github.com/primer/octicons/pull/252
- In React Octicons, we set aria-hidden to false if there's an aria-label provided
## 8.1.0
- Add the `arrow-both` icon courtesy of @venetucci
- TypeScript types are now available thanks to @j-f1!
- Fix CI builds for outside contributors (as long as they aren't changing octicons)
- Fix typo in README
- Update README with `@githubprimer/octicons-react scope`
- Publish release candidates from any branch beginning with `release`
## 8.0.0
- Breaking changes in `octicons_react` [#225](https://github.com/primer/octicons/pull/225)
- After the initial release of octicons_react https://github.com/primer/octicons/releases/tag/v7.4.0, we needed to rename the scope of the package. Due to some deployment conflicts in our pipelines.
## 7.4.0
- This release marks the first official version of Octicons for React! Check out the `@github/octicons-react` package on npm for more info, or peruse the long-running PR [#222](https://github.com/primer/octicons/pull/222).
- CI status is now reported to the `#design-ops` Slack channel
- Jekyll Octicons has moved in this repo from `lib/jekyll-octicons` to `lib/octicons_jekyll`
## 7.3.0
- Fix for heart icon https://github.com/primer/octicons/pull/211
- Adding an archive icon created by @colinkeany
- Fixes https://github.com/primer/octicons/issues/182
- Fixed versioning strategy https://github.com/primer/octicons/pull/#208
## Archived releases
### Octicons_node 7.0.0
- Removing `file-text` and `mail-reply` icons. Use `file` and `reply` respectively.
- Removing spritesheet calls and `toSVGUse` method.
### Octicons_gem 5.0.4
- Removing `file-text` and `mail-reply` icons. Use `file` and `reply` respectively.
- Removing spritesheet calls and `to_svg_use` method.
### 6.0.1
Fixes:
- Typo `kebab-veritcal` becomes `kebab-vertical`
### 6.0.0
Added:
- `kebab-horizontal` and `kebab-vertical` icons
- Polyfill for the `Object.assign` function
Removes:
- Removing a duplicate `ellipses` icon from the set. Use `ellipsis` instead.
### 5.0.1
Fixes:
- projects icon renders as a block, using `fill-rule` fixes it
### 5.0.0
Adds:
- `project`
- `note`
- `screen-full`
- `screen-normal`
- More node.js api endpoints for accessing icons https://github.com/primer/octicons/pull/120
- Creating a spritesheet demo https://github.com/primer/octicons/pull/121
Removes:
- Deprecating support for the webfont https://github.com/primer/octicons/pull/117
- Stop checking `/build/` directory into repository https://github.com/primer/octicons/pull/118
- Removing sass as a dependency https://github.com/primer/octicons/pull/119
### 4.4.0
Adds:
- svg.json file that is accessible from node require
### 4.3.0
Fixes:
- Vertical alignment on `italic`
Modifies:
- `person`
- `organization`
### 4.2.1
Fixes:
- Removing inline sourcemap from `min` versions of css.
### 4.2.0
Adds:
- Keywords.json file that has an index of all octicons with alias names
### 4.1.1 (June 16, 2016)
Fixes:
- Putting the `$octicons-font-path` back in the scss file.
### 4.1.0 (June 6, 2016)
Adds:
- Installation docs https://github.com/primer/octicons/pull/94
- `grabber`
- `plus-small`
Modifies:
- `smiley`
Refines:
- Renames `mail-reply` to `reply` and refines its shape.
Fixes:
- Revert license back to SPDX standard
### 4.0.0 (June 6, 2016)
Adds:
- Whole new grunt build system including svg sprite sheet.
- adding css min https://github.com/primer/octicons/pull/60
- adding woff2 format https://github.com/primer/octicons/issues/3
- creates spritesheet of svg files https://github.com/primer/octicons/issues/88
Removes:
- Bower support
Fixes:
- all svg icons include viewBox https://github.com/primer/octicons/issues/87
- license in package.json https://github.com/primer/octicons/issues/85
### 3.5.0 (February 12, 2016)
Adds:
- `unverified`
Refines:
- `verified`
### 3.4.1 (January 24, 2016)
This includes various SVG viewport refinements.
Refines:
- `thumbs-down`
- `logo-github`
### 3.4.0 (January 22, 2016)
Adds:
- `verified`
- `smiley`
Removes:
- `color-mode`
Refines:
- `primitive-dot`
- `horizontal-rule`
- `triangle-down`
- `triangle-up`
- `triangle-left`
- `triangle-right`
- `globe`
- `flame`
- `comment-discussion`
### 3.3.0 (November 12, 2015)
Adds:
- `logo-gist`
Resizes all our SVG to be 16x16 instead of 1024x1024
### 3.2.0 (November 6, 2015)
Adds:
- `bold`
- `text-size`
- `italic`
- `tasklist`
It also normalizes some styling in:
- `list-unordered`
- `list-ordered`
- `quote`
- `mention`
- `bookmark`
- `threebars`
Removes
- `screen-normal`
- `screen-full`
### 3.1.0 (August 13, 2015)
Adds
- `shield`
This thickens stroke widths slightly on the following icons:
- `circle-slash`
- `clock`
- `cloud-upload`
- `cloud-download`
- `dashboard`
- `info`
- `issue-closed`
- `issue`
- `issue-reopened`
- `history`
- `question`
- `search`
Fills `comment-discussion`
Thickens `x` to match `checkmark`
### 3.0.1 (August 10, 2015)
Some files were missing in `3.0.0`
### 3.0.0 (August 10, 2015)
Removes
- `microscope`
- `beer`
- `split`
- `puzzle`
- `steps`
- `podium`
- `timer`
- all `alignment` icons
- all `move` icons
- all `playback` icons
- all `jump` icons
Adds
- `beaker`
- `bell`
- `desktop-download`
- `watch`
Line-weight changes, sizing normalization, and new drawings
- `circle-slash`
- `lock`
- `cloud-upload`
- `cloud-download`
- `plus`
- `✕`
- `broadcast`
- `lock`
- all `repo` icons
- organization
- person
- all `chevrons` & `triangles`
- all `diff` icons
- `clippy`
- all `issue` and circular icons
- `rss`
- `ruby`
- `cancel`
- `settings`
- `mirror`
- `external-link`
- `history`
- `gear`
- `settings`
- `info`
- `history`
- `package`
- `gist-secret`
- `rocket`
- `law`
- `telescope`
- `search`
- `tag`
- `normal-screen`
- `iphone`
- `no-new-line`
- `desktop`
- all `git` icons
- `circuit-board`
- `heart`
- `home`
- `briefcase`
- `wiki`
- `bookmark`
- `briefcase`
- `calendar`
- `color-mode`
- `comment`
- `discussions`
- `credit-card`
- `dashboard`
- `camera`
- `video`
- `bug`
- `desktop`
- `ellipses`
- `eye`
- all `files` & `folders`
- `fold`
- `unfold`
- `gift`
- `graph`
- `hubot`
- `inbox`
- `jersey`
- `keyboard`
- `light-bulb`
- `link`
- `location`
- `mail`
- `mail-read`
- `marker`
- `plug`
- `mute`
- `pencil`
- `push-pin`
- `fullscreen`
- `unfullscreen`
- `server`
- `sign-in`
- `sign-out`
- `tag`
- `terminal`
- `thumbs-up`
- `thumbs-down`
- `trash`
- `unmute`
- `versions`
- `gist`
- `key`
- `megaphone`
- `checklist`
## 2.4.1 (June 2, 2015)
- Add the scss file I forgot to include
## 2.4.0 (June 2, 2015)
- Add `octicons.scss`
- Revert path changes to `sprockets-octicons.scss`, as they broke octicons in sprockets.
## 2.3.0 (May 28, 2015)
- Add a path variable to `sprockets-octicons.scss` to be consistent with octicons.less`
## 2.2.3 (May 21, 2015)
- Use SPDX license identifiers in package.json
## 2.2.2 (April 1, 2015)
Fixes file icons for
- `file-binary`
- `file-code`
- `file-media`
- `file-pdf`
- `file-symlink-file`
- `file-text`
- `file-zip`
## 2.2.1 (March 30, 2015)
- Fix vector artifact and smooth curves in `mark-github`
## 2.2.0 (Feb 18, 2015)
- Add two new icons: `thumbsup` and `thumbsdown`
## 2.0.1 (June 16, 2014)
- Add mention of github.com/logos to the license
## 2.0.0 (June 16, 2014)
- Hello world
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at design-systems@github.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
================================================
FILE: CONTRIBUTING.md
================================================
# Octicons Contribution Guidelines (Currently GitHub Staff only)
Thank you for your interest in contributing to Octicons! We are currently only accepting submissions from GitHub staff and only include icons that are used in the GitHub UI. If you'd like to submit feedback, a bug, or an idea for improvement, please open a new issue in this repo using the appropriate [issue template](https://github.com/primer/octicons/issues/new/choose).
## Icon request and review process
### 1. Icon review request is made
- Icon review requests are made using the [icon request template](https://github.com/github/primer/issues/new?assignees=&labels=octicon%2C+request%2C+needs+triage&template=02-icon-request.md&title=%5BIcon+request%5D+) in the github/primer repo (visible to GitHub staff only).
- Icons in the Primer Roadmap inbox will be triaged by a maintainer from the Octicons team. Maintainers should reply with a comment on the issue and then move the issue to Primer Teams Backlog.
### 2. Working on icons
- If an icon recommendation can be made async, we will discuss it in #primer-octicons or directly in the issue.
- Icon review requests require a working session, we will send an invitation.
- Once an icon has been assigned, it's up to assigned designer to be responsible for communicating the icon's status and drive the work forward.
### 3. Icon design, review, and communication
- Once design has been started on an icon, the request issue will be moved to the **Design in Progress** column of the Primer Teams Backlog.
- Designers should design the icon in Figma and when ready for review, use the [Octicons Push plugin](https://www.figma.com/community/plugin/825432045044458754/Octicons-Push) to create a PR
- After a PR is created link to the PR in the icon request issue. PRs need approval from the icon requestor (stakeholder) and at least one designer on the octicons maintainer team.
### 4. Icon request completed
- When an icon request PR has been approved, communicate that in the issue.
- After the Octicons release, the new icons that were added will have their request issues moved to the **Done** column
## Adding or updating an icon
Follow these steps to add or update an icon.
### Manually with SVG files
#### 1. Clone the repository
```shell
# Clone the repository
git clone https://github.com/primer/octicons
# Navigate to the newly cloned directory
cd octicons
```
If you don't have [`write`](https://help.github.com/en/github/getting-started-with-github/access-permissions-on-github) access to the [primer/octicons](https://github.com/primer/octicons) repository, instead of cloning the repository directly, you'll need to [fork](http://help.github.com/fork-a-repo/) the project, clone your fork, and configure the remotes:
```shell
# Clone your fork of the repository
git clone https://github.com/<your-username>/octicons
# Navigate to the newly cloned directory
cd octicons
# Assign the original repo to a remote called "upstream"
git remote add upstream https://github.com/primer/octicons
```
#### 2. Create a new feature branch
```shell
git checkout -b <branch-name>
```
#### 3. Add or update SVG files in the `/icons` directory
#### 4. Add or update keywords in `keywords.json`
```diff
{
"mark-github": ["octocat", "brand", "github", "logo"],
+ "your-icon": ["foo", "bar"]
}
```
#### 5. Commit and push changes
```shell
git add .
git commit -m <message>
git push
```
#### 6. Create a pull request
Use GitHub to [create a pull request](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) for your branch. In your pull request description, be sure to mention where the icon will be used and any relevant timeline information.
If everything looks good, a maintainer will approve and merge the pull request when appropriate. After the pull request is merged, your icon will be available in the next Octicons release.
### Using the Octicons Push Figma plugin
If you work at GitHub, you can use the [Octicons Push](https://www.figma.com/community/plugin/825432045044458754/Octicons-Push) Figma plugin to start an Octicons pull request from Figma.
Here's how it works:
1. Select the icon frames you want to commit. Make sure the frames are either 16x16 or 24x24 and that you've outlined all strokes.
2. Open the Octicons Push plugin.
3. Select the branch you want to commit to. You can choose an existing branch or create a new branch.
4. Press "Commit." The plugin will then export, commit, and push the selected icons to the branch you chose. If you chose to create a new branch, the plugin will give you a link to where you can start a new pull request with your branch.
After you create a pull request, a member of the Design Infrastructure team will triage and review your contribution.

## How changes are reviewed
Here are a few questions we'll ask when reviewing new octicons. Keep these in mind as you're designing:
- Where will this icon be used in the context of GitHub UI?
- Is an icon necessary in that context?
- Could we use an existing icon?
- Is the icon trying to represent too many ideas?
- Does it follow the design guidelines?
## Releasing changes
Once submitted changes have been agreed upon, these instructions will guide maintainers through releasing changes.
Releases are managed by 🦋 [Changesets](https://github.com/atlassian/changesets#documentation) which is a great tool for managing major/minor/patch bumps and changelogs. More info can be found in our [how we work docs](https://github.com/github/design-infrastructure/blob/main/how-we-work/engineering/changesets.md#using-changesets-to-prepare-and-publish-a-release).
We have the [changeset-bot comment on new pull requests](https://github.com/changesets/bot#readme) asking contributors or maintainers to add a changeset file, which will become the markdown supported changelog entry for the change.
When creating the changeset always commit into the working branch (pull request branch), not `main`.
When a pull request is approved merge it into the `main` branch. The changeset action will then create a Release pull request that includes this new pull request.
Once maintainers have agreed and are satisfied with the release. Merge the Release pull request. Changesets will then publish a new GitHub release to the repository with the changelog and new version number. A second action will be triggered by this release and publish the new versions to npm and rubygems.
🎉 Congratulations! The new release has been published.
## Other contributions
When contributing to Octicons outside of adding a new icon or release-dependent contribution, be sure to add the `skip-changeset` label to the pull request. This will allow for the pull request to skip the changeset check and have the ability to be merged into the main branch.
Examples of other contributions include adding documentation or improving a GitHub Actions workflows.
================================================
FILE: Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
group :development, :test do
gem "minitest"
gem "rake"
gem "rubocop-github", "0.20.0"
end
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================


<br>
<br>
<h1 align="center">Primer Octicons</h1>
<p align="center">Octicons are a set of SVG icons built by GitHub for GitHub.</p>
<p align="center">
<a aria-label="build status" href="https://github.com/primer/octicons/actions/workflows/ci.yml">
<img alt="" src="https://github.com/primer/octicons/actions/workflows/ci.yml/badge.svg?branch=main&event=push">
</a>
<a aria-label="publish status" href="https://github.com/primer/octicons/actions/workflows/publish.yml">
<img alt="" src="https://github.com/primer/octicons/actions/workflows/publish.yml/badge.svg">
</a>
</p>
## Libraries
This repository contains several libraries. Each of them is in the `lib/` folder and gives access to Octicons on a different platform/language.
### JavaScript
The octicons node.js library is the main JavaScript library. With [a JavaScript API](/lib/octicons_node/README.md) that can be used in a variety of applications.
| Package | Version |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| **[@primer/octicons](/lib/octicons_node)** <br />Node.js package with JavaScript API | [](https://www.npmjs.org/package/@primer/octicons) |
| **[@primer/octicons-react](/lib/octicons_react)** <br />React Octicons components | [](https://www.npmjs.org/package/@primer/octicons-react) |
| **[@primer/styled-octicons](/lib/octicons_styled)** <br />React Octicons components with Styled System props | [](https://www.npmjs.org/package/@primer/styled-octicons) |
### Ruby
| Package | Version |
| ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| **[octicons](/lib/octicons_gem)** <br />Ruby gem with Ruby API | [](https://rubygems.org/gems/octicons) |
| [octicons_helper](/lib/octicons_helper)<br />Rails helper for using octicons | [](https://rubygems.org/gems/octicons_helper) |
| [jekyll-octicons](/lib/octicons_jekyll)<br />Jekyll plugin for using octicons | [](https://rubygems.org/gems/jekyll-octicons) |
## Contributing
### Feedback, ideas, and bug reports
If you found a bug, have feedback about our Octicon Library, or an idea on how to improve it, please open a new issue in this repo using the appropriate [issue template](https://github.com/primer/octicons/issues/new/choose).
### Request an Icon Review (GitHub staff only)
To request an icon review for inclusion in the Octicons Library, open an issue using the [icon review request](https://github.com/github/primer/issues/new?assignees=&labels=octicon%2C+request%2C+needs+triage&template=03-icon-request.md&title=%5BIcon+request%5D+) template in github/primer.
### Adding or updating an icon
Read through our [contributing guide](./CONTRIBUTING.md#adding-or-updating-icons) if you want to add or update icons.
## License
(c) GitHub, Inc.
When using the GitHub logos, be sure to follow the [GitHub logo guidelines](https://github.com/logos).
_Code License:_ [MIT](./LICENSE)
Applies to all other files
================================================
FILE: add-octicon-checklist.md
================================================
# Add an octicon
Use this checklist to add a new/updated octicon to the Figma library and the Octicons package. Read the [contributing guidelines](/CONTRIBUTING.md) for more information on the entire contribution process.
## Figma
- [ ] Remove white background from icon frame
- [ ] Outline all strokes of vector shape
- [ ] Union shapes
- [ ] Merge/flatten vector (cmd+e)
- [ ] Remove any unused points
- [ ] Rename vector layer "Icon"
- [ ] Vector layer color set to `text/primary`
- [ ] Name the icon frame to the correct icon name
- Note: Octicon names should be written lower case and use `-` to separate descriptors
- Note: If the icon is related to another icon or is part of a set, check the naming convention of the other icons to be consistent. (e.g. the issue icons are all prefixed as `issue-(something)`, `issue-opened`/`issue-closed`)
- Note: 24px icons will end with `-24` (e.g. `issue-opened-24`)
- [ ] Copy/paste into [Octicons library file](https://www.figma.com/file/1ljgTFkT5NKNRfq5hw07JQ/Octicons?node-id=0%3A1)
- [ ] Convert the icons into components
- [ ] Set constraints of vectors to Scale/Scale
- Note: If adding multiple icons, use the ["All Constraints" plugin](https://www.figma.com/community/plugin/847224511609531534/All-Constraints) for bulk editing
- [ ] Add keywords to icon component
- Note: All keywords begin with the search flag `icon: `
- Note: Keywords should describe other metaphors that the icon can represent when searching
- Example: The `bookmark` icon's keywords are "icon: favorite, save, bookmark"
## Octicons package
- [ ] Use the [Octicons Push plugin](https://www.figma.com/community/plugin/825432045044458754/Octicons-Push) to create a pull request from Figma
- [ ] Open created pull request in the browser and add details
- Pull request should include
- [ ] Small description with the names of the new icons
- [ ] Screenshot
- [ ] Link to icon request issue for tracking
- [ ] Request reviewers
- [ ] Original requestor (from issue)
- [ ] Member of octicons team (@ashygee, @colebemis, @edokoa, @juliusschaeper)
- [ ] Submit pull request
================================================
FILE: keywords.json
================================================
{
"agent": ["agents", "ai", "cloud", "cloudecode", "code"],
"ai-model": ["ai", "model", "llm", "models", "copilot"],
"alert": ["warning", "triangle", "exclamation", "point"],
"archive": ["box", "catalog"],
"arrow-both": ["point", "direction", "left", "right"],
"arrow-down": ["point", "direction"],
"arrow-left": ["point", "direction"],
"arrow-right": ["point", "direction"],
"arrow-small-down": ["point", "direction", "little", "tiny"],
"arrow-small-left": ["point", "direction", "little", "tiny"],
"arrow-small-right": ["point", "direction", "little", "tiny"],
"arrow-small-up": ["point", "direction", "little", "tiny"],
"arrow-up": ["point", "direction"],
"beaker": [
"experiment",
"labs",
"experimental",
"feature",
"test",
"science",
"education",
"study",
"development",
"testing"
],
"bell": ["notification"],
"bold": ["markdown", "bold", "text"],
"book": ["book", "journal", "wiki", "readme"],
"book-locked": ["book", "journal", "wiki", "readme", "lock"],
"bookmark": ["tab", "star"],
"boolean-off": ["bool", "off", "false", "no", "0"],
"boolean-on": ["bool", "on", "true", "yes", "1"],
"briefcase": ["suitcase", "business"],
"broadcast": ["rss", "radio", "signal"],
"browser": ["window", "web"],
"bug": ["insect", "issue"],
"calendar": ["time", "day", "month", "year", "date", "appointment"],
"check": ["mark", "yes", "confirm", "accept", "ok", "success"],
"checkbox": ["box", "checkbox", "check"],
"checkbox-fill": ["box", "checkbox", "check"],
"checklist": ["todo", "tasks"],
"chevron-down": ["triangle", "arrow"],
"chevron-left": ["triangle", "arrow"],
"chevron-right": ["triangle", "arrow"],
"chevron-up": ["triangle", "arrow"],
"circle-slash": ["no", "deny", "fail", "failure", "error", "bad"],
"circuit-board": ["developer", "hardware", "electricity"],
"clippy": ["copy", "paste", "save", "capture", "clipboard"],
"clock": ["time", "hour", "minute", "second", "watch"],
"cloud-download": ["save", "install", "get"],
"cloud-upload": ["put", "export"],
"code": ["brackets"],
"comment": ["speak", "bubble", "chat"],
"comment-ai": ["ai", "speak", "bubble", "chat"],
"comment-discussion": ["converse", "talk", "chat"],
"comment-locked": ["comment", "discussion", "conversation", "bubbles", "lock"],
"compose": ["write", "new", "create", "pencil", "post"],
"credit-card": ["money", "billing", "payments", "transactions"],
"crosshairs": ["target", "focus", "center", "trigger", "aim"],
"dash": ["hyphen", "range"],
"dashboard": ["speed", "dial"],
"database": ["disks", "data"],
"dependent": ["dependency", "dependent", "file"],
"desktop-download": ["clone", "download"],
"device-camera": ["photo", "picture", "image", "snapshot"],
"device-camera-video": ["watch", "view", "media", "stream"],
"device-desktop": ["computer", "monitor"],
"device-mobile": ["phone", "iphone", "cellphone"],
"dice": ["lucky", "chance", "random"],
"diff": ["difference", "changes", "compare"],
"diff-added": ["new", "addition", "plus"],
"diff-ignored": ["slash"],
"diff-modified": ["dot", "changed", "updated"],
"diff-removed": ["deleted", "subtracted", "dash"],
"diff-renamed": ["moved", "arrow"],
"ellipsis": ["dot", "read", "more", "hidden", "expand"],
"exclamation": ["warning", "alert", "emphasis"],
"eye": ["look", "watch", "see"],
"eye-closed": ["hidden", "invisible", "concealed", ""],
"file": ["file", "text", "words"],
"file-binary": ["image", "video", "word", "powerpoint", "excel"],
"file-check": ["file", "done", "complete", "check", "checked", "selected"],
"file-code": ["text", "javascript", "html", "css", "php", "ruby", "coffeescript", "sass", "scss"],
"file-directory": ["folder"],
"file-media": ["image", "video", "audio"],
"file-pdf": ["adobe"],
"file-submodule": ["folder"],
"file-symlink-directory": ["folder", "subfolder", "link", "alias"],
"file-symlink-file": ["link", "alias"],
"file-zip": ["compress", "archive"],
"filter-remove": ["funnel", "filter", "remove", "delete"],
"fiscal-host": ["safe", "money"],
"flame": ["fire", "hot", "burn", "trending"],
"flowchart": ["diagram", "chart", "process", "workflow", "loop", "nodes", "flow"],
"focus-center": ["target", "focus", "center"],
"fold": ["unfold", "hide", "collapse"],
"fold-down": ["unfold", "hide", "collapse", "down"],
"fold-up": ["unfold", "hide", "collapse", "up"],
"gear": ["settings"],
"gift": ["package", "present", "skill", "craft", "freebie"],
"gist": ["gist", "github"],
"gist-secret": ["gist", "secret", "private"],
"git-branch": ["fork", "branch", "git", "duplicate"],
"git-branch-check": ["git", "branch", "check", "checked", "selected"],
"git-commit": ["save"],
"git-compare": ["difference", "changes"],
"git-merge": ["join"],
"git-pull-request": ["review"],
"git-pull-request-locked": ["pr", "pull", "git", "lock"],
"github-action": ["board", "workflow", "action", "automation"],
"globe": ["world", "earth", "planet", "enterprise"],
"grabber": ["mover", "drag", "drop", "sort"],
"graph": ["chart", "trend", "stats", "statistics"],
"graph-bar-horizontal": ["chart", "barchart", "horizontal", "axis", "x-axis", "stats", "statistics"],
"graph-bar-vertical": ["chart", "barchart", "vertical", "axis", "y-axis", "stats", "statistics"],
"heart": ["love", "beat"],
"heart-outline": ["love", "beat"],
"history": ["time", "past", "revert", "back"],
"home": ["welcome", "index", "house", "building"],
"horizontal-rule": ["hr"],
"hubot": ["robot", "bot"],
"inbox": ["mail", "todo", "new", "messages"],
"inbox-fill": ["mail", "todo", "new", "messages"],
"infinity": ["unlimited", "infinite"],
"info": ["help"],
"internal-repo": ["internal, repo, repository"],
"issue-closed": ["done", "complete"],
"issue-locked": ["issue", "open", "new", "lock"],
"issue-opened": ["new"],
"issue-reopened": ["regression"],
"italic": ["font", "italic", "style"],
"jersey": ["team", "game", "basketball"],
"kebab-horizontal": ["kebab", "dot", "menu", "more"],
"kebab-vertical": ["kebab", "dot", "menu", "more"],
"key": ["key", "lock", "secure", "safe"],
"keyboard": ["type", "keys", "write", "shortcuts"],
"law": ["legal", "bill"],
"light-bulb": ["idea"],
"line-arrow-down": ["arrow", "point", "direction", "down"],
"line-arrow-left": ["arrow", "point", "direction", "left"],
"line-arrow-right": ["arrow", "point", "direction", "right"],
"line-arrow-up": ["arrow", "point", "direction", "up"],
"link": ["connect", "hyperlink"],
"link-external": ["out", "see", "more", "go", "to"],
"list-ordered": ["numbers", "tasks", "todo", "items"],
"list-unordered": ["bullet", "point", "tasks", "todo", "items"],
"location": ["here", "marker"],
"lock": ["secure", "safe", "protected"],
"lockup-github": ["brand", "github", "logo"],
"logo-gist": ["brand", "github", "logo"],
"logo-github": ["brand", "github", "logo"],
"loop": ["loops", "automation", "repeat", "node", "actions", "copilot"],
"mail": ["email", "unread"],
"mail-read": ["email", "open"],
"mark-github": ["octocat", "brand", "github", "logo"],
"markdown": ["markup", "style"],
"maximize": ["expand", "enlarge", "arrow"],
"mcp": ["model", "context", "protocol"],
"megaphone": ["bullhorn", "loud", "shout", "broadcast"],
"mention": ["at", "ping"],
"milestone": ["marker"],
"minimize": ["smaller", "shrink", "arrow"],
"mirror": ["reflect"],
"mortar-board": ["education", "learn", "teach"],
"move-to-bottom": ["terminal", "end", "down", "end"],
"move-to-end": ["terminal", "right", "finish"],
"move-to-start": ["terminal", "left", "beginning"],
"move-to-top": ["terminal", "up", "start", "beginning"],
"mute": ["quiet", "sound", "audio", "turn", "off"],
"no-newline": ["return"],
"north-star": ["star", "snowflake", "asterisk"],
"node": ["circle", "dot", "point", "loop", "loops"],
"note": ["card", "paper", "ticket"],
"octoface": ["octocat", "brand"],
"organization": ["people", "group", "team"],
"package": ["box", "ship"],
"paintcan": ["style", "theme", "art", "color"],
"pause": ["stop", "interupt", "block", "pause"],
"pencil": ["edit", "change", "update", "write"],
"pencil-ai": ["ai", "copilot", "edit", "change", "update", "write"],
"person": ["people", "man", "woman", "human"],
"pin": ["save", "star", "bookmark"],
"pin-slash": ["unpin", "unsave", "unstar", "unbookmark"],
"pivot-column": ["pivot", "column", "table", "project", "filter"],
"play": ["play", "start", "begin", "action"],
"plug": ["hook", "webhook"],
"plus": ["add", "new", "more"],
"plus-small": ["add", "new", "more", "small"],
"primitive-dot": ["circle"],
"primitive-dot-stroke": ["circle", "dot", "unread"],
"primitive-square": ["box"],
"project": ["board", "kanban", "columns", "scrum"],
"pulse": ["graph", "trend", "line", "activity"],
"question": ["help", "explain"],
"quote": ["quotation"],
"radio-tower": ["broadcast"],
"reply": ["reply all", "back"],
"repo": ["book", "journal", "repository"],
"repo-clone": ["book", "journal", "repository"],
"repo-force-push": ["book", "journal", "put"],
"repo-forked": ["book", "journal", "copy"],
"repo-pull": ["book", "journal", "get"],
"repo-push": ["book", "journal", "repository", "put"],
"repo-template": ["book", "new", "add", "template"],
"repo-template-private": ["book", "new", "template"],
"report": ["report", "abuse", "flag"],
"request-changes": ["diff", "changes", "request"],
"rocket": ["staff", "stafftools", "blast", "off", "space", "launch", "ship"],
"rss": ["broadcast", "feed", "atom"],
"ruby": ["code", "language"],
"saved": ["saved", "bookmark"],
"screen-full": ["fullscreen", "expand"],
"screen-normal": ["fullscreen", "expand", "exit"],
"search": ["magnifying", "glass"],
"server": ["computers", "racks", "ops"],
"settings": ["sliders", "filters", "controls", "levels"],
"shield": ["security", "shield", "protection"],
"shield-check": ["security", "shield", "protection", "check", "success"],
"shield-lock": ["protect", "shield", "lock"],
"shield-slash": ["shield", "slash", "protect", "unsafe", "unprotected", "security"],
"shield-x": ["security", "shield", "protection", "fail"],
"sign-in": ["door", "arrow", "direction", "enter", "log in"],
"sign-out": ["door", "arrow", "direction", "leave", "log out"],
"skip": ["skip", "slash"],
"smiley": ["emoji", "smile", "mood", "emotion", "feedback", "happy", "4"],
"smiley-frown": ["emoji", "frown", "sad", "negative", "unhappy", "mood", "emotion", "feedback", "2"],
"smiley-frustrated": ["emoji", "frustrated", "negative", "angry", "mad", "pain", "mood", "emotion", "feedback", "1"],
"smiley-grin": ["emoji", "grin", "mood", "ecstatic", "elated", "thrilled", "happy", "emotion", "feedback", "5"],
"smiley-neutral": ["emoji", "neutral", "meh", "expressionless", "mood", "emotion", "feedback", "3"],
"space": ["spaces", "context", "copilot", "attachment", "folder", "ai"],
"spacing-small": ["spacing", "density", "padding", "small"],
"spacing-medium": ["spacing", "density", "padding", "medium"],
"spacing-large": ["spacing", "density", "padding", "large"],
"sparkle": ["spark", "ai", "generate", "shine"],
"split-view": ["columns", "split", "view", "panes", "sidebar"],
"square-circle": ["stop", "interupt", "block", "pause"],
"squirrel": ["ship", "shipit", "launch"],
"star": ["save", "remember", "like"],
"stop": ["block", "spam", "report"],
"sync": ["cycle", "refresh", "loop"],
"tag": ["release"],
"tasklist": ["todo"],
"telescope": ["science", "space", "look", "view", "explore"],
"terminal": ["code", "ops", "shell"],
"text-size": ["font", "size", "text"],
"three-bars": ["hamburger", "menu", "dropdown"],
"thumbsdown": ["thumb", "thumbsdown", "rejected", "dislike"],
"thumbsup": ["thumb", "thumbsup", "prop", "ship", "like"],
"tools": ["screwdriver", "wrench", "settings"],
"trashcan": ["garbage", "rubbish", "recycle", "delete"],
"triangle-down": ["arrow", "point", "direction"],
"triangle-left": ["arrow", "point", "direction"],
"triangle-right": ["arrow", "point", "direction"],
"triangle-up": ["arrow", "point", "direction"],
"unfold": ["expand", "open", "reveal"],
"unmute": ["loud", "volume", "audio", "sound", "play"],
"unsaved": ["unsaved", "bookmark"],
"unverified": ["insecure", "untrusted", "signed"],
"unwrap": ["lines", "text", "paragraph", "wordwrap", "wrap", "flow"],
"verified": ["trusted", "secure", "trustworthy", "signed"],
"versions": ["history", "commits"],
"watch": ["wait", "hourglass", "time", "date"],
"workflow": ["workflow", "actions"],
"workflow-all": ["workflow", "actions"],
"wrap": ["lines", "text", "paragraph", "wordwrap", "wrap", "flow"],
"x": ["remove", "close", "delete"],
"zap": ["electricity", "lightning", "props", "like", "star", "save"],
"zoom-in": ["zoom", "in", "plus", "bigger"],
"zoom-out": ["zoom", "out", "minus", "smaller"]
}
================================================
FILE: lib/octicons_gem/.npmignore
================================================
*
================================================
FILE: lib/octicons_gem/Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
gemspec
group :development, :test do
gem "minitest"
gem "rake"
gem "rubocop", "~> 1.0"
gem "rubocop-github", "0.20.0"
end
================================================
FILE: lib/octicons_gem/LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: lib/octicons_gem/README.md
================================================
# octicons
[](https://rubygems.org/gems/octicons)
## Install
Add this to your `Gemfile`
```rb
gem 'octicons'
```
Then `bundle install`.
If using a framework like Rails, please follow the [installation instructions](https://primer.style/view-components/#installation) in the [Primer ViewComponents](https://primer.style/view-components) documentation.
## Usage
```rb
require 'octicons'
icon = Octicons::Octicon.new("x")
icon.to_svg
# <svg class="octicon octicon-x" viewBox="0 0 16 16" width="16" height="16" version="1.1" "aria-hidden"="true"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
```
## Documentation
The `Octicon` class takes two arguments. The first is the symbol of the icon, and the second is a hash of arguments representing html attributes
### `symbol` _(required)_
This is the name of the octicon you want to use. For example `alert`. [Full list of icons](/)
### Options
* `:height` - When setting the height to a number, the icon will scale to that size. For example, passing `32`, will calculate the width based on the icon's natural size.
* `:width` - When setting the width to a number, the icon will scale to that size. For example, passing `32`, will calculate the width based on the icon's natural size.
If both `:width, :height` are passed into the options hash, then the icon will be sized exactly at those dimensions.
### Attributes
Once initialized, you can read a few properties from the icon.
#### `symbol`
Returns the string of the symbol name
```rb
icon = Octicons::Octicon.new("x")
icon.symbol
# "x"
```
#### `path`
Path returns the string representation of the path of the icon.
```rb
icon = Octicons::Octicon.new("x")
icon.path
# <path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path>
```
#### `options`
This is a hash of all the `options` that will be added to the output tag.
```rb
icon = Octicons::Octicon.new("x")
icon.options
# {:class=>"octicon octicon-x", :viewBox=>"0 0 12 16", :version=>"1.1", :width=>12, :height=>16, :"aria-hidden"=>"true"}
```
#### `width`
Width is the icon's true width. Based on the svg view box width. _Note, this doesn't change if you scale it up with size options, it only is the natural width of the icon_
#### `height`
Height is the icon's true height. Based on the svg view box height. _Note, this doesn't change if you scale it up with size options, it only is the natural height of the icon_
#### `keywords`
Returns an array of keywords for the icon. The data comes from the [data file in lib](../data.json). Consider contributing more aliases for the icons.
```rb
icon = Octicons::Octicon.new("x")
icon.keywords
# ["remove", "close", "delete"]
```
### Methods
#### `to_svg`
Returns a string of the svg tag
```rb
icon = Octicons::Octicon.new("x")
icon.to_svg
# <svg class="octicon octicon-x" viewBox="0 0 16 16" width="16" height="16" version="1.1" "aria-hidden"="true"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path></svg>
```
================================================
FILE: lib/octicons_gem/Rakefile
================================================
# frozen_string_literal: true
require "rake/testtask"
require "rubocop/rake_task"
require "bundler/gem_tasks"
RuboCop::RakeTask.new(:lint) do |t|
t.options = ["--display-cop-names"]
end
Rake::TestTask.new do |t|
t.libs = ["lib", "test"]
t.test_files = FileList["test/*_test.rb"]
end
task :version, [:v] do |t, args|
out = "# frozen_string_literal: true\n\nmodule Octicons\n"\
" VERSION = \"#{args[:v]}\".freeze\n"\
"end"
File.open(File.expand_path("../lib/octicons/version.rb", __FILE__), "w") { |file| file.puts out }
end
desc "Run tests"
task default: :test
================================================
FILE: lib/octicons_gem/lib/octicons/octicon.rb
================================================
# frozen_string_literal: true
module Octicons
class Octicon
DEFAULT_HEIGHT = 16
attr_reader :path, :options, :width, :height, :symbol, :keywords
def initialize(symbol, options = {})
@symbol = symbol.to_s
if octicon = get_octicon(@symbol, options)
@path = octicon["path"]
@width = octicon["width"]
@height = octicon["height"]
@keywords = octicon["keywords"]
@options = options.dup
@options.merge!({
class: classes,
viewBox: viewbox,
version: "1.1"
})
@options.merge!(size)
@options.merge!(a11y)
else
raise "Couldn't find octicon symbol for #{@symbol.inspect}"
end
end
# Returns an string representing a <svg> tag
def to_svg
"<svg #{html_attributes}>#{@path}</svg>"
end
private
def html_attributes
attrs = ""
@options.each { |attr, value| attrs += "#{attr}=\"#{value}\" " }
attrs.strip
end
# add some accessibility features to svg
def a11y
accessible = {}
if @options[:"aria-label"].nil? && @options["aria-label"].nil?
accessible[:"aria-hidden"] = "true"
else
accessible[:role] = "img"
end
accessible
end
# prepare the octicon class
def classes
"octicon octicon-#{@symbol} #{@options[:class]} ".strip
end
def viewbox
"0 0 #{@width} #{@height}"
end
# determine the height and width of the octicon based on :size option
def size
size = {
width: @width,
height: @height
}
# Specific size
unless @options[:width].nil? && @options[:height].nil?
size[:width] = @options[:width].nil? ? calculate_width(@options[:height]) : @options[:width]
size[:height] = @options[:height].nil? ? calculate_height(@options[:width]) : @options[:height]
end
size
end
def calculate_width(height)
(height.to_i * @width) / @height
end
def calculate_height(width)
(width.to_i * @height) / @width
end
def get_octicon(symbol, options = {})
if octicon = Octicons::OCTICON_SYMBOLS[symbol]
# We're using width as an approximation for height if the height option is not passed in
height = options[:height] || options[:width] || DEFAULT_HEIGHT
natural_height = closest_natural_height(octicon["heights"].keys, height)
return {
"name" => octicon["name"],
"keywords" => octicon["keywords"],
"width" => octicon["heights"][natural_height.to_s]["width"].to_i,
"height" => natural_height,
"path" => octicon["heights"][natural_height.to_s]["path"]
}
end
end
def closest_natural_height(natural_heights, height)
return natural_heights.reduce(natural_heights[0].to_i) do |acc, natural_height|
natural_height.to_i <= height.to_i ? natural_height.to_i : acc
end
end
end
end
================================================
FILE: lib/octicons_gem/lib/octicons/version.rb
================================================
# frozen_string_literal: true
module Octicons
VERSION = "19.9.0".freeze
end
================================================
FILE: lib/octicons_gem/lib/octicons.rb
================================================
# frozen_string_literal: true
require "octicons/version"
require "octicons/octicon"
require "json"
module Octicons
file_data = File.read(File.join(File.dirname(__FILE__), "./build/data.json"))
OCTICON_SYMBOLS = JSON.parse(file_data).freeze
end
================================================
FILE: lib/octicons_gem/octicons.gemspec
================================================
# frozen_string_literal: true
require File.expand_path("../lib/octicons/version", __FILE__)
Gem::Specification.new do |s|
s.name = "octicons"
s.version = Octicons::VERSION
s.summary = "GitHub's octicons gem"
s.platform = Gem::Platform::RUBY
s.description = "A package that distributes Octicons in a gem"
s.authors = ["GitHub Inc."]
s.email = ["support@github.com"]
s.files = Dir["{lib}/**/*"] + ["LICENSE", "README.md"]
s.homepage = "https://github.com/primer/octicons"
s.license = "MIT"
end
================================================
FILE: lib/octicons_gem/test/helper.rb
================================================
# frozen_string_literal: true
require "minitest/autorun"
require "octicons"
def octicon(symbol, options = {})
Octicons::Octicon.new(symbol, options)
end
================================================
FILE: lib/octicons_gem/test/octicon_test.rb
================================================
# frozen_string_literal: true
require_relative "helper"
describe Octicons::Octicon do
it "fails when the octicon doesn't exist" do
assert_raises(RuntimeError) do
octicon("octicon")
end
end
it "initialize accepts a string for an icon" do
icon = octicon("x")
assert icon
end
it "initialize accepts a symbol for an icon" do
icon = octicon(:x)
assert icon
end
it "gets keywords for the icon" do
icon = octicon("mark-github")
assert_equal ["octocat", "brand", "github", "logo"], icon.keywords
end
it "the attributes are readable" do
icon = octicon("x")
assert icon.path
assert icon.options
assert_equal "x", icon.symbol
assert_equal 16, icon.width
assert_equal 16, icon.height
end
describe "viewBox" do
it "always has a viewBox" do
icon = octicon("x")
assert_includes icon.to_svg, "viewBox=\"0 0 16 16\""
end
end
describe "html_attributes" do
it "includes other html attributes" do
icon = octicon("x", foo: "bar", disabled: "true")
assert_includes icon.to_svg, "disabled=\"true\""
assert_includes icon.to_svg, "foo=\"bar\""
end
end
describe "classes" do
it "includes classes passed in" do
icon = octicon("x", class: "text-closed")
assert_includes icon.to_svg, "class=\"octicon octicon-x text-closed\""
end
end
describe "size" do
it "always has width and height" do
icon = octicon("x")
assert_includes icon.to_svg, "height=\"16\""
assert_includes icon.to_svg, "width=\"16\""
end
it "converts number string height to integer" do
icon = octicon("x", height: "60")
assert_includes icon.to_svg, "height=\"60\""
assert_includes icon.to_svg, "width=\"60\""
end
it "converts number height to integer" do
icon = octicon("x", height: 60)
assert_includes icon.to_svg, "height=\"60\""
assert_includes icon.to_svg, "width=\"60\""
end
it "converts number string width to integer" do
icon = octicon("x", width: "45")
assert_includes icon.to_svg, "height=\"45\""
assert_includes icon.to_svg, "width=\"45\""
end
it "converts number width to integer" do
icon = octicon("x", width: 45)
assert_includes icon.to_svg, "height=\"45\""
assert_includes icon.to_svg, "width=\"45\""
end
it "with height and width passed in" do
icon = octicon("x", width: 60, height: 60)
assert_includes icon.to_svg, "width=\"60\""
assert_includes icon.to_svg, "height=\"60\""
end
it "chooses the correct svg given a height" do
icon = octicon("x", height: 32)
assert_includes icon.to_svg, "width=\"32\""
assert_includes icon.to_svg, "height=\"32\""
assert_includes icon.to_svg, "viewBox=\"0 0 24 24\""
end
it "chooses the correct svg given a width" do
icon = octicon("x", width: 24)
assert_includes icon.to_svg, "width=\"24\""
assert_includes icon.to_svg, "height=\"24\""
assert_includes icon.to_svg, "viewBox=\"0 0 24 24\""
end
it "chooses the correct svg given a height and width" do
icon = octicon("x", height: 24, width: 16)
assert_includes icon.to_svg, "width=\"16\""
assert_includes icon.to_svg, "height=\"24\""
assert_includes icon.to_svg, "viewBox=\"0 0 24 24\""
end
end
describe "a11y" do
it "includes attributes for symbol keys" do
icon = octicon("x", "aria-label": "Close")
assert_includes icon.to_svg, "role=\"img\""
assert_includes icon.to_svg, "aria-label=\"Close\""
refute_includes icon.to_svg, "aria-hidden"
end
it "includes attributes for string keys" do
icon = octicon("x", "aria-label" => "Close")
assert_includes icon.to_svg, "role=\"img\""
assert_includes icon.to_svg, "aria-label=\"Close\""
refute_includes icon.to_svg, "aria-hidden"
end
it "has aria-hidden when no label is passed in" do
icon = octicon("x")
assert_includes icon.to_svg, "aria-hidden=\"true\""
end
end
end
================================================
FILE: lib/octicons_gem/test/octicons_test.rb
================================================
# frozen_string_literal: true
require_relative "helper"
describe Octicons do
it "loads all icons on initialization" do
refute_equal 0, Octicons::OCTICON_SYMBOLS.length
x_icon = Octicons::OCTICON_SYMBOLS["x"]
assert x_icon["name"]
assert x_icon["keywords"]
assert x_icon["heights"]
assert x_icon["heights"]["16"]
assert x_icon["heights"]["16"]["width"]
assert x_icon["heights"]["16"]["path"]
end
end
================================================
FILE: lib/octicons_helper/.npmignore
================================================
*
================================================
FILE: lib/octicons_helper/Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
gemspec
gem "octicons", "19.9.0"
gem "rails"
group :development, :test do
gem "minitest", "~> 5.0"
gem "rake"
gem "rubocop", "~> 1.0"
gem "rubocop-github", "0.20.0"
end
================================================
FILE: lib/octicons_helper/LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: lib/octicons_helper/README.md
================================================
# octicons_helper
[](https://rubygems.org/gems/octicons_helper)
This rails helper lets you easily include svg octicons in your rails apps.
## Install
1. Add this to your `Gemfile`
```rb
gem 'octicons_helper'
```
3. Use this tag in your erbs
```rb
<%= octicon "alert", :height => 32, :class => "right left", :"aria-label" => "hi" %>
```
We recommend including the CSS in the [`@primer/octicons`](/packages/javascript) npm module. You can also npm install that package and include `build/build.css` in your styles.
================================================
FILE: lib/octicons_helper/Rakefile
================================================
# frozen_string_literal: true
require "rake/testtask"
require "rubocop/rake_task"
require "bundler/gem_tasks"
RuboCop::RakeTask.new(:lint) do |t|
t.options = ["--display-cop-names"]
end
task :version, [:v] do |t, args|
out = "# frozen_string_literal: true\n\nmodule OcticonsHelper\n"\
" VERSION = \"#{args[:v]}\".freeze\n"\
"end"
File.open(File.expand_path("../lib/octicons_helper/version.rb", __FILE__), "w") do |file|
file.puts out
end
["octicons_helper.gemspec", "Gemfile"].each do |filename|
gs = File.read(File.expand_path("../#{filename}", __FILE__))
File.open(File.expand_path("../#{filename}", __FILE__), "w") do |file|
file.puts gs.gsub(/"octicons", "[^"]+"/, "\"octicons\", \"#{args[:v]}\"")
end
end
end
Rake::TestTask.new do |t|
t.libs = ["lib", "test"]
t.test_files = FileList["test/*_test.rb"]
t.warning = false
end
desc "Run tests"
task default: :test
================================================
FILE: lib/octicons_helper/lib/octicons_helper/helper.rb
================================================
# frozen_string_literal: true
require "octicons"
require "action_view"
module OcticonsHelper
include ActionView::Helpers::TagHelper
mattr_accessor :octicons_helper_cache, default: {}
def octicon(symbol, options = {})
return "" if symbol.nil?
cache_key = [symbol, options]
if tag = octicons_helper_cache[cache_key]
tag
else
icon = Octicons::Octicon.new(symbol, options)
tag = content_tag(:svg, icon.path.html_safe, icon.options).freeze # rubocop:disable Rails/OutputSafety
octicons_helper_cache[cache_key] = tag
tag
end
end
end
================================================
FILE: lib/octicons_helper/lib/octicons_helper/railtie.rb
================================================
# frozen_string_literal: true
require "rails"
module OcticonsHelper
class Railtie < Rails::Railtie
initializer "octicons_helper.helper" do
ActionView::Base.send :include, OcticonsHelper
end
end
end
================================================
FILE: lib/octicons_helper/lib/octicons_helper/version.rb
================================================
# frozen_string_literal: true
module OcticonsHelper
VERSION = "19.9.0".freeze
end
================================================
FILE: lib/octicons_helper/lib/octicons_helper.rb
================================================
# frozen_string_literal: true
require "octicons_helper/version"
require "octicons_helper/helper"
require "octicons_helper/railtie" if defined?(Rails)
================================================
FILE: lib/octicons_helper/octicons_helper.gemspec
================================================
# frozen_string_literal: true
require File.expand_path("../lib/octicons_helper/version", __FILE__)
Gem::Specification.new do |s|
s.name = "octicons_helper"
s.version = OcticonsHelper::VERSION
s.summary = "Octicons rails helper"
s.description = "A rails helper that makes including svg Octicons simple."
s.authors = ["GitHub Inc."]
s.email = ["support@github.com"]
s.files = Dir["{lib}/**/*"] + ["LICENSE", "README.md"]
s.homepage = "https://github.com/primer/octicons"
s.license = "MIT"
s.require_paths = ["lib"]
s.add_dependency "octicons", "19.9.0"
s.add_dependency "railties"
s.add_dependency "actionview"
end
================================================
FILE: lib/octicons_helper/test/helper.rb
================================================
# frozen_string_literal: true
require "minitest/autorun"
require "minitest/mock"
require "octicons_helper"
include OcticonsHelper
================================================
FILE: lib/octicons_helper/test/octicons_helper_test.rb
================================================
# frozen_string_literal: true
require_relative "helper"
describe OcticonsHelper do
describe "rendering" do
it "renders nothing when no symbol is passed in" do
assert_equal "", octicon(nil)
end
it "renders the svg" do
assert_match /<svg.*octicon-x.*>.*<\/svg>/, octicon("x")
end
it "has a path" do
assert_match /<path/, octicon("alert")
end
it "adds html attributes to output" do
assert_match /foo="bar"/, octicon("alert", foo: "bar")
end
it "caches SVGs for two calls with the same arguments" do
OcticonsHelper.octicons_helper_cache = {}
mock = Minitest::Mock.new
def mock.path
@call_count ||= 0
@call_count += 1
raise "Octicon library called twice" if @call_count > 1
"foo"
end
def mock.options; end
Octicons::Octicon.stub :new, mock do
octicon("alert")
octicon("alert")
end
OcticonsHelper.octicons_helper_cache = {}
end
end
end
================================================
FILE: lib/octicons_jekyll/.npmignore
================================================
*
================================================
FILE: lib/octicons_jekyll/.rubocop.yml
================================================
inherit_gem:
rubocop-github:
- config/default.yml
Naming/FileName:
Enabled: false
Style/OneClassPerFile:
Exclude:
- "lib/jekyll-octicons/version.rb"
AllCops:
NewCops: enable
================================================
FILE: lib/octicons_jekyll/Gemfile
================================================
# frozen_string_literal: true
source "https://rubygems.org"
gemspec
gem "octicons", "19.8.0"
group :development, :test do
gem "minitest"
gem "rake"
gem "rubocop", "~> 1.0"
gem "rubocop-github", "0.20.0"
end
================================================
FILE: lib/octicons_jekyll/LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: lib/octicons_jekyll/README.md
================================================
# jekyll-octicons
[](https://rubygems.org/gems/jekyll-octicons)
The Jekyll liquid tag is a plugin that lets you include octicons in your Jekyll sites.
## Install
1. Add this to your `Gemfile`
```rb
gem 'jekyll-octicons'
```
2. Add this to your jekyll `_config.yml`
```yml
plugins:
- jekyll-octicons
```
3. Use this tag in your jekyll templates
```
{% octicon alert height:32 class:"right left" aria-label:hi %}
```
We recommend including the CSS in the [`@primer/octicons`](/packages/javascript) npm module. You can also npm install that package and include `build/build.css` in your styles.
================================================
FILE: lib/octicons_jekyll/Rakefile
================================================
# frozen_string_literal: true
require "rake/testtask"
require "rubocop/rake_task"
require "bundler/gem_tasks"
RuboCop::RakeTask.new(:lint) do |t|
t.options = ["--display-cop-names"]
end
task :version, [:v] => :environment do |t, args|
out = "# frozen_string_literal: true\n\n# Prevent bundler errors\n"\
"module Liquid; class Tag; end; end\n\n"\
"module Jekyll\n"\
" class Octicons < Liquid::Tag\n"\
" VERSION = \"#{args[:v]}\".freeze\n"\
" end\n"\
"end"
File.open(File.expand_path("../lib/jekyll-octicons/version.rb", __FILE__), "w") do |file|
file.puts out
end
["jekyll-octicons.gemspec", "Gemfile"].each do |filename|
gs = File.read(File.expand_path("../#{filename}", __FILE__))
File.open(File.expand_path("../#{filename}", __FILE__), "w") do |file|
file.puts gs.gsub(/"octicons", "[^"]+"/, "\"octicons\", \"#{args[:v]}\"")
end
end
end
Rake::TestTask.new do |t|
t.libs = ["lib", "test"]
t.test_files = FileList["test/*_test.rb"]
t.warning = false
end
desc "Run tests"
task default: :test
================================================
FILE: lib/octicons_jekyll/jekyll-octicons.gemspec
================================================
# frozen_string_literal: true
require File.expand_path("../lib/jekyll-octicons/version", __FILE__)
Gem::Specification.new do |s|
s.name = "jekyll-octicons"
s.version = Jekyll::Octicons::VERSION
s.summary = "Octicons jekyll liquid tag"
s.description = "A jekyll liquid plugin that makes including svg Octicons simple."
s.authors = ["GitHub Inc."]
s.email = ["support@github.com"]
s.files = Dir["{lib}/**/*"] + ["LICENSE", "README.md"]
s.homepage = "https://github.com/primer/octicons"
s.license = "MIT"
s.require_paths = ["lib"]
s.add_dependency "jekyll", ">= 3.6", "< 5.0"
s.add_dependency "octicons", "19.8.0"
end
================================================
FILE: lib/octicons_jekyll/lib/jekyll-octicons/version.rb
================================================
# frozen_string_literal: true
# Prevent bundler errors
module Liquid; class Tag; end; end
module Jekyll
class Octicons < Liquid::Tag
VERSION = "19.8.0".freeze
end
end
================================================
FILE: lib/octicons_jekyll/lib/jekyll-octicons.rb
================================================
# frozen_string_literal: true
require "octicons"
require "jekyll-octicons/version"
require "liquid"
require "jekyll/liquid_extensions"
module Jekyll
class Octicons < Liquid::Tag
include Jekyll::LiquidExtensions
# Syntax for the octicon symbol
Syntax = /\A(#{Liquid::VariableSignature}+)/
# For interpolation, look for liquid variables
Variable = /\{\{\s*([\w]+\.?[\w]*)\s*\}\}/i
# Copied from Liquid::TagAttributes to allow dashes in tag names:
#
# {% octicon alert area-label:"Hello World!" %}
#
TagAttributes = /([\w-]+)\s*\:\s*(#{Liquid::QuotedFragment})/o
def initialize(tag_name, markup, options)
super
@markup = markup
# If there's interpolation going on, we need to do this in render
prepare(markup) unless match = markup.match(Variable)
end
def render(context)
prepare(interpolate(@markup, context)) if match = @markup.match(Variable)
return nil if @symbol.nil?
::Octicons::Octicon.new(@symbol, @options).to_svg
end
private
def interpolate(markup, context)
markup.scan Variable do |variable|
markup = markup.gsub(Variable, lookup_variable(context, variable.first))
end
markup
end
def prepare(markup)
@symbol = symbol(markup)
@options = string_to_hash(markup)
end
def symbol(markup)
if match = markup.match(Syntax)
match[1]
end
end
# Create a ruby hash from a string passed by the jekyll tag
def string_to_hash(markup)
options = {}
if match = markup.match(Syntax)
markup.scan(TagAttributes) do |key, value|
options[key.to_sym] = value.gsub(/\A"|"\z/, "")
end
end
options
end
end
end
Liquid::Template.register_tag("octicon", Jekyll::Octicons)
================================================
FILE: lib/octicons_jekyll/test/helper.rb
================================================
# frozen_string_literal: true
require "minitest/autorun"
require "jekyll-octicons"
# Parse a string into a liquid template
# rubocop:disable Rails/Delegate
def parse(string)
Liquid::Template.parse(string)
end
# rubocop:enable Rails/Delegate
# Parse and render a string
def render(string, assigns = {})
parse(string).render!(assigns)
end
================================================
FILE: lib/octicons_jekyll/test/octicon_tag_test.rb
================================================
# frozen_string_literal: true
require_relative "helper"
describe Jekyll::Octicons do
describe "parsing" do
it "parses the tag options" do
output = render("{% octicon mark-github height:32 class:\"left right\" aria-label:hi %}")
assert_match /height="32"/, output
assert_match /class="[^"]+ left right/, output
assert_match /aria-label="hi"/, output
end
it "parses interpolation of variables" do
template = render("{% assign symbol = \"mark-github\" %}{% octicon {{ symbol }} %}")
assert_match /<svg.*octicon-mark-github.*/, template
end
end
describe "rendering" do
it "renders the svg" do
output = render("{% octicon mark-github height:32 %}")
assert_match /<svg.*octicon-mark-github.*/, output
assert_match /<svg.*width="32".*/, output
end
it "renders nothing without a symbol" do
assert_equal "", render("{% octicon %}")
end
end
end
================================================
FILE: lib/octicons_node/.npmignore
================================================
script
================================================
FILE: lib/octicons_node/LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: lib/octicons_node/README.md
================================================
# @primer/octicons
[](https://www.npmjs.org/package/@primer/octicons)
## Install
This package is distributed with [npm][npm]. After [installing npm][install-npm], you can install `@primer/octicons` with this command:
```shell
npm install @primer/octicons
```
## Usage
For all the usages, we recommend using the CSS located in [`build/build.css`](https://unpkg.com/@primer/octicons/build/build.css). This is some simple CSS to normalize the icons and inherit colors.
After installing `@primer/octicons` you can access the icons like this:
```js
var octicons = require("@primer/octicons")
octicons.alert
// {
// symbol: 'alert',
// keywords: ['warning', 'triangle', 'exclamation', 'point'],
// toSVG: [Function]
// heights: {
// 16: {
// width: 16,
// path: '<path d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/>',
// options: {
// version: '1.1',
// width: '16',
// height: '16',
// viewBox: '0 0 16 16',
// class: 'octicon octicon-alert',
// 'aria-hidden': 'true'
// },
// },
// 24: ...
// }
// }
```
There will be a key for every icon, with [`toSVG`](#octiconsnametosvg) and other properties.
_Note: `alert` in the above example can be replaced with any valid icon name. Icons with multi-word names (e.g. `arrow-right`) **cannot** be accessed using dot notation (e.g. `octicons.alert`). Instead, use bracket notation (e.g. `octicons['arrow-right']`)._
### `octicons[name].symbol`
Returns the string of the symbol name, same as the key for that icon.
```js
octicons.x.symbol
// "x"
```
### `octicons[name].keywords`
Returns an array of keywords for the icon. The data comes from [keywords.json](https://github.com/primer/octicons/blob/main/keywords.json). Consider contributing more aliases for the icons.
```js
octicons.x.keywords
// ["remove", "close", "delete"]
```
### `octicons[name].heights`
Each icon can have multiple SVGs that are designed for different sizes. The `heights` property allows you to access all the SVGs for an icon using the natural height of the SVG.
```js
octicons.x.heights
// {
// 16: {
// width: 16,
// path: '<path d="..."/>',
// options: {
// version: '1.1',
// width: '16',
// height: '16',
// viewBox: '0 0 16 16',
// class: 'octicon octicon-alert',
// 'aria-hidden': 'true'
// },
// },
// 24: {
// width: 24,
// path: '<path d="..."/>',
// options: {
// version: '1.1',
// width: '24',
// height: '24',
// viewBox: '0 0 24 24',
// class: 'octicon octicon-alert',
// 'aria-hidden': 'true'
// },
// },
// }
```
### `octicons[name].heights[height].width`
Returns the icon's true width, based on the SVG view box width. _Note, this doesn't change if you scale it up with size options, it only is the natural width of the icon._
### `octicons[name].heights[height].path`
Returns the string representation of the path of the icon.
```js
octicons.x.heights[16].path
// <path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"></path>
```
### `octicons[name].heights[height].options`
This is an object of all the attributes that will be added to the output tag.
```js
octicons.x.heights[16].options
// { version: '1.1', width: '12', height: '16', viewBox: '0 0 12 16', class: 'octicon octicon-x', 'aria-hidden': 'true' }
```
### `octicons[name].toSVG()`
Returns a string of the `<svg>` tag.
```js
octicons.x.toSVG()
// <svg version="1.1" width="12" height="16" viewBox="0 0 12 16" class="octicon octicon-x" aria-hidden="true"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
```
The `.toSVG()` method accepts an optional `options` object. This is used to add CSS class names, accessibility options, and sizes.
#### class
Add more CSS classes to the `<svg>` tag.
```js
octicons.x.toSVG({ "class": "close" })
// <svg version="1.1" width="12" height="16" viewBox="0 0 12 16" class="octicon octicon-x close" aria-hidden="true"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
```
#### aria-label
Add accessibility `aria-label` to the icon.
```js
octicons.x.toSVG({ "aria-label": "Close the window" })
// <svg version="1.1" width="12" height="16" viewBox="0 0 12 16" class="octicon octicon-x" aria-label="Close the window" role="img"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
```
#### width and height
Size the SVG icon larger using `width` and `height` independently or together. `.toSVG()` will automatically choose the best SVG to render based on the width or height passed in.
```js
octicons.x.toSVG({ "width": 45 })
// <svg version="1.1" width="45" height="45" viewBox="0 0 24 24" class="octicon octicon-x" aria-hidden="true"><path d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
```
[primer]: https://github.com/primer/primer
[docs]: http://primercss.io/
[npm]: https://www.npmjs.com/
[install-npm]: https://docs.npmjs.com/getting-started/installing-node
[sass]: http://sass-lang.com/
================================================
FILE: lib/octicons_node/index.js
================================================
const data = require('./build/data.json')
const objectAssign = require('object-assign')
const DEFAULT_HEIGHT = 16
for (const key of Object.keys(data)) {
// Returns a string representation of html attributes
const htmlAttributes = (icon, defaultOptions, options) => {
const attributes = []
const attrObj = objectAssign({}, defaultOptions, options)
// If the user passed in options
if (options) {
// If any of the width or height is passed in
if (options['width'] || options['height']) {
attrObj['width'] = options['width']
? options['width']
: (parseInt(options['height']) * defaultOptions['width']) / defaultOptions['height']
attrObj['height'] = options['height']
? options['height']
: (parseInt(options['width']) * defaultOptions['height']) / defaultOptions['width']
}
// If the user passed in class
if (options['class']) {
attrObj['class'] = `octicon octicon-${key} ${options['class']}`
attrObj['class'].trim()
}
// If the user passed in aria-label
if (options['aria-label']) {
attrObj['aria-label'] = options['aria-label']
attrObj['role'] = 'img'
// Un-hide the icon
delete attrObj['aria-hidden']
}
}
for (const option of Object.keys(attrObj)) {
attributes.push(`${option}="${attrObj[option]}"`)
}
return attributes.join(' ').trim()
}
// Set the symbol for easy access
data[key].symbol = key
// Set options for each icon height
for (const height of Object.keys(data[key].heights)) {
data[key].heights[height].options = {
version: '1.1',
width: data[key].heights[height].width,
height: parseInt(height),
viewBox: `0 0 ${data[key].heights[height].width} ${height}`,
class: `octicon octicon-${key}`,
'aria-hidden': 'true'
}
}
// Function to return an SVG object
data[key].toSVG = function (options = {}) {
const {height, width} = options
const naturalHeight = closestNaturalHeight(Object.keys(data[key].heights), height || width || DEFAULT_HEIGHT)
return `<svg ${htmlAttributes(data[key], data[key].heights[naturalHeight].options, options)}>${
data[key].heights[naturalHeight].path
}</svg>`
}
}
// Import data into exports
module.exports = data
function closestNaturalHeight(naturalHeights, height) {
return naturalHeights
.map(naturalHeight => parseInt(naturalHeight, 10))
.reduce((acc, naturalHeight) => (naturalHeight <= height ? naturalHeight : acc), naturalHeights[0])
}
================================================
FILE: lib/octicons_node/index.scss
================================================
.octicon {
display: inline-block;
vertical-align: text-top;
fill: currentColor;
overflow: visible;
}
================================================
FILE: lib/octicons_node/package.json
================================================
{
"name": "@primer/octicons",
"version": "19.23.1",
"description": "A scalable set of icons handcrafted with <3 by GitHub.",
"homepage": "https://primer.style/octicons",
"author": "GitHub Inc.",
"license": "MIT",
"style": "index.scss",
"main": "index.js",
"files": [
"index.js",
"index.scss",
"build"
],
"repository": "https://github.com/primer/octicons.git",
"bugs": {
"url": "https://github.com/primer/octicons/issues"
},
"scripts": {
"build": "\\cp -r ../build/. ./build && \\cp index.scss ./build/build.css",
"lint": "eslint index.js tests/*.js",
"test": "ava --verbose 'tests/*.js'"
},
"keywords": [
"GitHub",
"icons",
"svg",
"octicons"
],
"dependencies": {
"object-assign": "^4.1.1"
},
"devDependencies": {
"@github/prettier-config": "0.0.4",
"ava": "^0.22.0",
"eslint": "^6.5.1",
"eslint-plugin-github": "4.1.3"
},
"eslintConfig": {
"extends": [
"plugin:github/internal",
"plugin:github/recommended"
],
"env": {
"es6": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2017,
"requireConfigFile": false
},
"rules": {
"github/no-then": 0
}
}
}
================================================
FILE: lib/octicons_node/prettier.config.js
================================================
module.exports = require('@github/prettier-config')
================================================
FILE: lib/octicons_node/tests/index.js
================================================
import test from 'ava'
import octicons from '../'
test('Octicons are loaded', t => {
t.truthy(octicons, "Didn't find any octicons.")
t.not(Object.keys(octicons).length, 0, "Didn't find any octicons.")
})
test('Octicons have svg', t => {
t.truthy(octicons, "Didn't find any octicons.")
for (const point of Object.keys(octicons)) {
t.truthy(octicons[point].toSVG(), `The octicon "${point}" doesn't have svg`)
}
})
test('Octicons have default html attributes', t => {
t.truthy(octicons, "Didn't find any octicons.")
for (const point of Object.keys(octicons)) {
const svg = octicons[point].toSVG()
t.regex(svg, /version="1\.1"/, `The octicon "${point}" doesn't have the version attribute`)
t.regex(svg, /aria-hidden="true"/, `The octicon "${point}" doesn't have the aria-hidden attribute`)
t.regex(svg, new RegExp(`width=`), `The octicon "${point}" doesn't have the width attribute`)
t.regex(svg, new RegExp(`height=`), `The octicon "${point}" doesn't have the height attribute`)
t.regex(svg, new RegExp(`viewBox=`), `The octicon "${point}" doesn't have the viewBox attribute`)
t.regex(
svg,
new RegExp(`class="octicon octicon-${octicons[point].symbol}"`),
`The octicon "${point}" doesn't have the class attribute`
)
}
})
test('Passing in classnames will be included in output', t => {
t.truthy(octicons, "Didn't find any octicons.")
for (const point of Object.keys(octicons)) {
const svg = octicons[point].toSVG({class: 'new-class another-class'})
t.regex(
svg,
new RegExp(`class="octicon octicon-${octicons[point].symbol} new-class another-class"`),
`The octicon "${point}" doesn't have the class attribute`
)
}
})
test('Passing in aria-label will update the a11y options', t => {
t.truthy(octicons, "Didn't find any octicons.")
for (const point of Object.keys(octicons)) {
const svg = octicons[point].toSVG({'aria-label': 'This is an icon'})
t.regex(
svg,
new RegExp('aria-label="This is an icon"'),
`The octicon "${point}" doesn't have the aria-label attribute`
)
}
})
test('Passing in width will size properly', t => {
const svg = octicons['x'].toSVG({height: 60})
t.regex(svg, new RegExp('width="60"'), 'The octicon "x" doesn\'t have the width attribute scaled properly')
})
test('Passing in height will size properly', t => {
const svg = octicons['x'].toSVG({width: 45})
t.regex(svg, new RegExp('height="45"'), 'The octicon "x" doesn\'t have the height attribute scaled properly')
})
test('Passing in height will size properly', t => {
const svg = octicons['x'].toSVG({width: 45})
t.regex(svg, new RegExp('height="45"'), 'The octicon "x" doesn\'t have the height attribute scaled properly')
})
test('Chooses the correct svg given a height', t => {
const svg = octicons['x'].toSVG({height: 32})
t.regex(svg, new RegExp('width="32"'))
t.regex(svg, new RegExp('height="32"'))
t.regex(svg, new RegExp('viewBox="0 0 24 24"'))
})
test('Chooses the correct svg given a width', t => {
const svg = octicons['x'].toSVG({width: 24})
t.regex(svg, new RegExp('width="24"'))
t.regex(svg, new RegExp('height="24"'))
t.regex(svg, new RegExp('viewBox="0 0 24 24"'))
})
test('Chooses the correct svg given a width and height', t => {
const svg = octicons['x'].toSVG({width: 16, height: 24})
t.regex(svg, new RegExp('width="16"'))
t.regex(svg, new RegExp('height="24"'))
t.regex(svg, new RegExp('viewBox="0 0 24 24"'))
})
================================================
FILE: lib/octicons_react/.eslintignore
================================================
src/__generated__/
================================================
FILE: lib/octicons_react/.eslintrc.json
================================================
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
}
},
"extends": [
"plugin:react/recommended",
"plugin:jsx-a11y/recommended",
"plugin:prettier/recommended",
"plugin:github/recommended",
"plugin:github/browser"
],
"rules": {
"github/no-then": 0,
"import/named": 0,
"react/prop-types": 0
},
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"jest": true,
"node": true
},
"settings": {
"react": {
"version": "16"
}
}
}
================================================
FILE: lib/octicons_react/.gitignore
================================================
.cache
.next
dist/
src/__generated__/
.tool-versions
================================================
FILE: lib/octicons_react/.npmignore
================================================
*.config.js
.*.sw?
.*rc
.cache
.eslint*
.gitignore
.next
script
src
**/pages/**
**/__tests__/**
**/ts-tests/**
================================================
FILE: lib/octicons_react/.nvmrc
================================================
8
================================================
FILE: lib/octicons_react/LICENSE
================================================
MIT License
Copyright (c) 2026 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: lib/octicons_react/README.md
================================================
# @primer/octicons-react
[](https://www.npmjs.org/package/@primer/octicons-react)
## Install
```shell
npm install @primer/octicons-react
```
## Usage
### Icons
The `@primer/octicons-react` module exports individual icons as [named
exports](https://ponyfoo.com/articles/es6-modules-in-depth#named-exports). This
allows you to import only the icons that you need without blowing up your
bundle:
```jsx
import React from 'react'
import {BeakerIcon, ZapIcon} from '@primer/octicons-react'
export default function Icon({boom}) {
return boom ? <ZapIcon /> : <BeakerIcon />
}
```
If you were to compile this example with a tool that supports [tree-shaking][]
(such as Webpack, Rollup, or Parcel) the resulting bundle would only include
the "zap" and "beaker" icons.
### Vertical alignment
By default the octicons have `vertical-align: text-bottom;` applied as inline
styles. You can change the alignment via the `verticalAlign` prop, which can be
either `middle`, `text-bottom`, `text-top`, or `top`.
```js
import {RepoIcon} from '@primer/octicons-react'
export default () => (
<h1>
<RepoIcon verticalAlign="middle" /> github/github
</h1>
)
```
### `aria-label`
You have the option of adding accessibility information to the icon with the
[`aria-label` attribute][aria-label] via the `aria-label` prop.
```js
// Example usage
import {PlusIcon} from '@primer/octicons-react'
export default () => (
<button>
<PlusIcon aria-label="Add new item" /> New
</button>
)
```
### `aria-labelledby`
You have the option of adding accessibility information to the icon with the
[`aria-labelledby` attribute][aria-labelledby] via the `aria-labelledby` prop. Using aria-labelledby referencing the id values of the title element provides the accessible name.
```js
// Example usage
import {PlusIcon} from '@primer/octicons-react'
export default () => (
<button>
<PlusIcon aria-labelledby="title" title="Add new item" /> New
</button>
)
```
### `title`
You have the option of adding accessibility information to the icon with the
[`title` attribute][title] via the `title` prop.
### `id`
You have the option of adding information to the icon with the
[`id` attribute][id] via the `id` prop.
```js
// Example usage
import {PlusIcon} from '@primer/octicons-react'
export default () => (
<button>
<PlusIcon id="unique-plus-icon" /> New
</button>
)
```
### `tabIndex`
You can add the `tabindex` attribute to an SVG element via the `tabIndex` prop if the SVG element is intended to be interactive.
`tabIndex` prop also controls the `focusable` attribute of the SVG element which is defined by SVG Tiny 1.2 and only implemented in
Internet Explorer and Microsoft Edge.
If there is no `tabIndex` prop is present (default behavior), it will set the `focusable` attribute to `false`. This is helpful
for preventing the decorative SVG from being announced by some specialized assistive technology browsing modes which can get delayed
while trying to parse the SVG markup.
```js
// Example usage
import {PlusIcon} from '@primer/octicons-react'
export default () => (
<PlusIcon aria-label="Interactive Plus Icon" tabIndex={0} /> New Item
)
```
### Sizes
The `size` prop takes `small`, `medium`, and `large` values that can be used to
render octicons at standard sizes:
| Prop | Rendered Size |
| :-------------- | :------------------------------ |
| `size='small'` | 16px height by `computed` width |
| `size='medium'` | 32px height by `computed` width |
| `size='large'` | 64px height by `computed` width |
```js
// Example usage
import {LogoGithubIcon} from '@primer/octicons-react'
export default () => (
<h1>
<a href="https://github.com">
<LogoGithubIcon size="large" aria-label="GitHub" />
</a>
</h1>
)
```
### Fill
The `fill` prop takes a string value that can be used to set the color of the icon.
By default, `fill` is set to [`currentColor`](https://css-tricks.com/currentcolor/).
```js
// Example usage
import {LogoGithub} from '@primer/octicons-react'
export default () => (
<h1>
<a href="https://github.com">
<LogoGithubIcon fill="#f00" />
</a>
</h1>
)
```
[octicons]: https://primer.style/octicons/
[primer]: https://github.com/primer/primer
[docs]: http://primercss.io/
[npm]: https://www.npmjs.com/
[install-npm]: https://docs.npmjs.com/getting-started/installing-node
[tree-shaking]: https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking
[aria-label]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label
[aria-labelledby]: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby
[title]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title
[id]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id
================================================
FILE: lib/octicons_react/__tests__/__snapshots__/public-api.test.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`@primer/octicons-react should not update exports without a semver change 1`] = `
[
"AccessibilityIcon",
"AccessibilityInsetIcon",
"AgentIcon",
"AiModelIcon",
"AlertFillIcon",
"AlertIcon",
"AppsIcon",
"ArchiveIcon",
"ArrowBothIcon",
"ArrowDownIcon",
"ArrowDownLeftIcon",
"ArrowDownRightIcon",
"ArrowLeftIcon",
"ArrowRightIcon",
"ArrowSwitchIcon",
"ArrowUpIcon",
"ArrowUpLeftIcon",
"ArrowUpRightIcon",
"BeakerIcon",
"BellFillIcon",
"BellIcon",
"BellSlashIcon",
"BlockedIcon",
"BoldIcon",
"BookIcon",
"BookLockedIcon",
"BookmarkFillIcon",
"BookmarkFilledIcon",
"BookmarkIcon",
"BookmarkSlashFillIcon",
"BookmarkSlashIcon",
"BooleanOffIcon",
"BooleanOnIcon",
"BriefcaseIcon",
"BroadcastIcon",
"BrowserIcon",
"BugIcon",
"CacheIcon",
"CalendarIcon",
"CheckCircleFillIcon",
"CheckCircleIcon",
"CheckIcon",
"CheckboxFillIcon",
"CheckboxIcon",
"ChecklistIcon",
"ChevronDownIcon",
"ChevronLeftIcon",
"ChevronRightIcon",
"ChevronUpIcon",
"CircleIcon",
"CircleSlashIcon",
"ClockFillIcon",
"ClockIcon",
"CloudIcon",
"CloudOfflineIcon",
"CodeIcon",
"CodeOfConductIcon",
"CodeReviewIcon",
"CodeSquareIcon",
"CodescanCheckmarkIcon",
"CodescanIcon",
"CodespacesIcon",
"ColumnsIcon",
"CommandPaletteIcon",
"CommentAiIcon",
"CommentDiscussionIcon",
"CommentIcon",
"CommentLockedIcon",
"ComposeIcon",
"ContainerIcon",
"CopilotErrorIcon",
"CopilotIcon",
"CopilotWarningIcon",
"CopyIcon",
"CpuIcon",
"CreditCardIcon",
"CrossReferenceIcon",
"CrosshairsIcon",
"DashIcon",
"DatabaseIcon",
"DependabotIcon",
"DesktopDownloadIcon",
"DeviceCameraIcon",
"DeviceCameraVideoIcon",
"DeviceDesktopIcon",
"DeviceMobileIcon",
"DevicesIcon",
"DiamondIcon",
"DiceIcon",
"DiffAddedIcon",
"DiffIcon",
"DiffIgnoredIcon",
"DiffModifiedIcon",
"DiffRemovedIcon",
"DiffRenamedIcon",
"DiscussionClosedIcon",
"DiscussionDuplicateIcon",
"DiscussionOutdatedIcon",
"DotFillIcon",
"DotIcon",
"DownloadIcon",
"DuplicateIcon",
"EllipsisIcon",
"ExclamationIcon",
"EyeClosedIcon",
"EyeIcon",
"FeedDiscussionIcon",
"FeedForkedIcon",
"FeedHeartIcon",
"FeedIssueClosedIcon",
"FeedIssueDraftIcon",
"FeedIssueOpenIcon",
"FeedIssueReopenIcon",
"FeedMergedIcon",
"FeedPersonIcon",
"FeedPlusIcon",
"FeedPublicIcon",
"FeedPullRequestClosedIcon",
"FeedPullRequestDraftIcon",
"FeedPullRequestOpenIcon",
"FeedRepoIcon",
"FeedRocketIcon",
"FeedStarIcon",
"FeedTagIcon",
"FeedTrophyIcon",
"FileAddedIcon",
"FileBadgeIcon",
"FileBinaryIcon",
"FileCheckIcon",
"FileCodeIcon",
"FileDiffIcon",
"FileDirectoryFillIcon",
"FileDirectoryIcon",
"FileDirectoryOpenFillIcon",
"FileDirectorySymlinkIcon",
"FileIcon",
"FileMediaIcon",
"FileMovedIcon",
"FileRemovedIcon",
"FileSubmoduleIcon",
"FileSymlinkFileIcon",
"FileZipIcon",
"FilterIcon",
"FilterRemoveIcon",
"FiscalHostIcon",
"FlameIcon",
"FlowchartIcon",
"FocusCenterIcon",
"FoldDownIcon",
"FoldIcon",
"FoldUpIcon",
"GearIcon",
"GiftIcon",
"GitBranchCheckIcon",
"GitBranchIcon",
"GitCommitIcon",
"GitCompareIcon",
"GitMergeIcon",
"GitMergeQueueIcon",
"GitPullRequestClosedIcon",
"GitPullRequestDraftIcon",
"GitPullRequestIcon",
"GitPullRequestLockedIcon",
"GlobeIcon",
"GoalIcon",
"GrabberIcon",
"GraphBarHorizontalIcon",
"GraphBarVerticalIcon",
"GraphIcon",
"HashIcon",
"HeadingIcon",
"HeartFillIcon",
"HeartIcon",
"HistoryIcon",
"HomeFillIcon",
"HomeIcon",
"HorizontalRuleIcon",
"HourglassIcon",
"HubotIcon",
"IdBadgeIcon",
"ImageIcon",
"InboxFillIcon",
"InboxIcon",
"InfinityIcon",
"InfoIcon",
"IssueClosedIcon",
"IssueDraftIcon",
"IssueLockedIcon",
"IssueOpenedIcon",
"IssueReopenedIcon",
"IssueTrackedByIcon",
"IssueTracksIcon",
"ItalicIcon",
"IterationsIcon",
"KebabHorizontalIcon",
"KeyAsteriskIcon",
"KeyIcon",
"LawIcon",
"LightBulbIcon",
"LinkExternalIcon",
"LinkIcon",
"ListOrderedIcon",
"ListUnorderedIcon",
"LocationIcon",
"LockIcon",
"LockupGithubIcon",
"LogIcon",
"LogoGistIcon",
"LogoGithubIcon",
"LoopIcon",
"MailIcon",
"MarkGithubIcon",
"MarkdownIcon",
"MaximizeIcon",
"McpIcon",
"MegaphoneIcon",
"MentionIcon",
"MeterIcon",
"MilestoneIcon",
"MinimizeIcon",
"MirrorIcon",
"MoonIcon",
"MortarBoardIcon",
"MoveToBottomIcon",
"MoveToEndIcon",
"MoveToStartIcon",
"MoveToTopIcon",
"MultiSelectIcon",
"MuteIcon",
"NoEntryFillIcon",
"NoEntryIcon",
"NodeIcon",
"NorthStarIcon",
"NoteIcon",
"NumberIcon",
"OrganizationIcon",
"PackageDependenciesIcon",
"PackageDependentsIcon",
"PackageIcon",
"PaintbrushIcon",
"PaperAirplaneIcon",
"PaperclipIcon",
"PasskeyFillIcon",
"PasteIcon",
"PauseIcon",
"PencilAiIcon",
"PencilIcon",
"PeopleIcon",
"PersonAddIcon",
"PersonFillIcon",
"PersonIcon",
"PinIcon",
"PinSlashIcon",
"PivotColumnIcon",
"PlayIcon",
"PlugIcon",
"PlusCircleIcon",
"PlusIcon",
"ProjectIcon",
"ProjectRoadmapIcon",
"ProjectSymlinkIcon",
"ProjectTemplateIcon",
"PulseIcon",
"QuestionIcon",
"QuoteIcon",
"ReadIcon",
"RedoIcon",
"RelFilePathIcon",
"ReplyIcon",
"RepoCloneIcon",
"RepoDeleteIcon",
"RepoDeletedIcon",
"RepoForkedIcon",
"RepoIcon",
"RepoLockedIcon",
"RepoPullIcon",
"RepoPushIcon",
"RepoTemplateIcon",
"ReportIcon",
"RocketIcon",
"RowsIcon",
"RssIcon",
"RubyIcon",
"ScreenFullIcon",
"ScreenNormalIcon",
"SearchIcon",
"ServerIcon",
"ShareAndroidIcon",
"ShareIcon",
"ShieldCheckIcon",
"ShieldIcon",
"ShieldLockIcon",
"ShieldSlashIcon",
"ShieldXIcon",
"SidebarCollapseIcon",
"SidebarExpandIcon",
"SignInIcon",
"SignOutIcon",
"SingleSelectIcon",
"SkipFillIcon",
"SkipIcon",
"SlidersIcon",
"SmileyFrownIcon",
"SmileyFrustratedIcon",
"SmileyGrinIcon",
"SmileyIcon",
"SmileyNeutralIcon",
"SortAscIcon",
"SortDescIcon",
"SpaceIcon",
"SpacingLargeIcon",
"SpacingMediumIcon",
"SpacingSmallIcon",
"SparkleFillIcon",
"SparkleIcon",
"SparklesFillIcon",
"SplitViewIcon",
"SponsorTiersIcon",
"SquareCircleIcon",
"SquareFillIcon",
"SquareIcon",
"SquirrelIcon",
"StackIcon",
"StarFillIcon",
"StarIcon",
"StopIcon",
"StopwatchIcon",
"StrikethroughIcon",
"SunIcon",
"SyncIcon",
"TabExternalIcon",
"TabIcon",
"TableIcon",
"TagIcon",
"TasklistIcon",
"TelescopeFillIcon",
"TelescopeIcon",
"TerminalIcon",
"ThreeBarsIcon",
"ThumbsdownIcon",
"ThumbsupIcon",
"ToolsIcon",
"TrackedByClosedCompletedIcon",
"TrackedByClosedNotPlannedIcon",
"TrashIcon",
"TriangleDownIcon",
"TriangleLeftIcon",
"TriangleRightIcon",
"TriangleUpIcon",
"TrophyIcon",
"TypographyIcon",
"UndoIcon",
"UnfoldIcon",
"UnlinkIcon",
"UnlockIcon",
"UnmuteIcon",
"UnreadIcon",
"UnverifiedIcon",
"UnwrapIcon",
"UploadIcon",
"VerifiedIcon",
"VersionsIcon",
"VideoIcon",
"VscodeIcon",
"WebhookIcon",
"WorkflowIcon",
"WrapIcon",
"XCircleFillIcon",
"XCircleIcon",
"XIcon",
"ZapIcon",
"ZoomInIcon",
"ZoomOutIcon",
]
`;
================================================
FILE: lib/octicons_react/__tests__/public-api.test.js
================================================
import * as Octicons from '../'
describe('@primer/octicons-react', () => {
it('should not update exports without a semver change', () => {
expect(Object.keys(Octicons).sort()).toMatchSnapshot()
})
})
================================================
FILE: lib/octicons_react/__tests__/tree-shaking.test.js
================================================
const path = require('node:path')
const commonjs = require('@rollup/plugin-commonjs')
const {nodeResolve} = require('@rollup/plugin-node-resolve')
const {rollup} = require('rollup')
const virtual = require('@rollup/plugin-virtual')
const packageImport = path.resolve(__dirname, '..')
test('tree shaking', async () => {
const bundle = await rollup({
input: '__entrypoint__',
external: [],
plugins: [
nodeResolve(),
commonjs(),
virtual({
__entrypoint__: `import { AlertIcon } from '${packageImport}'`
})
],
onwarn: ({code, message}) => {
if (code !== 'EMPTY_BUNDLE') {
throw new Error(message)
}
}
})
const {output} = await bundle.generate({
format: 'esm'
})
for (const {code} of output) {
expect(code.trim()).toBe('')
}
})
test('tree shaking single export', async () => {
const bundle = await rollup({
input: '__entrypoint__',
external: ['react'],
plugins: [
nodeResolve(),
commonjs(),
virtual({
__entrypoint__: `export { XIcon } from '${packageImport}'`
})
]
})
const {output} = await bundle.generate({
format: 'esm'
})
const bundleSize = Buffer.byteLength(output[0].code.trim()) / 1000
expect(`${bundleSize}kB`).toMatchInlineSnapshot(`"6.084kB"`)
})
================================================
FILE: lib/octicons_react/babel.config.js
================================================
'use strict'
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
],
'@babel/preset-react'
],
env: {
production: {
presets: ['next/babel']
}
}
}
================================================
FILE: lib/octicons_react/jest.config.js
================================================
'use strict'
module.exports = {
moduleNameMapper: {
'^rollup$': require.resolve('rollup')
},
testEnvironment: 'jsdom',
transform: {
'^.+\\.(mjs|cjs|js|jsx)$': require.resolve('babel-jest')
}
}
================================================
FILE: lib/octicons_react/next.config.mjs
================================================
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
transpilePackages: ['@primer/components'],
pageExtensions: ['js', 'jsx', 'mjs', 'ts', 'tsx'],
}
export default nextConfig
================================================
FILE: lib/octicons_react/package.json
================================================
{
"name": "@primer/octicons-react",
"version": "19.23.1",
"description": "A scalable set of icons handcrafted with <3 by GitHub.",
"homepage": "https://primer.style/octicons",
"author": "GitHub, Inc.",
"license": "MIT",
"type": "commonjs",
"main": "dist/index.umd.js",
"module": "dist/index.esm.mjs",
"exports": {
"types": {
"import": "./dist/index.d.mts",
"require": "./dist/index.d.ts"
},
"import": "./dist/index.esm.mjs",
"require": "./dist/index.umd.js"
},
"sideEffects": false,
"types": "dist/index.d.ts",
"repository": "primer/octicons",
"scripts": {
"build": "script/build.js && script/types.js && rollup -c",
"clean": "rimraf .next dist src/__generated__",
"develop": "next",
"lint": "eslint src pages/*.mjs script",
"test": "jest",
"ts-test": "tsc -P ts-tests",
"posttest": "yarn ts-test"
},
"files": [
"dist"
],
"keywords": [
"GitHub",
"icons",
"svg",
"octicons",
"react",
"primer"
],
"devDependencies": {
"@babel/core": "^7.22.0",
"@babel/generator": "^7.22.0",
"@babel/preset-env": "^7.22.0",
"@babel/preset-react": "^7.22.0",
"@babel/types": "^7.22.0",
"@github/prettier-config": "0.0.4",
"@primer/components": "27.0.0",
"@rollup/plugin-babel": "5.3.1",
"@rollup/plugin-commonjs": "22.0.2",
"@rollup/plugin-node-resolve": "14.1.0",
"@rollup/plugin-virtual": "2.1.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/react": "^18.2.0",
"babel-jest": "29.0.3",
"eslint": "^6.5.1",
"eslint-plugin-github": "4.1.3",
"eslint-plugin-jest": "^21.17.0",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.23.2",
"fs-extra": "^6.0.1",
"jest": "^29.0.3",
"jest-environment-jsdom": "29.0.3",
"next": "^16.1.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rimraf": "3.0.2",
"rollup": "^2.79.0",
"styled-components": "^4.2.0",
"typescript": "^4.8.3"
},
"peerDependencies": {
"react": ">=16.3"
},
"engines": {
"node": ">=8"
}
}
================================================
FILE: lib/octicons_react/pages/_document.mjs
================================================
import React from 'react'
import Document, {Head, Html, Main, NextScript} from 'next/document'
export default class PrimerDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<link rel="stylesheet" href="https://unpkg.com/primer/build/build.css" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
================================================
FILE: lib/octicons_react/pages/index.mjs
================================================
import React from 'react'
import {Box, Text} from '@primer/components'
import pkg from '../package.json'
// eslint-disable-next-line import/no-namespace
import * as Octicons from '../'
// eslint-disable-next-line no-unused-vars, import/namespace
const {default: _Octicon, ...iconsByName} = Octicons
export default function App() {
const sizes = ['small', 'medium', 'large']
return (
<Box p={4}>
<table className="data-table">
<thead>
<tr>
<th>key</th>
<th>import</th>
<th>small, medium, large</th>
<th>code sample</th>
</tr>
</thead>
<tbody>
{Object.keys(iconsByName).map(key => {
const Icon = iconsByName[key]
const iconName = Icon.displayName || key
return (
<tr key={key}>
<td>
<Text mono nowrap>
{key}
</Text>
</td>
<td>
<Text mono nowrap>
{iconName}
</Text>
</td>
<td>
{sizes.map(size => (
<Text mr={4} key={size}>
<Icon size={size} verticalAlign="middle" />
</Text>
))}
</td>
<td>
<pre>
{`
import {${iconName}} from '${pkg.name}'
export default () => <${iconName} />
`.trim()}
</pre>
</td>
</tr>
)
})}
</tbody>
</table>
</Box>
)
}
================================================
FILE: lib/octicons_react/prettier.config.js
================================================
module.exports = require('@github/prettier-config')
================================================
FILE: lib/octicons_react/rollup.config.js
================================================
import babel from '@rollup/plugin-babel'
import commonjs from '@rollup/plugin-commonjs'
import packageJson from './package.json'
const dependencies = [
...Object.keys(packageJson.peerDependencies ?? {}),
...Object.keys(packageJson.dependencies ?? {}),
...Object.keys(packageJson.devDependencies ?? {})
]
function createPackageRegex(name) {
return new RegExp(`^${name}(/.*)?`)
}
const baseConfig = {
input: 'src/index.js',
external: dependencies.map(createPackageRegex),
plugins: [
babel({
babelrc: false,
presets: [
[
'@babel/preset-env',
{
modules: false
}
],
'@babel/preset-react'
],
babelHelpers: 'bundled'
}),
commonjs()
]
}
export default [
{
...baseConfig,
output: {
file: `dist/index.esm.mjs`,
format: 'esm'
}
},
{
...baseConfig,
output: {
file: `dist/index.umd.js`,
format: 'umd',
name: 'reocticons',
globals: {
react: 'React'
}
}
}
]
================================================
FILE: lib/octicons_react/script/.eslintrc.json
================================================
{
"env": {
"node": true,
"browser": false
},
"rules": {
"no-console": 0,
"no-shadow": 0
}
}
================================================
FILE: lib/octicons_react/script/build.js
================================================
#!/usr/bin/env node
const octicons = require('../../build/data.json')
const {default: generate} = require('@babel/generator')
const t = require('@babel/types')
const fse = require('fs-extra')
const {join, resolve} = require('path')
const srcDir = resolve(__dirname, '../src/__generated__')
const iconsFile = join(srcDir, 'icons.js')
const typesFile = join(srcDir, 'icons.d.ts')
const GENERATED_HEADER = '/* THIS FILE IS GENERATED. DO NOT EDIT IT. */'
function pascalCase(str) {
return str.replace(/(^|-)([a-z])/g, (_, __, c) => c.toUpperCase())
}
const icons = Object.entries(octicons)
.map(([key, octicon]) => {
const name = `${pascalCase(key)}Icon`
// Build an object with the following structure:
//
// type SVGData = {
// [key in string]: {
// width: number,
// path: React.JSXElement
// },
// }
//
const svgData = t.objectExpression(
Object.entries(octicon.heights).map(([height, icon]) => {
return t.objectProperty(
t.stringLiteral(height),
t.objectExpression([
t.objectProperty(t.stringLiteral('width'), t.numericLiteral(icon.width)),
t.objectProperty(t.stringLiteral('path'), svgToJSX(icon.ast))
])
)
})
)
// Define the icon by using the `createIconComponent` helper and the svgData
// defined above. This generates the following:
//
// const IconName = /*#__PURE__*/ createIconComponent('name', 'default-class-name', () => ({
// /* svgData */
// }));
//
const {code} = generate(
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(name),
t.addComment(
t.callExpression(t.identifier('createIconComponent'), [
// The name of the generated icon
t.stringLiteral(name),
// The className used on the underlying <svg> element
t.stringLiteral(`octicon octicon-${key}`),
t.arrowFunctionExpression([], t.blockStatement([t.returnStatement(svgData)]))
]),
'leading',
'#__PURE__'
)
)
])
)
return {
key,
name,
octicon,
code
}
})
.sort((a, b) => a.key.localeCompare(b.key))
function writeIcons(file) {
const count = icons.length
const code = `${GENERATED_HEADER}
import React from 'react'
import { createIconComponent } from '../createIconComponent'
${icons.map(({code}) => code).join('\n')}
export {
${icons.map(({name}) => name).join(',\n ')}
}`
return fse.writeFile(file, code, 'utf8').then(() => {
console.warn('wrote %s with %d exports', file, count)
return icons
})
}
function writeTypes(file) {
const count = icons.length
const code = `${GENERATED_HEADER}
import * as React from 'react'
type Size = 'small' | 'medium' | 'large'
interface IconProps {
'aria-label'?: string
className?: string
fill?: string
size?: number | Size
verticalAlign?: 'middle' | 'text-bottom' | 'text-top' | 'top' | 'unset'
}
type Icon = React.FC<IconProps>
${icons.map(({name}) => `declare const ${name}: Icon`).join('\n')}
export {
Icon,
IconProps,
${icons.map(({name}) => name).join(',\n ')}
}`
return fse.writeFile(file, code, 'utf8').then(() => {
console.warn('wrote %s with %d exports', file, count)
return icons
})
}
fse
.mkdirs(srcDir)
.then(() => writeIcons(iconsFile))
.then(() => writeTypes(typesFile))
.catch(error => {
console.error(error)
process.exit(1)
})
/**
* Convert a given node from an svg AST into a JS AST of JSX Elements
*/
function svgToJSX(node) {
if (node.type === 'element') {
const children = node.children.map(svgToJSX)
if (node.name === 'svg') {
if (children.length === 0) {
throw new Error(`No children available for icon`)
}
if (children.length > 1) {
return t.jsxFragment(t.jsxOpeningFragment(), t.jsxClosingFragment(), children)
}
return children[0]
}
const attrs = Object.entries(node.attributes).map(([key, value]) => {
if (typeof value !== 'string') {
throw new Error(`Unknown value type: ${value}`)
}
return t.jsxAttribute(t.jsxIdentifier(key), t.stringLiteral(value))
})
const openingElement = t.jsxOpeningElement(t.jsxIdentifier(node.name), attrs, children.length === 0)
const closingElement = t.jsxClosingElement(t.jsxIdentifier(node.name))
if (children.length > 0) {
return t.jsxElement(openingElement, closingElement, children, false)
}
return t.jsxElement(openingElement, closingElement, [], true)
}
throw new Error(`Unknown type: ${node.type}`)
}
================================================
FILE: lib/octicons_react/script/types.js
================================================
#!/usr/bin/env node
const fse = require('fs-extra')
const {join, resolve} = require('path')
const srcDir = resolve(__dirname, '../src/__generated__')
const iconsSrc = join(srcDir, 'icons.d.ts')
const indexSrc = join(srcDir, '../index.d.ts')
const destDir = resolve(__dirname, '../dist')
const iconsDest = join(destDir, 'icons.d.ts')
const indexDest = join(destDir, 'index.d.ts')
async function main() {
await fse.copy(iconsSrc, iconsDest)
let contents = await fse.readFile(indexSrc, 'utf8')
contents = contents.replace(/.\/__generated__\//g, './')
await fse.writeFile(indexDest, contents, 'utf8')
await fse.writeFile(join(destDir, 'index.d.mts'), contents, 'utf8')
}
main().catch(error => {
console.error(error)
process.exitCode = 1
})
================================================
FILE: lib/octicons_react/src/__tests__/.eslintrc.json
================================================
{
"rules": {
"github/unescaped-html-literal": 0
}
}
================================================
FILE: lib/octicons_react/src/__tests__/__snapshots__/octicon.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`An icon component matches snapshot 1`] = `
<svg
aria-hidden="true"
class="octicon octicon-alert"
display="inline-block"
fill="currentColor"
focusable="false"
height="16"
overflow="visible"
style="vertical-align: text-bottom;"
viewBox="0 0 16 16"
width="16"
>
<path
d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"
/>
</svg>
`;
================================================
FILE: lib/octicons_react/src/__tests__/octicon.js
================================================
import '@testing-library/jest-dom'
import {render, screen} from '@testing-library/react'
import React from 'react'
import {AlertIcon} from '../index'
describe('An icon component', () => {
it('matches snapshot', () => {
const {container} = render(<AlertIcon />)
expect(container.querySelector('svg')).toMatchSnapshot()
})
it('defaults to `aria-hidden="true"` if no label is present', () => {
const {container} = render(<AlertIcon />)
expect(container.querySelector('svg')).toHaveAttribute('aria-hidden', 'true')
})
it('sets `role="img"` if `aria-label` is provided', () => {
render(<AlertIcon aria-label="Alert" />)
expect(screen.getByLabelText('Alert')).toHaveAttribute('role', 'img')
})
it('sets `role="img"` if `aria-labelledby` is provided', () => {
render(
<>
<span id="label">Alert</span>
<AlertIcon aria-labelledby="label" />
</>
)
expect(screen.getByLabelText('Alert')).toHaveAttribute('role', 'img')
})
it('sets aria-hidden="false" if ariaLabel prop is present', () => {
const {container} = render(<AlertIcon aria-label="icon" />)
expect(container.querySelector('svg')).not.toHaveAttribute('aria-hidden')
expect(container.querySelector('svg')).toHaveAttribute('aria-label', 'icon')
})
it('set the focusable prop to false if tabIndex prop is not present', () => {
const {container} = render(<AlertIcon />)
expect(container.querySelector('svg')).toHaveAttribute('focusable', 'false')
})
it('sets focusable prop to true if tabIndex prop is present and greater than 0', () => {
const {container} = render(<AlertIcon aria-label="icon" tabIndex={0} />)
expect(container.querySelector('svg')).toHaveAttribute('tabindex', '0')
expect(container.querySelector('svg')).toHaveAttribute('focusable', 'true')
})
it('sets focusable prop to false if tabIndex prop is -1', () => {
const {container} = render(<AlertIcon aria-label="icon" tabIndex={-1} />)
expect(container.querySelector('svg')).toHaveAttribute('tabindex', '-1')
expect(container.querySelector('svg')).toHaveAttribute('focusable', 'false')
})
it('respects the className prop', () => {
const {container} = render(<AlertIcon className="foo" />)
expect(container.querySelector('svg')).to
gitextract_5k8z2tga/
├── .changeset/
│ ├── README.md
│ └── config.json
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug-report.md
│ │ ├── config.yml
│ │ └── feedback.md
│ ├── actions/
│ │ ├── build_node/
│ │ │ ├── Dockerfile
│ │ │ └── entrypoint.sh
│ │ ├── build_ruby/
│ │ │ ├── Dockerfile
│ │ │ └── entrypoint.sh
│ │ ├── python/
│ │ │ └── requirements.txt
│ │ └── version/
│ │ ├── Dockerfile
│ │ └── entrypoint.js
│ ├── dependabot.yml
│ └── workflows/
│ ├── add-to-inbox.yml
│ ├── check_for_changeset.yml
│ ├── ci.yml
│ ├── codeql.yml
│ ├── optimize.yml
│ ├── publish.yml
│ ├── release.yml
│ └── stale.yml
├── .gitignore
├── .npmrc
├── .rubocop.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Gemfile
├── LICENSE
├── README.md
├── add-octicon-checklist.md
├── keywords.json
├── lib/
│ ├── octicons_gem/
│ │ ├── .npmignore
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── lib/
│ │ │ ├── octicons/
│ │ │ │ ├── octicon.rb
│ │ │ │ └── version.rb
│ │ │ └── octicons.rb
│ │ ├── octicons.gemspec
│ │ └── test/
│ │ ├── helper.rb
│ │ ├── octicon_test.rb
│ │ └── octicons_test.rb
│ ├── octicons_helper/
│ │ ├── .npmignore
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── lib/
│ │ │ ├── octicons_helper/
│ │ │ │ ├── helper.rb
│ │ │ │ ├── railtie.rb
│ │ │ │ └── version.rb
│ │ │ └── octicons_helper.rb
│ │ ├── octicons_helper.gemspec
│ │ └── test/
│ │ ├── helper.rb
│ │ └── octicons_helper_test.rb
│ ├── octicons_jekyll/
│ │ ├── .npmignore
│ │ ├── .rubocop.yml
│ │ ├── Gemfile
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── jekyll-octicons.gemspec
│ │ ├── lib/
│ │ │ ├── jekyll-octicons/
│ │ │ │ └── version.rb
│ │ │ └── jekyll-octicons.rb
│ │ └── test/
│ │ ├── helper.rb
│ │ └── octicon_tag_test.rb
│ ├── octicons_node/
│ │ ├── .npmignore
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── index.scss
│ │ ├── package.json
│ │ ├── prettier.config.js
│ │ └── tests/
│ │ └── index.js
│ ├── octicons_react/
│ │ ├── .eslintignore
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── .nvmrc
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── __snapshots__/
│ │ │ │ └── public-api.test.js.snap
│ │ │ ├── public-api.test.js
│ │ │ └── tree-shaking.test.js
│ │ ├── babel.config.js
│ │ ├── jest.config.js
│ │ ├── next.config.mjs
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── _document.mjs
│ │ │ └── index.mjs
│ │ ├── prettier.config.js
│ │ ├── rollup.config.js
│ │ ├── script/
│ │ │ ├── .eslintrc.json
│ │ │ ├── build.js
│ │ │ └── types.js
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── .eslintrc.json
│ │ │ │ ├── __snapshots__/
│ │ │ │ │ └── octicon.js.snap
│ │ │ │ └── octicon.js
│ │ │ ├── createIconComponent.js
│ │ │ ├── index.d.ts
│ │ │ └── index.js
│ │ └── ts-tests/
│ │ ├── index.tsx
│ │ └── tsconfig.json
│ └── octicons_styled/
│ ├── .babelrc
│ ├── .eslintignore
│ ├── .eslintrc.json
│ ├── .gitignore
│ ├── .npmignore
│ ├── .nvmrc
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── prettier.config.js
│ ├── rollup.config.js
│ ├── script/
│ │ ├── .eslintrc.json
│ │ ├── build.js
│ │ └── copy.sh
│ ├── src/
│ │ ├── __tests__/
│ │ │ ├── .eslintrc.json
│ │ │ └── octicon.js
│ │ └── utils.js
│ └── ts-tests/
│ ├── index.tsx
│ └── tsconfig.json
├── package.json
├── prettier.config.js
├── script/
│ ├── build.js
│ ├── changeset-publish
│ └── version
├── svgo.config.js
└── tests/
├── build.js
├── index.js
└── snapshots/
├── build.js.md
└── build.js.snap
SYMBOL INDEX (57 symbols across 23 files)
FILE: lib/octicons_gem/lib/octicons.rb
type Octicons (line 7) | module Octicons
FILE: lib/octicons_gem/lib/octicons/octicon.rb
type Octicons (line 3) | module Octicons
class Octicon (line 4) | class Octicon
method initialize (line 9) | def initialize(symbol, options = {})
method to_svg (line 30) | def to_svg
method html_attributes (line 36) | def html_attributes
method a11y (line 43) | def a11y
method classes (line 56) | def classes
method viewbox (line 60) | def viewbox
method size (line 65) | def size
method calculate_width (line 80) | def calculate_width(height)
method calculate_height (line 84) | def calculate_height(width)
method get_octicon (line 88) | def get_octicon(symbol, options = {})
method closest_natural_height (line 103) | def closest_natural_height(natural_heights, height)
FILE: lib/octicons_gem/lib/octicons/version.rb
type Octicons (line 3) | module Octicons
FILE: lib/octicons_gem/test/helper.rb
function octicon (line 6) | def octicon(symbol, options = {})
FILE: lib/octicons_helper/lib/octicons_helper/helper.rb
type OcticonsHelper (line 6) | module OcticonsHelper
function octicon (line 11) | def octicon(symbol, options = {})
FILE: lib/octicons_helper/lib/octicons_helper/railtie.rb
type OcticonsHelper (line 5) | module OcticonsHelper
class Railtie (line 6) | class Railtie < Rails::Railtie
FILE: lib/octicons_helper/lib/octicons_helper/version.rb
type OcticonsHelper (line 3) | module OcticonsHelper
FILE: lib/octicons_helper/test/octicons_helper_test.rb
function path (line 27) | def mock.path
function options (line 35) | def mock.options; end
FILE: lib/octicons_jekyll/lib/jekyll-octicons.rb
type Jekyll (line 8) | module Jekyll
class Octicons (line 9) | class Octicons < Liquid::Tag
method initialize (line 24) | def initialize(tag_name, markup, options)
method render (line 32) | def render(context)
method interpolate (line 41) | def interpolate(markup, context)
method prepare (line 48) | def prepare(markup)
method symbol (line 53) | def symbol(markup)
method string_to_hash (line 60) | def string_to_hash(markup)
FILE: lib/octicons_jekyll/lib/jekyll-octicons/version.rb
type Liquid (line 4) | module Liquid; class Tag; end; end
class Tag (line 4) | class Tag; end
type Jekyll (line 6) | module Jekyll
class Octicons (line 7) | class Octicons < Liquid::Tag
FILE: lib/octicons_jekyll/test/helper.rb
function parse (line 8) | def parse(string)
function render (line 14) | def render(string, assigns = {})
FILE: lib/octicons_node/index.js
constant DEFAULT_HEIGHT (line 4) | const DEFAULT_HEIGHT = 16
function closestNaturalHeight (line 75) | function closestNaturalHeight(naturalHeights, height) {
FILE: lib/octicons_react/pages/_document.mjs
class PrimerDocument (line 4) | class PrimerDocument extends Document {
method render (line 5) | render() {
FILE: lib/octicons_react/pages/index.mjs
function App (line 10) | function App() {
FILE: lib/octicons_react/rollup.config.js
function createPackageRegex (line 11) | function createPackageRegex(name) {
FILE: lib/octicons_react/script/build.js
constant GENERATED_HEADER (line 13) | const GENERATED_HEADER = '/* THIS FILE IS GENERATED. DO NOT EDIT IT. */'
function pascalCase (line 15) | function pascalCase(str) {
function writeIcons (line 77) | function writeIcons(file) {
function writeTypes (line 94) | function writeTypes(file) {
function svgToJSX (line 136) | function svgToJSX(node) {
FILE: lib/octicons_react/script/types.js
function main (line 13) | async function main() {
FILE: lib/octicons_react/src/createIconComponent.js
function createIconComponent (line 9) | function createIconComponent(name, defaultClassName, getSVGData) {
function closestNaturalHeight (line 73) | function closestNaturalHeight(naturalHeights, height) {
FILE: lib/octicons_react/src/index.d.ts
type Size (line 7) | type Size = 'small' | 'medium' | 'large'
type OcticonProps (line 9) | interface OcticonProps extends React.ComponentPropsWithoutRef<'svg'> {
FILE: lib/octicons_react/ts-tests/index.tsx
function TestOcticons (line 4) | function TestOcticons() {
FILE: lib/octicons_styled/script/build.js
constant GENERATED_HEADER (line 6) | const GENERATED_HEADER = '/* THIS FILE IS GENERATED. DO NOT EDIT IT. */'
FILE: lib/octicons_styled/src/utils.js
constant COMMON (line 5) | const COMMON = styledSystem.compose(styledSystem.space, styledSystem.color)
FILE: lib/octicons_styled/ts-tests/index.tsx
function TestOcticons (line 4) | function TestOcticons() {
Condensed preview — 134 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (246K chars).
[
{
"path": ".changeset/README.md",
"chars": 510,
"preview": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that wo"
},
{
"path": ".changeset/config.json",
"chars": 290,
"preview": "{\n \"$schema\": \"https://unpkg.com/@changesets/config@1.6.1/schema.json\",\n \"changelog\": [\"@changesets/changelog-github\","
},
{
"path": ".github/CODEOWNERS",
"chars": 36,
"preview": "* @primer/engineer-reviewers\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug-report.md",
"chars": 1120,
"preview": "---\nname: 🐞 Bug report\nabout: Report a bug in Octicons \ntitle: \"[Bug] \"\nlabels: \"bug, octicon\"\nassignees: ''\n\n---\n\n<!-- "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 196,
"preview": "blank_issues_enabled: true\n\ncontact_links:\n - name: Add to the Octicon library?\n url: https://github.com/github/"
},
{
"path": ".github/ISSUE_TEMPLATE/feedback.md",
"chars": 721,
"preview": "---\nname: 💬 Feedback and ideas\nabout: Suggest improvements or give feedback on icon designs\ntitle: \"[Feedback] \"\nlabels:"
},
{
"path": ".github/actions/build_node/Dockerfile",
"chars": 234,
"preview": "FROM node:24-slim\n\nRUN apt-get update && \\\n apt-get install --no-install-recommends -y \\\n jq && \\\n apt-"
},
{
"path": ".github/actions/build_node/entrypoint.sh",
"chars": 771,
"preview": "#!/bin/bash -l\n\nset -e\n\nPACKAGE_VERSION=$(jq '.version' --raw-output ./package.json)\n\necho \"************* Building v$PAC"
},
{
"path": ".github/actions/build_ruby/Dockerfile",
"chars": 230,
"preview": "FROM ruby:3.0\n\nRUN apt-get update && \\\n apt-get install --no-install-recommends -y \\\n jq && \\\n apt-get "
},
{
"path": ".github/actions/build_ruby/entrypoint.sh",
"chars": 1077,
"preview": "#!/bin/bash -l\n\nset -e\n\nPACKAGE_VERSION=$(jq '.version' --raw-output ./package.json)\n\nPACKAGE_VERSION=$(echo $PACKAGE_VE"
},
{
"path": ".github/actions/python/requirements.txt",
"chars": 15,
"preview": "picosvg~=0.20.6"
},
{
"path": ".github/actions/version/Dockerfile",
"chars": 95,
"preview": "FROM node:10-slim\n\nWORKDIR /\nCOPY . /\nRUN npm install\n\nENTRYPOINT [ \"node\", \"/entrypoint.js\" ]\n"
},
{
"path": ".github/actions/version/entrypoint.js",
"chars": 934,
"preview": "const fs = require('fs')\nconst {\n resolve\n} = require('path')\n const {\n GITHUB_REF,\n GITHUB_SHA\n} = process.env\n\n// O"
},
{
"path": ".github/dependabot.yml",
"chars": 573,
"preview": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where "
},
{
"path": ".github/workflows/add-to-inbox.yml",
"chars": 1161,
"preview": "name: Add to Inbox 📥\non:\n issues:\n types: [opened, reopened]\n\njobs:\n add-to-inbox:\n if: ${{ github.repository =="
},
{
"path": ".github/workflows/check_for_changeset.yml",
"chars": 796,
"preview": "name: Check for changeset\n\non:\n pull_request:\n types:\n # On by default if you specify no types.\n - 'opened"
},
{
"path": ".github/workflows/ci.yml",
"chars": 4400,
"preview": "name: CI\non:\n push:\n branches:\n - main\n pull_request:\n\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n "
},
{
"path": ".github/workflows/codeql.yml",
"chars": 2732,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/optimize.yml",
"chars": 989,
"preview": "on: \n push:\n paths:\n - 'icons/**'\n - '.github/workflows/optimize.yml'\n - '.github/actions/python/requ"
},
{
"path": ".github/workflows/publish.yml",
"chars": 2866,
"preview": "on:\n release:\n types: [published]\n workflow_dispatch:\n\npermissions:\n id-token: write # Required for OIDC\n content"
},
{
"path": ".github/workflows/release.yml",
"chars": 1573,
"preview": "name: Release\non:\n push:\n branches:\n - \"main\"\n - \"next_major\"\njobs:\n release:\n name: Final\n if: ${{"
},
{
"path": ".github/workflows/stale.yml",
"chars": 1025,
"preview": "name: Stale\non:\n schedule:\n - cron: '0 * * * *'\n\njobs:\n stale:\n runs-on: ubuntu-latest\n steps:\n - uses: "
},
{
"path": ".gitignore",
"chars": 170,
"preview": "*.gem\n/package-lock.json\n*.log\n.DS_Store\n.bundle\n.env\nnode_modules\nvendor\nGemfile.lock\n\n# Ignore build/export artifacts\n"
},
{
"path": ".npmrc",
"chars": 35,
"preview": "save-exact=true\npackage-lock=false\n"
},
{
"path": ".rubocop.yml",
"chars": 106,
"preview": "inherit_gem:\n rubocop-github:\n - config/default.yml\n - config/rails.yml\nAllCops:\n NewCops: enable\n"
},
{
"path": "CHANGELOG.md",
"chars": 61402,
"preview": "# Changelog\n\n## 19.23.1\n\n### Patch Changes\n\n- [#1175](https://github.com/primer/octicons/pull/1175) [`ea8e6bb7`](https:/"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 3357,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
},
{
"path": "CONTRIBUTING.md",
"chars": 7107,
"preview": "# Octicons Contribution Guidelines (Currently GitHub Staff only)\n\nThank you for your interest in contributing to Octicon"
},
{
"path": "Gemfile",
"chars": 158,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\n\ngroup :development, :test do\n gem \"minitest\"\n gem \"rake\""
},
{
"path": "LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "README.md",
"chars": 4286,
"preview": " 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_gem/README.md",
"chars": 3237,
"preview": "# octicons \n\n[](https://rubygems.org/gems/octicons)\n\n## Install"
},
{
"path": "lib/octicons_gem/Rakefile",
"chars": 584,
"preview": "# frozen_string_literal: true\n\nrequire \"rake/testtask\"\nrequire \"rubocop/rake_task\"\nrequire \"bundler/gem_tasks\"\n\nRuboCop:"
},
{
"path": "lib/octicons_gem/lib/octicons/octicon.rb",
"chars": 2984,
"preview": "# frozen_string_literal: true\n\nmodule Octicons\n class Octicon\n DEFAULT_HEIGHT = 16\n\n attr_reader :path, :options,"
},
{
"path": "lib/octicons_gem/lib/octicons/version.rb",
"chars": 79,
"preview": "# frozen_string_literal: true\n\nmodule Octicons\n VERSION = \"19.9.0\".freeze\nend\n"
},
{
"path": "lib/octicons_gem/lib/octicons.rb",
"chars": 250,
"preview": "# frozen_string_literal: true\n\nrequire \"octicons/version\"\nrequire \"octicons/octicon\"\nrequire \"json\"\n\nmodule Octicons\n f"
},
{
"path": "lib/octicons_gem/octicons.gemspec",
"chars": 555,
"preview": "# frozen_string_literal: true\n\nrequire File.expand_path(\"../lib/octicons/version\", __FILE__)\n\nGem::Specification.new do "
},
{
"path": "lib/octicons_gem/test/helper.rb",
"chars": 157,
"preview": "# frozen_string_literal: true\n\nrequire \"minitest/autorun\"\nrequire \"octicons\"\n\ndef octicon(symbol, options = {})\n Octico"
},
{
"path": "lib/octicons_gem/test/octicon_test.rb",
"chars": 4070,
"preview": "# frozen_string_literal: true\n\nrequire_relative \"helper\"\n\ndescribe Octicons::Octicon do\n it \"fails when the octicon doe"
},
{
"path": "lib/octicons_gem/test/octicons_test.rb",
"chars": 437,
"preview": "# frozen_string_literal: true\n\nrequire_relative \"helper\"\n\ndescribe Octicons do\n it \"loads all icons on initialization\" "
},
{
"path": "lib/octicons_helper/.npmignore",
"chars": 2,
"preview": "*\n"
},
{
"path": "lib/octicons_helper/Gemfile",
"chars": 241,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\n\ngemspec\n\ngem \"octicons\", \"19.9.0\"\ngem \"rails\"\n\ngroup :deve"
},
{
"path": "lib/octicons_helper/LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_helper/README.md",
"chars": 609,
"preview": "# octicons_helper\n\n[](https://rubygems.org/gems/octicons"
},
{
"path": "lib/octicons_helper/Rakefile",
"chars": 921,
"preview": "# frozen_string_literal: true\n\nrequire \"rake/testtask\"\nrequire \"rubocop/rake_task\"\nrequire \"bundler/gem_tasks\"\n\nRuboCop:"
},
{
"path": "lib/octicons_helper/lib/octicons_helper/helper.rb",
"chars": 592,
"preview": "# frozen_string_literal: true\n\nrequire \"octicons\"\nrequire \"action_view\"\n\nmodule OcticonsHelper\n include ActionView::Hel"
},
{
"path": "lib/octicons_helper/lib/octicons_helper/railtie.rb",
"chars": 218,
"preview": "# frozen_string_literal: true\n\nrequire \"rails\"\n\nmodule OcticonsHelper\n class Railtie < Rails::Railtie\n initializer \""
},
{
"path": "lib/octicons_helper/lib/octicons_helper/version.rb",
"chars": 85,
"preview": "# frozen_string_literal: true\n\nmodule OcticonsHelper\n VERSION = \"19.9.0\".freeze\nend\n"
},
{
"path": "lib/octicons_helper/lib/octicons_helper.rb",
"chars": 151,
"preview": "# frozen_string_literal: true\n\nrequire \"octicons_helper/version\"\nrequire \"octicons_helper/helper\"\nrequire \"octicons_help"
},
{
"path": "lib/octicons_helper/octicons_helper.gemspec",
"chars": 681,
"preview": "# frozen_string_literal: true\n\nrequire File.expand_path(\"../lib/octicons_helper/version\", __FILE__)\n\nGem::Specification."
},
{
"path": "lib/octicons_helper/test/helper.rb",
"chars": 132,
"preview": "# frozen_string_literal: true\n\nrequire \"minitest/autorun\"\nrequire \"minitest/mock\"\nrequire \"octicons_helper\"\n\ninclude Oct"
},
{
"path": "lib/octicons_helper/test/octicons_helper_test.rb",
"chars": 1005,
"preview": "# frozen_string_literal: true\n\nrequire_relative \"helper\"\n\ndescribe OcticonsHelper do\n describe \"rendering\" do\n it \"r"
},
{
"path": "lib/octicons_jekyll/.npmignore",
"chars": 2,
"preview": "*\n"
},
{
"path": "lib/octicons_jekyll/.rubocop.yml",
"chars": 193,
"preview": "inherit_gem:\n rubocop-github:\n - config/default.yml\n\nNaming/FileName:\n Enabled: false\n\nStyle/OneClassPerFile:\n Exc"
},
{
"path": "lib/octicons_jekyll/Gemfile",
"chars": 219,
"preview": "# frozen_string_literal: true\n\nsource \"https://rubygems.org\"\n\ngemspec\n\ngem \"octicons\", \"19.8.0\"\n\ngroup :development, :te"
},
{
"path": "lib/octicons_jekyll/LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_jekyll/README.md",
"chars": 708,
"preview": "# jekyll-octicons\n\n[](https://rubygems.org/gems/jekyll-o"
},
{
"path": "lib/octicons_jekyll/Rakefile",
"chars": 1054,
"preview": "# frozen_string_literal: true\n\nrequire \"rake/testtask\"\nrequire \"rubocop/rake_task\"\nrequire \"bundler/gem_tasks\"\n\nRuboCop:"
},
{
"path": "lib/octicons_jekyll/jekyll-octicons.gemspec",
"chars": 681,
"preview": "# frozen_string_literal: true\n\nrequire File.expand_path(\"../lib/jekyll-octicons/version\", __FILE__)\n\nGem::Specification."
},
{
"path": "lib/octicons_jekyll/lib/jekyll-octicons/version.rb",
"chars": 177,
"preview": "# frozen_string_literal: true\n\n# Prevent bundler errors\nmodule Liquid; class Tag; end; end\n\nmodule Jekyll\n class Octico"
},
{
"path": "lib/octicons_jekyll/lib/jekyll-octicons.rb",
"chars": 1818,
"preview": "# frozen_string_literal: true\n\nrequire \"octicons\"\nrequire \"jekyll-octicons/version\"\nrequire \"liquid\"\nrequire \"jekyll/liq"
},
{
"path": "lib/octicons_jekyll/test/helper.rb",
"chars": 344,
"preview": "# frozen_string_literal: true\n\nrequire \"minitest/autorun\"\nrequire \"jekyll-octicons\"\n\n# Parse a string into a liquid temp"
},
{
"path": "lib/octicons_jekyll/test/octicon_tag_test.rb",
"chars": 940,
"preview": "# frozen_string_literal: true\n\nrequire_relative \"helper\"\n\ndescribe Jekyll::Octicons do\n describe \"parsing\" do\n it \"p"
},
{
"path": "lib/octicons_node/.npmignore",
"chars": 7,
"preview": "script\n"
},
{
"path": "lib/octicons_node/LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_node/README.md",
"chars": 5757,
"preview": "# @primer/octicons\n\n\n[](https://www.npmjs.org/package/@"
},
{
"path": "lib/octicons_node/index.js",
"chars": 2583,
"preview": "const data = require('./build/data.json')\nconst objectAssign = require('object-assign')\n\nconst DEFAULT_HEIGHT = 16\n\nfor "
},
{
"path": "lib/octicons_node/index.scss",
"chars": 109,
"preview": ".octicon {\n display: inline-block;\n vertical-align: text-top;\n fill: currentColor;\n overflow: visible;\n}\n"
},
{
"path": "lib/octicons_node/package.json",
"chars": 1239,
"preview": "{\n \"name\": \"@primer/octicons\",\n \"version\": \"19.23.1\",\n \"description\": \"A scalable set of icons handcrafted with <3 by"
},
{
"path": "lib/octicons_node/prettier.config.js",
"chars": 52,
"preview": "module.exports = require('@github/prettier-config')\n"
},
{
"path": "lib/octicons_node/tests/index.js",
"chars": 3495,
"preview": "import test from 'ava'\nimport octicons from '../'\n\ntest('Octicons are loaded', t => {\n t.truthy(octicons, \"Didn't find "
},
{
"path": "lib/octicons_react/.eslintignore",
"chars": 19,
"preview": "src/__generated__/\n"
},
{
"path": "lib/octicons_react/.eslintrc.json",
"chars": 566,
"preview": "{\n \"parser\": \"@typescript-eslint/parser\",\n \"parserOptions\": {\n \"ecmaFeatures\": {\n \"jsx\": true\n }\n },\n \"ex"
},
{
"path": "lib/octicons_react/.gitignore",
"chars": 53,
"preview": ".cache\n.next\ndist/\nsrc/__generated__/\n.tool-versions\n"
},
{
"path": "lib/octicons_react/.npmignore",
"chars": 111,
"preview": "*.config.js\n.*.sw?\n.*rc\n.cache\n.eslint*\n.gitignore\n.next\nscript\nsrc\n**/pages/**\n**/__tests__/**\n**/ts-tests/**\n"
},
{
"path": "lib/octicons_react/.nvmrc",
"chars": 2,
"preview": "8\n"
},
{
"path": "lib/octicons_react/LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_react/README.md",
"chars": 4900,
"preview": "# @primer/octicons-react\n\n[](https://www.npmjs.or"
},
{
"path": "lib/octicons_react/__tests__/__snapshots__/public-api.test.js.snap",
"chars": 7255,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`@primer/octicons-react should not update exports without a semver c"
},
{
"path": "lib/octicons_react/__tests__/public-api.test.js",
"chars": 209,
"preview": "import * as Octicons from '../'\n\ndescribe('@primer/octicons-react', () => {\n it('should not update exports without a se"
},
{
"path": "lib/octicons_react/__tests__/tree-shaking.test.js",
"chars": 1317,
"preview": "const path = require('node:path')\nconst commonjs = require('@rollup/plugin-commonjs')\nconst {nodeResolve} = require('@ro"
},
{
"path": "lib/octicons_react/babel.config.js",
"chars": 257,
"preview": "'use strict'\n\nmodule.exports = {\n presets: [\n [\n '@babel/preset-env',\n {\n targets: {\n node"
},
{
"path": "lib/octicons_react/jest.config.js",
"chars": 212,
"preview": "'use strict'\n\nmodule.exports = {\n moduleNameMapper: {\n '^rollup$': require.resolve('rollup')\n },\n testEnvironment:"
},
{
"path": "lib/octicons_react/next.config.mjs",
"chars": 214,
"preview": "/** @type {import('next').NextConfig} */\nconst nextConfig = {\n reactStrictMode: true,\n transpilePackages: ['@primer/co"
},
{
"path": "lib/octicons_react/package.json",
"chars": 2138,
"preview": "{\n \"name\": \"@primer/octicons-react\",\n \"version\": \"19.23.1\",\n \"description\": \"A scalable set of icons handcrafted with"
},
{
"path": "lib/octicons_react/pages/_document.mjs",
"chars": 416,
"preview": "import React from 'react'\nimport Document, {Head, Html, Main, NextScript} from 'next/document'\n\nexport default class Pri"
},
{
"path": "lib/octicons_react/pages/index.mjs",
"chars": 1673,
"preview": "import React from 'react'\nimport {Box, Text} from '@primer/components'\nimport pkg from '../package.json'\n// eslint-disab"
},
{
"path": "lib/octicons_react/prettier.config.js",
"chars": 52,
"preview": "module.exports = require('@github/prettier-config')\n"
},
{
"path": "lib/octicons_react/rollup.config.js",
"chars": 1047,
"preview": "import babel from '@rollup/plugin-babel'\nimport commonjs from '@rollup/plugin-commonjs'\nimport packageJson from './packa"
},
{
"path": "lib/octicons_react/script/.eslintrc.json",
"chars": 116,
"preview": "{\n \"env\": {\n \"node\": true,\n \"browser\": false\n },\n \"rules\": {\n \"no-console\": 0,\n \"no-shadow\": 0\n }\n}\n"
},
{
"path": "lib/octicons_react/script/build.js",
"chars": 4700,
"preview": "#!/usr/bin/env node\n\nconst octicons = require('../../build/data.json')\nconst {default: generate} = require('@babel/gener"
},
{
"path": "lib/octicons_react/script/types.js",
"chars": 756,
"preview": "#!/usr/bin/env node\nconst fse = require('fs-extra')\nconst {join, resolve} = require('path')\n\nconst srcDir = resolve(__di"
},
{
"path": "lib/octicons_react/src/__tests__/.eslintrc.json",
"chars": 60,
"preview": "{\n \"rules\": {\n \"github/unescaped-html-literal\": 0\n }\n}\n"
},
{
"path": "lib/octicons_react/src/__tests__/__snapshots__/octicon.js.snap",
"chars": 666,
"preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`An icon component matches snapshot 1`] = `\n<svg\n aria-hidden=\"true"
},
{
"path": "lib/octicons_react/src/__tests__/octicon.js",
"chars": 4768,
"preview": "import '@testing-library/jest-dom'\nimport {render, screen} from '@testing-library/react'\nimport React from 'react'\nimpor"
},
{
"path": "lib/octicons_react/src/createIconComponent.js",
"chars": 2052,
"preview": "import React from 'react'\n\nconst sizeMap = {\n small: 16,\n medium: 32,\n large: 64\n}\n\nexport function createIconCompone"
},
{
"path": "lib/octicons_react/src/index.d.ts",
"chars": 721,
"preview": "// eslint-disable-next-line import/no-namespace\nimport * as React from 'react'\n\n// eslint-disable-next-line prettier/pre"
},
{
"path": "lib/octicons_react/src/index.js",
"chars": 38,
"preview": "export * from './__generated__/icons'\n"
},
{
"path": "lib/octicons_react/ts-tests/index.tsx",
"chars": 289,
"preview": "import * as React from 'react'\nimport {MarkGithubIcon, PlusIcon, RepoIcon} from '../src'\n\nfunction TestOcticons() {\n re"
},
{
"path": "lib/octicons_react/ts-tests/tsconfig.json",
"chars": 251,
"preview": "{\n \"$schema\": \"http://json.schemastore.org/tsconfig\",\n \"compileOnSave\": false,\n \"compilerOptions\": {\n \"module\": \"c"
},
{
"path": "lib/octicons_styled/.babelrc",
"chars": 119,
"preview": "{\n \"presets\": [\"env\", \"stage-0\", \"react\"],\n \"env\": {\n \"production\": {\n \"presets\": [\"next/babel\"]\n }\n }\n}\n"
},
{
"path": "lib/octicons_styled/.eslintignore",
"chars": 19,
"preview": "src/__generated__/\n"
},
{
"path": "lib/octicons_styled/.eslintrc.json",
"chars": 566,
"preview": "{\n \"parser\": \"@typescript-eslint/parser\",\n \"parserOptions\": {\n \"ecmaFeatures\": {\n \"jsx\": true\n }\n },\n \"ex"
},
{
"path": "lib/octicons_styled/.gitignore",
"chars": 38,
"preview": ".cache\n.next\ndist/\nsrc/__generated__/\n"
},
{
"path": "lib/octicons_styled/.npmignore",
"chars": 68,
"preview": "*.config.js\n.*.sw?\n.*rc\n.cache\n.eslint*\n.gitignore\n.next\nscript\nsrc\n"
},
{
"path": "lib/octicons_styled/.nvmrc",
"chars": 2,
"preview": "8\n"
},
{
"path": "lib/octicons_styled/LICENSE",
"chars": 1068,
"preview": "MIT License\n\nCopyright (c) 2026 GitHub Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a cop"
},
{
"path": "lib/octicons_styled/README.md",
"chars": 1871,
"preview": "# @primer/styled-octicons\n\n[](https://www.npmjs."
},
{
"path": "lib/octicons_styled/package.json",
"chars": 1860,
"preview": "{\n \"name\": \"@primer/styled-octicons\",\n \"version\": \"16.1.0\",\n \"description\": \"A scalable set of icons handcrafted with"
},
{
"path": "lib/octicons_styled/prettier.config.js",
"chars": 52,
"preview": "module.exports = require('@github/prettier-config')\n"
},
{
"path": "lib/octicons_styled/rollup.config.js",
"chars": 1000,
"preview": "import babel from '@rollup/plugin-babel'\n// eslint-disable-next-line import/no-namespace\nimport * as octicons from '../o"
},
{
"path": "lib/octicons_styled/script/.eslintrc.json",
"chars": 96,
"preview": "{\n \"env\": {\n \"node\": true,\n \"browser\": false\n },\n \"rules\": {\n \"no-console\": 0\n }\n}\n"
},
{
"path": "lib/octicons_styled/script/build.js",
"chars": 1892,
"preview": "#!/usr/bin/env node\nconst path = require('path')\nconst fs = require('fs-extra')\nconst octicons = require('../../octicons"
},
{
"path": "lib/octicons_styled/script/copy.sh",
"chars": 109,
"preview": "#!/bin/bash\n\ncp src/__generated__/index.d.ts dist/index.d.ts\ncp src/__generated__/index.js dist/index.esm.js\n"
},
{
"path": "lib/octicons_styled/src/__tests__/.eslintrc.json",
"chars": 60,
"preview": "{\n \"rules\": {\n \"github/unescaped-html-literal\": 0\n }\n}\n"
},
{
"path": "lib/octicons_styled/src/__tests__/octicon.js",
"chars": 4085,
"preview": "import '@testing-library/jest-dom'\nimport {render} from '@testing-library/react'\nimport 'jest-styled-components'\nimport "
},
{
"path": "lib/octicons_styled/src/utils.js",
"chars": 257,
"preview": "// eslint-disable-next-line import/no-namespace\nimport * as styledSystem from 'styled-system'\nimport css from '@styled-s"
},
{
"path": "lib/octicons_styled/ts-tests/index.tsx",
"chars": 336,
"preview": "import * as React from 'react'\nimport {RepoIcon} from '../src/__generated__'\n\nfunction TestOcticons() {\n return (\n <"
},
{
"path": "lib/octicons_styled/ts-tests/tsconfig.json",
"chars": 251,
"preview": "{\n \"$schema\": \"http://json.schemastore.org/tsconfig\",\n \"compileOnSave\": false,\n \"compilerOptions\": {\n \"module\": \"c"
},
{
"path": "package.json",
"chars": 1407,
"preview": "{\n \"name\": \"@primer/octicons\",\n \"version\": \"19.23.1\",\n \"publishConfig\": {\n \"registry\": \"no registry, don't publish"
},
{
"path": "prettier.config.js",
"chars": 52,
"preview": "module.exports = require('@github/prettier-config')\n"
},
{
"path": "script/build.js",
"chars": 4277,
"preview": "#!/usr/bin/env node\n/* eslint-env node */\nconst fs = require('fs-extra')\nconst path = require('path')\nconst globby = req"
},
{
"path": "script/changeset-publish",
"chars": 526,
"preview": "#!/bin/bash\n\n# This is a hack to make the changeset action think we npm published, so that it creates the github release"
},
{
"path": "script/version",
"chars": 700,
"preview": "#!/bin/bash\n\nPACKAGE_VERSION=$(jq '.version' --raw-output ./package.json)\n\necho $PACKAGE_VERSION\n\necho \"Versioning Octic"
},
{
"path": "svgo.config.js",
"chars": 452,
"preview": "/* eslint-disable import/no-commonjs,filenames/match-regex */\n\nmodule.exports = {\n multipass: true,\n plugins: [\n {\n"
},
{
"path": "tests/build.js",
"chars": 5089,
"preview": "/* eslint-disable import/no-commonjs */\nconst path = require('path')\nconst test = require('ava')\nconst execa = require('"
},
{
"path": "tests/index.js",
"chars": 1397,
"preview": "/* eslint-disable import/no-commonjs */\n/* eslint-disable i18n-text/no-en */\n\nconst test = require('ava')\nconst fs = req"
},
{
"path": "tests/snapshots/build.js.md",
"chars": 6216,
"preview": "# Snapshot report for `tests/build.js`\n\nThe actual snapshot is saved in `build.js.snap`.\n\nGenerated by [AVA](https://ava"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the primer/octicons GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 134 files (220.5 KB), approximately 68.3k tokens, and a symbol index with 57 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.