| | import { TokenizationError } from 'liquidjs' |
| | import octicons from '@primer/octicons' |
| |
|
| | |
| | interface LiquidTag { |
| | icon: string |
| | options: Record<string, string> |
| | parse(tagToken: any): void |
| | render(): Promise<string> |
| | } |
| |
|
| | interface OcticonsMatch { |
| | groups: { |
| | icon: string |
| | options?: string |
| | } |
| | } |
| |
|
| | const OptionsSyntax = /([a-zA-Z-]+)="([\w\s-]+)"*/g |
| | const Syntax = new RegExp(`"(?<icon>[a-zA-Z-]+)"(?<options>(?:\\s${OptionsSyntax.source})*)`) |
| | const SyntaxHelp = 'Syntax Error in tag \'octicon\' - Valid syntax: octicon "<name>" <key="value">' |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | const Octicon: LiquidTag = { |
| | icon: '', |
| | options: {}, |
| |
|
| | parse(tagToken: any): void { |
| | const match: OcticonsMatch | null = tagToken.args.match(Syntax) |
| | if (!match) { |
| | throw new TokenizationError(SyntaxHelp, tagToken) |
| | } |
| |
|
| | |
| | this.icon = match.groups.icon |
| | |
| | |
| | if (this.icon === 'trashcan') this.icon = 'trash' |
| | |
| | if (this.icon === 'duplicate') this.icon = 'copy' |
| | if (this.icon === 'clippy') this.icon = 'paste' |
| |
|
| | this.options = {} |
| |
|
| | |
| | if (match.groups.options) { |
| | let optionsMatch: RegExpExecArray | null |
| |
|
| | |
| | while ((optionsMatch = OptionsSyntax.exec(match.groups.options))) { |
| | |
| | const [, key, value] = optionsMatch |
| | this.options[key] = value |
| |
|
| | |
| | if (key === 'label') this.options['aria-label'] = value |
| | } |
| | } |
| | }, |
| |
|
| | async render(): Promise<string> { |
| | |
| | if (!Object.prototype.hasOwnProperty.call(octicons, this.icon)) { |
| | throw new Error(`Octicon ${this.icon} does not exist`) |
| | } |
| |
|
| | |
| | |
| | if (!this.options['aria-label']) { |
| | const defaultLabel = `${this.icon.toLowerCase().replace(/[^a-z0-9]+/gi, ' ')} icon` |
| | this.options['aria-label'] = defaultLabel |
| | } |
| |
|
| | const result: string = octicons[this.icon].toSVG(this.options) |
| | return result |
| | }, |
| | } |
| |
|
| | export default Octicon |
| |
|