mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-11-03 21:39:22 +00:00
Ditch the abandoned ngx-bootstrap-icons by rolling our own
This commit is contained in:
9 files changed
+443
-19
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
import { BootstrapIconComponent } from './bootstrap-icon.component'
|
||||
|
||||
describe('BootstrapIconComponent', () => {
|
||||
let fixture: ComponentFixture<BootstrapIconComponent>
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [BootstrapIconComponent],
|
||||
})
|
||||
fixture = TestBed.createComponent(BootstrapIconComponent)
|
||||
})
|
||||
|
||||
it('should render the named icon as inline svg', () => {
|
||||
fixture.componentRef.setInput('name', 'arrow-down-up')
|
||||
fixture.detectChanges()
|
||||
const svg: SVGElement = fixture.nativeElement.querySelector('svg')
|
||||
expect(svg.classList).toContain('bi-arrow-down-up')
|
||||
expect(svg.getAttribute('width')).toEqual('16')
|
||||
expect(svg.getAttribute('height')).toEqual('16')
|
||||
})
|
||||
|
||||
it('should apply width and height', () => {
|
||||
fixture.componentRef.setInput('name', 'x-lg')
|
||||
fixture.componentRef.setInput('width', '1.2em')
|
||||
fixture.componentRef.setInput('height', 2)
|
||||
fixture.detectChanges()
|
||||
const svg: SVGElement = fixture.nativeElement.querySelector('svg')
|
||||
expect(svg.getAttribute('width')).toEqual('1.2em')
|
||||
expect(svg.getAttribute('height')).toEqual('2')
|
||||
})
|
||||
|
||||
it('should update when the name changes', () => {
|
||||
fixture.componentRef.setInput('name', 'x-lg')
|
||||
fixture.detectChanges()
|
||||
fixture.componentRef.setInput('name', 'sliders2-vertical')
|
||||
fixture.detectChanges()
|
||||
expect(fixture.nativeElement.querySelector('svg').classList).toContain(
|
||||
'bi-sliders2-vertical'
|
||||
)
|
||||
})
|
||||
|
||||
it('should render nothing and warn for an unregistered icon', () => {
|
||||
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
fixture.componentRef.setInput('name', 'not-an-icon')
|
||||
fixture.detectChanges()
|
||||
expect(fixture.nativeElement.innerHTML).toEqual('')
|
||||
expect(warnSpy).toHaveBeenCalledWith('Icon not found: not-an-icon')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,59 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
effect,
|
||||
ElementRef,
|
||||
inject,
|
||||
input,
|
||||
} from '@angular/core'
|
||||
import { icons } from './icons'
|
||||
|
||||
const DEFAULT_SIZE = '16'
|
||||
|
||||
/** Converts icon name e.g. `arrow-down-up` to its registry key. */
|
||||
const toKey = (name: string) =>
|
||||
name.trim().replace(/-(.)/g, (_, char: string) => char.toUpperCase())
|
||||
|
||||
/**
|
||||
* Renders an icon from the official bootstrap-icons package as inline SVG.
|
||||
* Icons must be registered in `./icons.ts`.
|
||||
*/
|
||||
@Component({
|
||||
// keep the selector of the ngx-bootstrap-icons
|
||||
// eslint-disable-next-line @angular-eslint/component-selector
|
||||
selector: 'i-bs',
|
||||
template: '',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BootstrapIconComponent {
|
||||
private readonly elementRef = inject(ElementRef<HTMLElement>)
|
||||
|
||||
readonly name = input<string>()
|
||||
readonly width = input<string | number>()
|
||||
readonly height = input<string | number>()
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
this.elementRef.nativeElement.innerHTML = this.svg()
|
||||
})
|
||||
}
|
||||
|
||||
private svg(): string {
|
||||
const name = this.name()
|
||||
if (!name) return ''
|
||||
let svg = icons[toKey(name)]
|
||||
if (!svg) {
|
||||
console.warn(`Icon not found: ${name}`)
|
||||
return ''
|
||||
}
|
||||
const width = this.width()
|
||||
const height = this.height()
|
||||
if (width) {
|
||||
svg = svg.replace(`width="${DEFAULT_SIZE}"`, `width="${width}"`)
|
||||
}
|
||||
if (height) {
|
||||
svg = svg.replace(`height="${DEFAULT_SIZE}"`, `height="${height}"`)
|
||||
}
|
||||
return svg
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
import airplane from 'bootstrap-icons/icons/airplane.svg'
|
||||
import archive from 'bootstrap-icons/icons/archive.svg'
|
||||
import arrowClockwise from 'bootstrap-icons/icons/arrow-clockwise.svg'
|
||||
import arrowCounterclockwise from 'bootstrap-icons/icons/arrow-counterclockwise.svg'
|
||||
import arrowDownUp from 'bootstrap-icons/icons/arrow-down-up.svg'
|
||||
import arrowDown from 'bootstrap-icons/icons/arrow-down.svg'
|
||||
import arrowLeft from 'bootstrap-icons/icons/arrow-left.svg'
|
||||
import arrowRepeat from 'bootstrap-icons/icons/arrow-repeat.svg'
|
||||
import arrowReturnLeft from 'bootstrap-icons/icons/arrow-return-left.svg'
|
||||
import arrowRightShort from 'bootstrap-icons/icons/arrow-right-short.svg'
|
||||
import arrowRight from 'bootstrap-icons/icons/arrow-right.svg'
|
||||
import arrowUpRight from 'bootstrap-icons/icons/arrow-up-right.svg'
|
||||
import asterisk from 'bootstrap-icons/icons/asterisk.svg'
|
||||
import bank from 'bootstrap-icons/icons/bank.svg'
|
||||
import basket from 'bootstrap-icons/icons/basket.svg'
|
||||
import bell from 'bootstrap-icons/icons/bell.svg'
|
||||
import bodyText from 'bootstrap-icons/icons/body-text.svg'
|
||||
import bookmark from 'bootstrap-icons/icons/bookmark.svg'
|
||||
import boxArrowInRight from 'bootstrap-icons/icons/box-arrow-in-right.svg'
|
||||
import boxArrowUpRight from 'bootstrap-icons/icons/box-arrow-up-right.svg'
|
||||
import boxArrowUp from 'bootstrap-icons/icons/box-arrow-up.svg'
|
||||
import boxes from 'bootstrap-icons/icons/boxes.svg'
|
||||
import braces from 'bootstrap-icons/icons/braces.svg'
|
||||
import briefcase from 'bootstrap-icons/icons/briefcase.svg'
|
||||
import building from 'bootstrap-icons/icons/building.svg'
|
||||
import calculator from 'bootstrap-icons/icons/calculator.svg'
|
||||
import calendarEventFill from 'bootstrap-icons/icons/calendar-event-fill.svg'
|
||||
import calendarEvent from 'bootstrap-icons/icons/calendar-event.svg'
|
||||
import calendar from 'bootstrap-icons/icons/calendar.svg'
|
||||
import camera from 'bootstrap-icons/icons/camera.svg'
|
||||
import cardChecklist from 'bootstrap-icons/icons/card-checklist.svg'
|
||||
import cardHeading from 'bootstrap-icons/icons/card-heading.svg'
|
||||
import caretDown from 'bootstrap-icons/icons/caret-down.svg'
|
||||
import caretUp from 'bootstrap-icons/icons/caret-up.svg'
|
||||
import cash from 'bootstrap-icons/icons/cash.svg'
|
||||
import chatLeftText from 'bootstrap-icons/icons/chat-left-text.svg'
|
||||
import chatSquareDots from 'bootstrap-icons/icons/chat-square-dots.svg'
|
||||
import checkAll from 'bootstrap-icons/icons/check-all.svg'
|
||||
import checkCircleFill from 'bootstrap-icons/icons/check-circle-fill.svg'
|
||||
import checkCircle from 'bootstrap-icons/icons/check-circle.svg'
|
||||
import checkLg from 'bootstrap-icons/icons/check-lg.svg'
|
||||
import check from 'bootstrap-icons/icons/check.svg'
|
||||
import check2All from 'bootstrap-icons/icons/check2-all.svg'
|
||||
import chevronDoubleLeft from 'bootstrap-icons/icons/chevron-double-left.svg'
|
||||
import chevronDoubleRight from 'bootstrap-icons/icons/chevron-double-right.svg'
|
||||
import chevronDown from 'bootstrap-icons/icons/chevron-down.svg'
|
||||
import chevronRight from 'bootstrap-icons/icons/chevron-right.svg'
|
||||
import chevronUp from 'bootstrap-icons/icons/chevron-up.svg'
|
||||
import circle from 'bootstrap-icons/icons/circle.svg'
|
||||
import clipboardCheckFill from 'bootstrap-icons/icons/clipboard-check-fill.svg'
|
||||
import clipboardCheck from 'bootstrap-icons/icons/clipboard-check.svg'
|
||||
import clipboardFill from 'bootstrap-icons/icons/clipboard-fill.svg'
|
||||
import clipboard from 'bootstrap-icons/icons/clipboard.svg'
|
||||
import clockHistory from 'bootstrap-icons/icons/clock-history.svg'
|
||||
import cpu from 'bootstrap-icons/icons/cpu.svg'
|
||||
import creditCard from 'bootstrap-icons/icons/credit-card.svg'
|
||||
import dashCircle from 'bootstrap-icons/icons/dash-circle.svg'
|
||||
import dash from 'bootstrap-icons/icons/dash.svg'
|
||||
import diagram3 from 'bootstrap-icons/icons/diagram-3.svg'
|
||||
import dice5 from 'bootstrap-icons/icons/dice-5.svg'
|
||||
import doorOpen from 'bootstrap-icons/icons/door-open.svg'
|
||||
import download from 'bootstrap-icons/icons/download.svg'
|
||||
import envelopeAtFill from 'bootstrap-icons/icons/envelope-at-fill.svg'
|
||||
import envelopeAt from 'bootstrap-icons/icons/envelope-at.svg'
|
||||
import envelope from 'bootstrap-icons/icons/envelope.svg'
|
||||
import exclamationCircleFill from 'bootstrap-icons/icons/exclamation-circle-fill.svg'
|
||||
import exclamationTriangleFill from 'bootstrap-icons/icons/exclamation-triangle-fill.svg'
|
||||
import exclamationTriangle from 'bootstrap-icons/icons/exclamation-triangle.svg'
|
||||
import eye from 'bootstrap-icons/icons/eye.svg'
|
||||
import fileEarmarkArrowUp from 'bootstrap-icons/icons/file-earmark-arrow-up.svg'
|
||||
import fileEarmarkCheck from 'bootstrap-icons/icons/file-earmark-check.svg'
|
||||
import fileEarmarkDiff from 'bootstrap-icons/icons/file-earmark-diff.svg'
|
||||
import fileEarmarkFill from 'bootstrap-icons/icons/file-earmark-fill.svg'
|
||||
import fileEarmarkLock from 'bootstrap-icons/icons/file-earmark-lock.svg'
|
||||
import fileEarmarkMedical from 'bootstrap-icons/icons/file-earmark-medical.svg'
|
||||
import fileEarmarkMinus from 'bootstrap-icons/icons/file-earmark-minus.svg'
|
||||
import fileEarmarkPerson from 'bootstrap-icons/icons/file-earmark-person.svg'
|
||||
import fileEarmarkPlus from 'bootstrap-icons/icons/file-earmark-plus.svg'
|
||||
import fileEarmarkRichtext from 'bootstrap-icons/icons/file-earmark-richtext.svg'
|
||||
import fileEarmarkSpreadsheet from 'bootstrap-icons/icons/file-earmark-spreadsheet.svg'
|
||||
import fileEarmark from 'bootstrap-icons/icons/file-earmark.svg'
|
||||
import fileText from 'bootstrap-icons/icons/file-text.svg'
|
||||
import files from 'bootstrap-icons/icons/files.svg'
|
||||
import filter from 'bootstrap-icons/icons/filter.svg'
|
||||
import folderFill from 'bootstrap-icons/icons/folder-fill.svg'
|
||||
import folder from 'bootstrap-icons/icons/folder.svg'
|
||||
import funnel from 'bootstrap-icons/icons/funnel.svg'
|
||||
import gear from 'bootstrap-icons/icons/gear.svg'
|
||||
import globe2 from 'bootstrap-icons/icons/globe2.svg'
|
||||
import google from 'bootstrap-icons/icons/google.svg'
|
||||
import grid from 'bootstrap-icons/icons/grid.svg'
|
||||
import gripVertical from 'bootstrap-icons/icons/grip-vertical.svg'
|
||||
import hash from 'bootstrap-icons/icons/hash.svg'
|
||||
import hddStack from 'bootstrap-icons/icons/hdd-stack.svg'
|
||||
import heart from 'bootstrap-icons/icons/heart.svg'
|
||||
import house from 'bootstrap-icons/icons/house.svg'
|
||||
import inbox from 'bootstrap-icons/icons/inbox.svg'
|
||||
import infoCircle from 'bootstrap-icons/icons/info-circle.svg'
|
||||
import journalBookmarkFill from 'bootstrap-icons/icons/journal-bookmark-fill.svg'
|
||||
import journals from 'bootstrap-icons/icons/journals.svg'
|
||||
import lightbulb from 'bootstrap-icons/icons/lightbulb.svg'
|
||||
import link from 'bootstrap-icons/icons/link.svg'
|
||||
import listNested from 'bootstrap-icons/icons/list-nested.svg'
|
||||
import listTask from 'bootstrap-icons/icons/list-task.svg'
|
||||
import listUl from 'bootstrap-icons/icons/list-ul.svg'
|
||||
import list from 'bootstrap-icons/icons/list.svg'
|
||||
import microsoft from 'bootstrap-icons/icons/microsoft.svg'
|
||||
import newspaper from 'bootstrap-icons/icons/newspaper.svg'
|
||||
import nodePlus from 'bootstrap-icons/icons/node-plus.svg'
|
||||
import paperclip from 'bootstrap-icons/icons/paperclip.svg'
|
||||
import pencil from 'bootstrap-icons/icons/pencil.svg'
|
||||
import peopleFill from 'bootstrap-icons/icons/people-fill.svg'
|
||||
import people from 'bootstrap-icons/icons/people.svg'
|
||||
import personCircle from 'bootstrap-icons/icons/person-circle.svg'
|
||||
import personFillLock from 'bootstrap-icons/icons/person-fill-lock.svg'
|
||||
import personFill from 'bootstrap-icons/icons/person-fill.svg'
|
||||
import personLock from 'bootstrap-icons/icons/person-lock.svg'
|
||||
import personSquare from 'bootstrap-icons/icons/person-square.svg'
|
||||
import person from 'bootstrap-icons/icons/person.svg'
|
||||
import playFill from 'bootstrap-icons/icons/play-fill.svg'
|
||||
import plusCircle from 'bootstrap-icons/icons/plus-circle.svg'
|
||||
import plus from 'bootstrap-icons/icons/plus.svg'
|
||||
import printer from 'bootstrap-icons/icons/printer.svg'
|
||||
import questionCircle from 'bootstrap-icons/icons/question-circle.svg'
|
||||
import receipt from 'bootstrap-icons/icons/receipt.svg'
|
||||
import safe from 'bootstrap-icons/icons/safe.svg'
|
||||
import scissors from 'bootstrap-icons/icons/scissors.svg'
|
||||
import search from 'bootstrap-icons/icons/search.svg'
|
||||
import send from 'bootstrap-icons/icons/send.svg'
|
||||
import shop from 'bootstrap-icons/icons/shop.svg'
|
||||
import slashCircle from 'bootstrap-icons/icons/slash-circle.svg'
|
||||
import sliders2Vertical from 'bootstrap-icons/icons/sliders2-vertical.svg'
|
||||
import sortAlphaDown from 'bootstrap-icons/icons/sort-alpha-down.svg'
|
||||
import sortAlphaUpAlt from 'bootstrap-icons/icons/sort-alpha-up-alt.svg'
|
||||
import stack from 'bootstrap-icons/icons/stack.svg'
|
||||
import stars from 'bootstrap-icons/icons/stars.svg'
|
||||
import tagFill from 'bootstrap-icons/icons/tag-fill.svg'
|
||||
import tag from 'bootstrap-icons/icons/tag.svg'
|
||||
import tags from 'bootstrap-icons/icons/tags.svg'
|
||||
import telephone from 'bootstrap-icons/icons/telephone.svg'
|
||||
import textIndentLeft from 'bootstrap-icons/icons/text-indent-left.svg'
|
||||
import textLeft from 'bootstrap-icons/icons/text-left.svg'
|
||||
import threeDotsVertical from 'bootstrap-icons/icons/three-dots-vertical.svg'
|
||||
import threeDots from 'bootstrap-icons/icons/three-dots.svg'
|
||||
import trash from 'bootstrap-icons/icons/trash.svg'
|
||||
import truck from 'bootstrap-icons/icons/truck.svg'
|
||||
import uiRadios from 'bootstrap-icons/icons/ui-radios.svg'
|
||||
import unlock from 'bootstrap-icons/icons/unlock.svg'
|
||||
import upcScan from 'bootstrap-icons/icons/upc-scan.svg'
|
||||
import wallet2 from 'bootstrap-icons/icons/wallet2.svg'
|
||||
import windowStack from 'bootstrap-icons/icons/window-stack.svg'
|
||||
import xCircle from 'bootstrap-icons/icons/x-circle.svg'
|
||||
import xLg from 'bootstrap-icons/icons/x-lg.svg'
|
||||
import x from 'bootstrap-icons/icons/x.svg'
|
||||
|
||||
/**
|
||||
* `<i-bs>`. Only icons registered here are bundled but can add
|
||||
* new ones (any icon from the bootstrap-icons package) as needed.
|
||||
*/
|
||||
export const icons: Record<string, string> = {
|
||||
airplane,
|
||||
archive,
|
||||
arrowClockwise,
|
||||
arrowCounterclockwise,
|
||||
arrowDown,
|
||||
arrowDownUp,
|
||||
arrowLeft,
|
||||
arrowRepeat,
|
||||
arrowReturnLeft,
|
||||
arrowRight,
|
||||
arrowRightShort,
|
||||
arrowUpRight,
|
||||
asterisk,
|
||||
bank,
|
||||
basket,
|
||||
bell,
|
||||
braces,
|
||||
bodyText,
|
||||
bookmark,
|
||||
boxArrowInRight,
|
||||
boxArrowUp,
|
||||
boxArrowUpRight,
|
||||
boxes,
|
||||
briefcase,
|
||||
building,
|
||||
calculator,
|
||||
calendar,
|
||||
calendarEvent,
|
||||
calendarEventFill,
|
||||
camera,
|
||||
cardChecklist,
|
||||
cardHeading,
|
||||
caretDown,
|
||||
caretUp,
|
||||
chatLeftText,
|
||||
chatSquareDots,
|
||||
check,
|
||||
check2All,
|
||||
checkAll,
|
||||
checkCircle,
|
||||
checkCircleFill,
|
||||
checkLg,
|
||||
chevronDoubleLeft,
|
||||
chevronDoubleRight,
|
||||
chevronDown,
|
||||
chevronRight,
|
||||
chevronUp,
|
||||
circle,
|
||||
clipboard,
|
||||
clipboardCheck,
|
||||
clipboardCheckFill,
|
||||
clipboardFill,
|
||||
clockHistory,
|
||||
cpu,
|
||||
cash,
|
||||
creditCard,
|
||||
dash,
|
||||
dashCircle,
|
||||
diagram3,
|
||||
dice5,
|
||||
doorOpen,
|
||||
download,
|
||||
envelope,
|
||||
envelopeAt,
|
||||
envelopeAtFill,
|
||||
exclamationCircleFill,
|
||||
exclamationTriangle,
|
||||
exclamationTriangleFill,
|
||||
eye,
|
||||
fileEarmark,
|
||||
fileEarmarkArrowUp,
|
||||
fileEarmarkCheck,
|
||||
fileEarmarkDiff,
|
||||
fileEarmarkFill,
|
||||
fileEarmarkLock,
|
||||
fileEarmarkMedical,
|
||||
fileEarmarkMinus,
|
||||
fileEarmarkPerson,
|
||||
fileEarmarkPlus,
|
||||
fileEarmarkRichtext,
|
||||
fileEarmarkSpreadsheet,
|
||||
files,
|
||||
fileText,
|
||||
filter,
|
||||
folder,
|
||||
folderFill,
|
||||
funnel,
|
||||
gear,
|
||||
globe2,
|
||||
google,
|
||||
grid,
|
||||
gripVertical,
|
||||
hash,
|
||||
hddStack,
|
||||
heart,
|
||||
house,
|
||||
inbox,
|
||||
infoCircle,
|
||||
journalBookmarkFill,
|
||||
journals,
|
||||
lightbulb,
|
||||
link,
|
||||
list,
|
||||
listNested,
|
||||
listTask,
|
||||
listUl,
|
||||
microsoft,
|
||||
newspaper,
|
||||
nodePlus,
|
||||
pencil,
|
||||
paperclip,
|
||||
people,
|
||||
peopleFill,
|
||||
person,
|
||||
personCircle,
|
||||
personFill,
|
||||
personFillLock,
|
||||
personLock,
|
||||
personSquare,
|
||||
playFill,
|
||||
plus,
|
||||
plusCircle,
|
||||
printer,
|
||||
questionCircle,
|
||||
receipt,
|
||||
safe,
|
||||
scissors,
|
||||
search,
|
||||
send,
|
||||
slashCircle,
|
||||
shop,
|
||||
sliders2Vertical,
|
||||
sortAlphaDown,
|
||||
sortAlphaUpAlt,
|
||||
stack,
|
||||
stars,
|
||||
tagFill,
|
||||
tag,
|
||||
tags,
|
||||
textIndentLeft,
|
||||
textLeft,
|
||||
telephone,
|
||||
threeDots,
|
||||
threeDotsVertical,
|
||||
trash,
|
||||
truck,
|
||||
uiRadios,
|
||||
unlock,
|
||||
upcScan,
|
||||
wallet2,
|
||||
windowStack,
|
||||
x,
|
||||
xCircle,
|
||||
xLg,
|
||||
}
|
||||
Reference in new issue
Block a user