@charcoal-ui/icons 1.0.1-alpha.3 → 1.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/BaseLoader.d.ts +22 -0
- package/dist/BaseLoader.d.ts.map +1 -0
- package/dist/PixivIcon.d.ts +5 -5
- package/dist/PixivIcon.d.ts.map +1 -1
- package/dist/filenames.d.ts +1 -1
- package/dist/filenames.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/loaders.d.ts +21 -9
- package/dist/loaders.d.ts.map +1 -1
- package/dist/ssr.d.ts +0 -9
- package/dist/ssr.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/BaseLoader.ts +64 -0
- package/src/PixivIcon.ts +38 -21
- package/src/filenames.ts +2 -7
- package/src/index.ts +1 -1
- package/src/loaders.ts +64 -37
- package/src/ssr.ts +5 -8
- package/svg/16/Artwork.svg +1 -0
- package/svg/16/Comment.svg +1 -0
- package/svg/16/ImageResponse.svg +1 -0
- package/svg/16/Info.svg +1 -1
- package/svg/16/Like.svg +1 -0
- package/svg/16/Ranking.svg +1 -0
- package/svg/16/Smile.svg +1 -0
- package/svg/16/View.svg +1 -0
- package/svg/24/Discovery.svg +1 -2
- package/svg/24/Emoji.svg +1 -1
- package/svg/24/LikeOff.svg +1 -1
- package/svg/24/NoImage.svg +1 -0
- package/svg/24/ReadHorizontalLeft.svg +1 -0
- package/svg/24/ReadHorizontalRight.svg +1 -0
- package/svg/24/ReadVertical.svg +1 -0
- package/svg/Inline/View.svg +1 -1
- package/svg/Inline/ViewOutline.svg +1 -0
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.js","sources":["../src/loaders.ts","../src/ssr.ts","../src/PixivIcon.ts","../src/filenames.ts","../src/index.ts"],"sourcesContent":["const cache = new Map<string, string>()\n\ninterface SvgModule {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __esModule: true\n default: string\n}\n\nexport class PixivIconLoadError extends Error {\n constructor(message?: string) {\n super(message)\n Object.setPrototypeOf(this, new.target)\n }\n}\n\nfunction createLoader(getPath: (attributeName: string) => Promise<string>) {\n return async function getSvgString(attributeName: string): Promise<string> {\n if (cache.has(attributeName)) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return cache.get(attributeName)!\n }\n\n const rawSvg = await getPath(attributeName)\n .then((path) => fetch(path))\n .then((response) => {\n if (!response.ok) {\n throw new PixivIconLoadError(\n `Failed to fetch <pixiv-icon name=\"${attributeName}\">`\n )\n }\n\n return response.text()\n })\n\n cache.set(attributeName, rawSvg)\n\n return rawSvg\n }\n}\n\nexport type Loader = ReturnType<typeof createLoader>\n\nconst loadFromRawUrl: Loader = createLoader((attributeName) =>\n Promise.resolve(attributeName)\n)\n\nconst loadFromFile: Loader = createLoader(async (attributeName) => {\n const [size, name] = attributeName.split('/')\n\n const { default: filename } = (await import(\n `../svg/${encodeURIComponent(size)}/${encodeURIComponent(name)}.svg`\n )) as SvgModule\n\n return filename\n})\n\nexport const loaders = { loadFromRawUrl, loadFromFile }\n","export const __SERVER__ = typeof window === 'undefined'\n\nconst CAN_USE_DOM = typeof HTMLElement !== 'undefined'\n\n/**\n * NOTICE: SSR 環境では `extends HTMLElement` できない\n *\n * @see https://github.com/vuejs/core/blob/9c304bfe7942a20264235865b4bb5f6e53fdee0d/packages/runtime-dom/src/apiCustomElement.ts#L143-L145\n */\nexport const BaseElement = (\n !__SERVER__ && CAN_USE_DOM ? HTMLElement : class {}\n) as typeof HTMLElement\n","import type React from 'react'\nimport warning from 'warning'\nimport { KnownIconFile } from './filenames'\nimport { loaders as defaultLoaders, Loader } from './loaders'\nimport { BaseElement, __SERVER__ } from './ssr'\nimport { sanitize } from 'dompurify'\n\nconst { loadFromFile, loadFromRawUrl } = defaultLoaders\n\nconst attributes = ['name', 'scale', 'unsafe-non-guideline-scale'] as const\n\nconst ROOT_MARGIN = 50\n\nexport interface KnownIconType extends Record<KnownIconFile, unknown> {}\n\nexport interface Props\n extends Omit<\n React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>,\n 'className' | 'css'\n > {\n name: keyof KnownIconType\n scale?: 1 | 2 | 3 | '1' | '2' | '3'\n 'unsafe-non-guideline-scale'?: number | string\n\n // CustomElements は className が使えない。class と書く必要がある\n // https://ja.reactjs.org/docs/web-components.html#using-web-components-in-react\n class?: string\n}\n\nconst loaders = new Map<string, Loader>()\n\ntype ExtendedIconFile = Exclude<keyof KnownIconType, KnownIconFile>\ntype Extended = [ExtendedIconFile] extends [never] // NOTE: ExtendedIconFileがneverならKnownIconTypeは拡張されていない\n ? false\n : true\n\nexport class PixivIcon extends BaseElement {\n static readonly tagName = 'pixiv-icon'\n\n static extend(\n map: Extended extends true\n ? Record<ExtendedIconFile, string>\n : Record<string, string>\n ) {\n warning(!__SERVER__, 'Using `PixivIcon.extend()` on server has no effect')\n if (__SERVER__) {\n return\n }\n\n Object.entries(map).forEach(([name, url]) => {\n if (!name.includes('/')) {\n throw new TypeError(\n `${name} is not a valid icon name. \"name\" must be named like [size]/[Name].`\n )\n }\n\n loaders.set(name, function customLoader() {\n return loadFromRawUrl(url)\n })\n })\n }\n\n static get observedAttributes() {\n return attributes\n }\n\n private svgContent?: string\n private observer?: IntersectionObserver\n\n get props() {\n const partial = Object.fromEntries(\n attributes.map((attribute) => [attribute, this.getAttribute(attribute)])\n ) as Record<typeof attributes[number], string | null>\n\n const name = partial.name\n\n if (name === null) {\n throw new TypeError('property \"name\" is required.')\n }\n\n if (!name.includes('/')) {\n throw new TypeError(\n `${name} is not a valid icon name. \"name\" must be named like [size]/[Name].`\n )\n }\n\n return {\n ...partial,\n name,\n }\n }\n\n get forceResizedSize() {\n if (this.props['unsafe-non-guideline-scale'] === null) {\n return null\n }\n\n const [size] = this.props.name.split('/')\n const scale = Number(this.props['unsafe-non-guideline-scale'])\n\n switch (size) {\n case 'Inline': {\n return 16 * scale\n }\n\n default: {\n return Number(size) * scale\n }\n }\n }\n\n get scaledSize() {\n const [size] = this.props.name.split('/')\n\n const scale = Number(this.props.scale ?? '1')\n\n switch (size) {\n case 'Inline': {\n switch (scale) {\n case 2: {\n return 32\n }\n\n default: {\n return 16\n }\n }\n }\n\n case '24': {\n return Number(size) * scale\n }\n\n default: {\n return Number(size)\n }\n }\n }\n\n constructor() {\n super()\n this.attachShadow({ mode: 'open' })\n }\n\n connectedCallback() {\n this.render()\n this.update()\n }\n\n disconnectedCallback() {\n this.observer?.disconnect()\n this.observer = undefined\n }\n\n attributeChangedCallback() {\n this.update()\n }\n\n render() {\n const size = this.forceResizedSize ?? this.scaledSize\n\n const style = sanitize(\n `<style>\n :host {\n display: inline-flex;\n --size: ${size}px;\n }\n\n svg {\n width: var(--size);\n height: var(--size);\n }\n</style>`,\n { ALLOWED_TAGS: ['style'], FORCE_BODY: true }\n )\n\n const svg = sanitize(\n this.svgContent !== undefined\n ? this.svgContent\n : `<svg viewBox=\"0 0 ${size} ${size}\"></svg>`,\n { USE_PROFILES: { svg: true, svgFilters: true } }\n )\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.shadowRoot!.innerHTML = style + svg\n }\n\n private update() {\n void this.waitUntilVisible().then(async () => {\n const { name } = this.props\n const loader = loaders.get(name) ?? loadFromFile\n\n this.svgContent = await loader(name)\n this.render()\n })\n }\n\n private waitUntilVisible() {\n return new Promise<void>((resolve) => {\n this.observer = new IntersectionObserver(\n ([first]) => {\n if (first.isIntersecting) {\n this.observer?.disconnect()\n this.observer = undefined\n resolve()\n }\n },\n { rootMargin: `${ROOT_MARGIN}px` }\n )\n\n this.observer.observe(this)\n })\n }\n}\n","/** This file is auto generated. DO NOT EDIT BY HAND. */\n\n/* eslint-disable */\n\n// prettier-ignore\nexport const KNOWN_ICON_FILES = [\"32/ShareIos\",\"32/Dot\",\"32/Message\",\"32/Gift\",\"32/Close\",\"32/Prev\",\"32/Next\",\"32/PullDown\",\"32/PullUp\",\"32/Expand\",\"32/Collapse\",\"32/Edit\",\"32/ShareAndroid\",\"32/BookmarkOff\",\"32/BookmarkOn\",\"32/NovelViewerSettings\",\"32/CommentOff\",\"32/CommentOn\",\"32/Home\",\"32/Index\",\"32/Serif\",\"32/Camera\",\"32/Delete\",\"32/Pan\",\"32/RollVertical\",\"32/RollHorizontal\",\"32/ZoomIn\",\"32/Upload\",\"32/Shopping\",\"32/User\",\"32/HorizontalWriting\",\"32/Notification\",\"32/SansSerif\",\"32/VerticalWriting\",\"32/NotificationOff\",\"24/Expand\",\"24/Collapse\",\"24/Close\",\"24/Pencil\",\"24/PencilDraw\",\"24/PencilText\",\"24/Reorder\",\"24/Add\",\"24/Subtract\",\"24/Star\",\"24/Check\",\"24/Send\",\"24/LockLock\",\"24/LockUnlock\",\"24/Up\",\"24/Down\",\"24/ReloadLoop\",\"24/Reload\",\"24/Options\",\"24/CommentOutline\",\"24/Trash\",\"24/TrashAlt\",\"24/ShareIos\",\"24/ViewGrid3Columns\",\"24/ViewGrid2Columns\",\"24/ViewList\",\"24/Upload\",\"24/UploadAlt\",\"24/DownloadAlt\",\"24/ArrowUp\",\"24/LikeOff\",\"24/LikeOn\",\"24/ArrowDown\",\"24/OptionsAlt\",\"24/PencilLive\",\"24/OpenInNew\",\"24/Settings\",\"24/Roll\",\"24/Calendar\",\"24/Save\",\"24/Logout\",\"24/CommentFill\",\"24/ShareAndroid\",\"16/More\",\"16/Back\",\"16/Search\",\"16/Add\",\"16/Check\",\"16/Menu\",\"16/Dot\",\"16/Book\",\"16/ArrowDown\",\"16/Speaker\",\"16/Remove\",\"16/BookmarkOn\",\"16/BookmarkOff\",\"16/Filter\",\"16/Error\",\"16/Info\",\"16/Pencil\",\"Inline/LikeOff\",\"Inline/View\",\"Inline/BookmarkOff\",\"Inline/BookmarkOn\",\"Inline/Breadcrumbs\",\"Inline/More\",\"Inline/ImageResponse\",\"Inline/Lock\",\"Inline/External\",\"Inline/Location\",\"Inline/View\",\"Inline/Like\",\"Inline/Smile\",\"Inline/SmileOn\",\"Inline/Check\",\"Inline/List\",\"Inline/ContextMenu\",\"Inline/Add\",\"Inline/Remove\",\"Inline/Images\",\"Inline/Nextworks\",\"Inline/Filter\",\"Inline/Users\",\"24/Next\",\"24/PullDown\",\"24/PullUp\",\"24/Prev\",\"24/Dot\",\"24/Notification\",\"24/NotificationOff\",\"24/Search\",\"24/Menu\",\"24/Index\",\"24/Services\",\"24/Error\",\"24/Home\",\"24/Warning\",\"24/Info\",\"24/QuestionOutline\",\"24/ChatBot\",\"24/ErrorOctagon\",\"24/Question\",\"24/Alart\",\"24/DotAlt\",\"24/ImageHidden\",\"24/AddRubi\",\"24/ImageReplace\",\"24/Text\",\"24/AddText\",\"24/FormatAlignRight\",\"24/FormatAlignLeft\",\"24/FormatAlignCenter\",\"24/AddImage\",\"24/ImgContain\",\"24/ImgCover\",\"24/BringForward\",\"24/BringBackward\",\"24/RotateRight\",\"24/Palette\",\"24/Duplicate\",\"24/FormatLineSpacing\",\"24/FormatLetterSpacing\",\"24/Rotate90DegreesCc\",\"24/Rotate90DegreesC\",\"24/FormatFontSize\",\"24/FormatFontFamily\",\"24/FormatColorFill\",\"24/FormatColorFillNoColor\",\"24/ChromaticAberration\",\"24/Move1\",\"24/Play\",\"24/Pause\",\"24/Microphone\",\"24/PauseAlt\",\"24/CameraVideo\",\"24/Camera\",\"24/Fov\",\"24/Sun\",\"24/Shutter\",\"24/Contrast\",\"24/FrameEffect\",\"24/Hue\",\"24/Saturation\",\"24/Glow\",\"24/Binet\",\"24/Overlay\",\"24/Flare\",\"24/Dust\",\"24/Temperature\",\"24/Filter\",\"24/Usagi\",\"24/Set\",\"24/Gift\",\"24/MobilePhone\",\"24/Users\",\"24/AddPeople\",\"24/Person\",\"24/Emoji\",\"24/Shopping\",\"24/UsagiAlt\",\"24/Fashion\",\"24/FaceEdit\",\"24/DeviceRotation\",\"24/Ar\",\"24/FrameSize\",\"24/Body\",\"24/BodyEdit\",\"24/HairEdit\",\"24/ItemRemove\",\"24/AddModel\",\"24/ChangeCharactor\",\"24/Pose\",\"24/Show\",\"24/ShowOutline\",\"24/Hide\",\"24/Idea\",\"24/Book\",\"24/Message\",\"24/Images\",\"24/Image\",\"24/Video\",\"24/Hashtag\",\"24/ImageAlt\",\"24/Discovery\",\"24/Description\",\"24/File\",\"24/Archive\",\"24/Invoice\",\"24/Announcement\",\"24/Link\",\"24/Manga\",\"24/Novels\",\"24/Contest\",\"24/LatestWorks\",\"24/Ranking\",\"24/Feed\",\"24/Groups\",\"24/Events\",\"24/Projects\",\"24/Codes\",\"24/Invalid\",\"32/LikeOff\",\"32/LikeOn\",\"32/LikeOnPrivate\",\"24/ImageHidden\",\"Inline/Folder\",\"Inline/Pencil\",\"Inline/Comment\"] as const;\n\nexport type KnownIconFile = typeof KNOWN_ICON_FILES[number]\n\n/* eslint-enable */\n","import { PixivIcon, Props } from './PixivIcon'\nimport { __SERVER__ } from './ssr'\nexport { PixivIcon, type KnownIconType, type Props } from './PixivIcon'\nexport { KNOWN_ICON_FILES } from './filenames'\nexport { PixivIconLoadError } from './loaders'\n\ndeclare global {\n interface Window {\n PixivIcon: typeof PixivIcon\n }\n\n // eslint-disable-next-line @typescript-eslint/no-namespace\n export namespace JSX {\n interface IntrinsicElements {\n 'pixiv-icon': Props\n }\n }\n}\n\nif (!__SERVER__) {\n // TODO: HMR対応\n if (!window.customElements.get(PixivIcon.tagName)) {\n window.PixivIcon = PixivIcon\n window.customElements.define(PixivIcon.tagName, PixivIcon)\n }\n}\n"],"names":["cache","Map","PixivIconLoadError","message","_this","Object","setPrototypeOf","Error","createLoader","getPath","attributeName","has","get","then","path","fetch","response","ok","text","rawSvg","set","loaders","loadFromRawUrl","Promise","resolve","loadFromFile","split","name","import","encodeURIComponent","__SERVER__","window","CAN_USE_DOM","HTMLElement","BaseElement","defaultLoaders","attributes","PixivIcon","svgContent","observer","attachShadow","mode","extend","map","warning","entries","forEach","url","includes","TypeError","connectedCallback","this","render","update","disconnectedCallback","disconnect","undefined","attributeChangedCallback","size","forceResizedSize","scaledSize","style","sanitize","ALLOWED_TAGS","FORCE_BODY","svg","USE_PROFILES","svgFilters","shadowRoot","innerHTML","waitUntilVisible","_this2","props","loader","_this3","IntersectionObserver","isIntersecting","rootMargin","ROOT_MARGIN","observe","partial","fromEntries","attribute","_this4","getAttribute","scale","Number","tagName","KNOWN_ICON_FILES","customElements","define"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.module.js","sources":["../src/BaseLoader.ts","../src/loaders.ts","../src/ssr.ts","../src/PixivIcon.ts","../src/filenames.ts","../src/index.ts"],"sourcesContent":["export class PixivIconLoadError extends Error {\n constructor(message?: string) {\n super(message)\n Object.setPrototypeOf(this, new.target)\n }\n}\n\n/**\n * SVG アイコンを取得するクラス\n *\n * 一度リクエストされたアイコンは(リクエスト中のも含め)何度もリクエストしないようになっている\n */\nexport class BaseLoader {\n private _name: string\n private _getSource: () => Promise<string>\n\n private _promise: Promise<string> | undefined = undefined\n private _resultSvg: string | undefined = undefined\n\n constructor(name: string, getSource: () => Promise<string>) {\n this._name = name\n this._getSource = getSource\n }\n\n isLoading() {\n return this._promise !== undefined\n }\n\n async fetch() {\n if (this._resultSvg !== undefined) {\n return this._resultSvg\n }\n\n if (this._promise) {\n return this._promise\n }\n\n this._promise = this._getSource()\n .then((src) => fetch(src))\n .then((response) => {\n if (!response.ok) {\n throw new PixivIconLoadError(\n `Failed to fetch <pixiv-icon name=\"${this._name}\">`\n )\n }\n\n return response.text()\n })\n .then((svg) => {\n this._resultSvg = svg\n return this._resultSvg\n })\n .finally(() => {\n this._promise = undefined\n })\n\n return this._promise\n }\n}\n\nexport interface Loadable {\n fetch(): Promise<string>\n isLoading(): boolean\n}\n","import { Loadable, BaseLoader } from './BaseLoader'\n\n/**\n * オブジェクトプール。Loader のインスタンスは作り次第ここに入れる\n *\n * 同じアイコンへの複数回のリクエストが起きないためには、Loader がこの中でユニークでないと行けない\n */\nconst pool = new Map<string, Loadable>()\n\n/**\n * アイコンを特定の URL から取得する Loader\n */\nexport class UrlLoader implements Loadable {\n private fetcher: BaseLoader\n\n static find(name: string) {\n return pool.get(name)\n }\n\n static register(name: string, url: string) {\n const loader = new UrlLoader(name, url)\n\n pool.set(name, loader)\n }\n\n private constructor(name: string, url: string) {\n this.fetcher = new BaseLoader(name, () => Promise.resolve(url))\n }\n\n fetch(): Promise<string> {\n return this.fetcher.fetch()\n }\n\n isLoading() {\n return this.fetcher.isLoading()\n }\n}\n\n/**\n * アイコン名から import すべきファイル名( このパッケージ内にある )を解決してくる Loader\n */\nexport class FileLoader implements Loadable {\n private fetcher: BaseLoader\n\n static findOrRegister(name: string) {\n const registeredLoader = pool.get(name)\n if (registeredLoader) {\n return registeredLoader\n }\n\n const newLoader = new FileLoader(name)\n pool.set(name, newLoader)\n\n return newLoader\n }\n\n private constructor(name: string) {\n this.fetcher = new BaseLoader(name, () => getSourceFromName(name))\n }\n\n fetch(): Promise<string> {\n return this.fetcher.fetch()\n }\n\n isLoading() {\n return this.fetcher.isLoading()\n }\n}\n\ninterface SvgModule {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n __esModule: true\n default: string\n}\n\nasync function getSourceFromName(fullName: string) {\n const [size, name] = fullName.split('/')\n\n const { default: filename } = (await import(\n `../svg/${encodeURIComponent(size)}/${encodeURIComponent(name)}.svg`\n )) as SvgModule\n\n return filename\n}\n","export const __SERVER__ = typeof window === 'undefined'\n\nconst CAN_USE_DOM = typeof HTMLElement !== 'undefined'\n\n// Workaround: `extends HTMLELement` の形式でないとbabelのトランスパイルがおかしくなる\nif (__SERVER__ || !CAN_USE_DOM) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any\n globalThis.HTMLElement = class {} as any\n}\n","import type React from 'react'\nimport warning from 'warning'\nimport { KnownIconFile } from './filenames'\nimport { FileLoader, UrlLoader } from './loaders'\nimport { __SERVER__ } from './ssr'\nimport { sanitize } from 'dompurify'\n\nconst attributes = ['name', 'scale', 'unsafe-non-guideline-scale'] as const\n\nconst ROOT_MARGIN = 50\n\nexport interface KnownIconType extends Record<KnownIconFile, unknown> {}\n\nexport interface Props\n extends Omit<\n React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>,\n 'className' | 'css'\n > {\n name: keyof KnownIconType\n scale?: 1 | 2 | 3 | '1' | '2' | '3'\n 'unsafe-non-guideline-scale'?: number | string\n\n // CustomElements は className が使えない。class と書く必要がある\n // https://ja.reactjs.org/docs/web-components.html#using-web-components-in-react\n class?: string\n}\n\ntype ExtendedIconFile = Exclude<keyof KnownIconType, KnownIconFile>\ntype Extended = [ExtendedIconFile] extends [never] // NOTE: ExtendedIconFileがneverならKnownIconTypeは拡張されていない\n ? false\n : true\n\nexport class PixivIcon extends HTMLElement {\n static readonly tagName = 'pixiv-icon'\n\n static extend(\n map: Extended extends true\n ? Record<ExtendedIconFile, string>\n : Record<string, string>\n ) {\n warning(!__SERVER__, 'Using `PixivIcon.extend()` on server has no effect')\n if (__SERVER__) {\n return\n }\n\n Object.entries(map).forEach(([name, url]) => {\n if (!name.includes('/')) {\n throw new TypeError(\n `${name} is not a valid icon name. \"name\" must be named like [size]/[Name].`\n )\n }\n\n UrlLoader.register(name, url)\n })\n }\n\n static get observedAttributes() {\n return attributes\n }\n\n private svgContent?: string\n private observer?: IntersectionObserver\n private isVisible = false\n\n get props() {\n const partial = Object.fromEntries(\n attributes.map((attribute) => [attribute, this.getAttribute(attribute)])\n ) as Record<typeof attributes[number], string | null>\n\n const name = partial.name\n\n if (name === null) {\n throw new TypeError('property \"name\" is required.')\n }\n\n if (!name.includes('/')) {\n throw new TypeError(\n `${name} is not a valid icon name. \"name\" must be named like [size]/[Name].`\n )\n }\n\n return {\n ...partial,\n name,\n }\n }\n\n get forceResizedSize() {\n if (this.props['unsafe-non-guideline-scale'] === null) {\n return null\n }\n\n const [size] = this.props.name.split('/')\n const scale = Number(this.props['unsafe-non-guideline-scale'])\n\n switch (size) {\n case 'Inline': {\n return 16 * scale\n }\n\n default: {\n return Number(size) * scale\n }\n }\n }\n\n get scaledSize() {\n const [size] = this.props.name.split('/')\n\n const scale = Number(this.props.scale ?? '1')\n\n switch (size) {\n case 'Inline': {\n switch (scale) {\n case 2: {\n return 32\n }\n\n default: {\n return 16\n }\n }\n }\n\n case '24': {\n return Number(size) * scale\n }\n\n default: {\n return Number(size)\n }\n }\n }\n\n constructor() {\n super()\n this.attachShadow({ mode: 'open' })\n }\n\n async connectedCallback() {\n this.render()\n await this.waitUntilVisible()\n this.isVisible = true\n await this.loadSvg(this.props.name)\n }\n\n disconnectedCallback() {\n this.observer?.disconnect()\n this.observer = undefined\n this.isVisible = false\n }\n\n attributeChangedCallback(\n attr: string,\n _oldValue: string | null,\n newValue: string\n ) {\n // 非表示の場合はロードしない\n if (!this.isVisible) {\n return\n }\n\n // name が変更された場合必ず再読み込みを試みる\n if (attr === 'name') {\n void this.loadSvg(newValue)\n return\n }\n\n // SVG が読み込み済み && scale などの変更だけならそこだけ反映すればいい\n if (this.svgContent !== undefined) {\n this.render()\n return\n }\n\n // まだ SVG が読み込めてないなら load\n void this.loadSvg(this.props.name)\n }\n\n render() {\n const size = this.forceResizedSize ?? this.scaledSize\n\n const style = sanitize(\n `<style>\n :host {\n display: inline-flex;\n --size: ${size}px;\n }\n\n svg {\n width: var(--size);\n height: var(--size);\n }\n</style>`,\n { ALLOWED_TAGS: ['style'], FORCE_BODY: true }\n )\n\n const svg = sanitize(\n this.svgContent !== undefined\n ? this.svgContent\n : `<svg viewBox=\"0 0 ${size} ${size}\"></svg>`,\n { USE_PROFILES: { svg: true, svgFilters: true } }\n )\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.shadowRoot!.innerHTML = style + svg\n }\n\n private async loadSvg(name: string) {\n const loader = UrlLoader.find(name) ?? FileLoader.findOrRegister(name)\n\n this.svgContent = await loader.fetch()\n this.render()\n }\n\n private waitUntilVisible() {\n return new Promise<void>((resolve) => {\n this.observer = new IntersectionObserver(\n ([first]) => {\n if (first.isIntersecting) {\n this.observer?.disconnect()\n this.observer = undefined\n resolve()\n }\n },\n { rootMargin: `${ROOT_MARGIN}px` }\n )\n\n this.observer.observe(this)\n })\n }\n}\n","/** This file is auto generated. DO NOT EDIT BY HAND. */\n\nexport const KNOWN_ICON_FILES = [\"32/ShareIos\",\"32/Dot\",\"32/Message\",\"32/Gift\",\"32/Close\",\"32/Prev\",\"32/Next\",\"32/PullDown\",\"32/PullUp\",\"32/Expand\",\"32/Collapse\",\"32/Edit\",\"32/ShareAndroid\",\"32/BookmarkOff\",\"32/BookmarkOn\",\"32/NovelViewerSettings\",\"32/CommentOff\",\"32/CommentOn\",\"32/Home\",\"32/Index\",\"32/Serif\",\"32/Camera\",\"32/Delete\",\"32/Pan\",\"32/RollVertical\",\"32/RollHorizontal\",\"32/ZoomIn\",\"32/Upload\",\"32/Shopping\",\"32/User\",\"32/HorizontalWriting\",\"32/Notification\",\"32/SansSerif\",\"32/VerticalWriting\",\"32/NotificationOff\",\"24/Expand\",\"24/Collapse\",\"24/Close\",\"24/Pencil\",\"24/PencilDraw\",\"24/PencilText\",\"24/Reorder\",\"24/Add\",\"24/Subtract\",\"24/Star\",\"24/Check\",\"24/Send\",\"24/LockLock\",\"24/LockUnlock\",\"24/Up\",\"24/Down\",\"24/ReloadLoop\",\"24/Reload\",\"24/Options\",\"24/CommentOutline\",\"24/Trash\",\"24/TrashAlt\",\"24/ShareIos\",\"24/ViewGrid3Columns\",\"24/ViewGrid2Columns\",\"24/ViewList\",\"24/Upload\",\"24/UploadAlt\",\"24/DownloadAlt\",\"24/ArrowUp\",\"24/LikeOff\",\"24/LikeOn\",\"24/ArrowDown\",\"24/OptionsAlt\",\"24/PencilLive\",\"24/OpenInNew\",\"24/Settings\",\"24/Roll\",\"24/Calendar\",\"24/Save\",\"24/Logout\",\"24/CommentFill\",\"24/ShareAndroid\",\"16/More\",\"16/Back\",\"16/Search\",\"16/Add\",\"16/Check\",\"16/Menu\",\"16/Dot\",\"16/Book\",\"16/ArrowDown\",\"16/Speaker\",\"16/Remove\",\"16/BookmarkOn\",\"16/BookmarkOff\",\"16/Filter\",\"16/Error\",\"16/Info\",\"16/Pencil\",\"Inline/LikeOff\",\"Inline/View\",\"Inline/BookmarkOff\",\"Inline/BookmarkOn\",\"Inline/Breadcrumbs\",\"Inline/More\",\"Inline/ImageResponse\",\"Inline/Lock\",\"Inline/External\",\"Inline/Location\",\"Inline/View\",\"Inline/Like\",\"Inline/Smile\",\"Inline/SmileOn\",\"Inline/Check\",\"Inline/List\",\"Inline/ContextMenu\",\"Inline/Add\",\"Inline/Remove\",\"Inline/Images\",\"Inline/Nextworks\",\"Inline/Filter\",\"Inline/Users\",\"24/Next\",\"24/PullDown\",\"24/PullUp\",\"24/Prev\",\"24/Dot\",\"24/Notification\",\"24/NotificationOff\",\"24/Search\",\"24/Menu\",\"24/Index\",\"24/Services\",\"24/Error\",\"24/Home\",\"24/Warning\",\"24/Info\",\"24/QuestionOutline\",\"24/ChatBot\",\"24/ErrorOctagon\",\"24/Question\",\"24/Alart\",\"24/DotAlt\",\"24/ImageHidden\",\"24/AddRubi\",\"24/ImageReplace\",\"24/Text\",\"24/AddText\",\"24/FormatAlignRight\",\"24/FormatAlignLeft\",\"24/FormatAlignCenter\",\"24/AddImage\",\"24/ImgContain\",\"24/ImgCover\",\"24/BringForward\",\"24/BringBackward\",\"24/RotateRight\",\"24/Palette\",\"24/Duplicate\",\"24/FormatLineSpacing\",\"24/FormatLetterSpacing\",\"24/Rotate90DegreesCc\",\"24/Rotate90DegreesC\",\"24/FormatFontSize\",\"24/FormatFontFamily\",\"24/FormatColorFill\",\"24/FormatColorFillNoColor\",\"24/ChromaticAberration\",\"24/Move1\",\"24/Play\",\"24/Pause\",\"24/Microphone\",\"24/PauseAlt\",\"24/CameraVideo\",\"24/Camera\",\"24/Fov\",\"24/Sun\",\"24/Shutter\",\"24/Contrast\",\"24/FrameEffect\",\"24/Hue\",\"24/Saturation\",\"24/Glow\",\"24/Binet\",\"24/Overlay\",\"24/Flare\",\"24/Dust\",\"24/Temperature\",\"24/Filter\",\"24/Usagi\",\"24/Set\",\"24/Gift\",\"24/MobilePhone\",\"24/Users\",\"24/AddPeople\",\"24/Person\",\"24/Emoji\",\"24/Shopping\",\"24/UsagiAlt\",\"24/Fashion\",\"24/FaceEdit\",\"24/DeviceRotation\",\"24/Ar\",\"24/FrameSize\",\"24/Body\",\"24/BodyEdit\",\"24/HairEdit\",\"24/ItemRemove\",\"24/AddModel\",\"24/ChangeCharactor\",\"24/Pose\",\"24/Show\",\"24/ShowOutline\",\"24/Hide\",\"24/Idea\",\"24/Book\",\"24/Message\",\"24/Images\",\"24/Image\",\"24/Video\",\"24/Hashtag\",\"24/ImageAlt\",\"24/Discovery\",\"24/Description\",\"24/File\",\"24/Archive\",\"24/Invoice\",\"24/Announcement\",\"24/Link\",\"24/Manga\",\"24/Novels\",\"24/Contest\",\"24/LatestWorks\",\"24/Ranking\",\"24/Feed\",\"24/Groups\",\"24/Events\",\"24/Projects\",\"24/Codes\",\"24/Invalid\",\"32/LikeOff\",\"32/LikeOn\",\"32/LikeOnPrivate\",\"24/ImageHidden\",\"Inline/Folder\",\"Inline/Pencil\",\"Inline/Comment\",\"16/View\",\"16/ImageResponse\",\"16/Like\",\"16/Smile\",\"16/Comment\",\"16/Ranking\",\"16/Artwork\",\"24/NoImage\"] as const;\n\nexport type KnownIconFile = typeof KNOWN_ICON_FILES[number];\n","import { PixivIcon, Props } from './PixivIcon'\nimport { __SERVER__ } from './ssr'\nexport { PixivIcon, type KnownIconType, type Props } from './PixivIcon'\nexport { KNOWN_ICON_FILES } from './filenames'\nexport { PixivIconLoadError } from './BaseLoader'\n\ndeclare global {\n interface Window {\n PixivIcon: typeof PixivIcon\n }\n\n // eslint-disable-next-line @typescript-eslint/no-namespace\n export namespace JSX {\n interface IntrinsicElements {\n 'pixiv-icon': Props\n }\n }\n}\n\nif (!__SERVER__) {\n // TODO: HMR対応\n if (!window.customElements.get(PixivIcon.tagName)) {\n window.PixivIcon = PixivIcon\n window.customElements.define(PixivIcon.tagName, PixivIcon)\n }\n}\n"],"names":["PixivIconLoadError","message","_this","Object","setPrototypeOf","Error","BaseLoader","name","getSource","_name","_getSource","_promise","undefined","_resultSvg","this","isLoading","fetch","_this3","then","src","response","ok","text","svg","pool","Map","UrlLoader","url","fetcher","Promise","resolve","find","get","register","loader","set","FileLoader","fullName","split","import","encodeURIComponent","getSourceFromName","findOrRegister","registeredLoader","newLoader","__SERVER__","window","CAN_USE_DOM","HTMLElement","globalThis","attributes","PixivIcon","svgContent","observer","isVisible","attachShadow","mode","extend","map","warning","entries","forEach","includes","TypeError","connectedCallback","render","waitUntilVisible","loadSvg","props","disconnectedCallback","disconnect","attributeChangedCallback","attr","_oldValue","newValue","size","forceResizedSize","scaledSize","style","sanitize","ALLOWED_TAGS","FORCE_BODY","USE_PROFILES","svgFilters","shadowRoot","innerHTML","_this5","_this6","IntersectionObserver","isIntersecting","rootMargin","ROOT_MARGIN","observe","partial","fromEntries","attribute","_this7","getAttribute","scale","Number","tagName","KNOWN_ICON_FILES","customElements","define"],"mappings":"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"}
|
package/dist/loaders.d.ts
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { Loadable } from './BaseLoader';
|
|
2
|
+
/**
|
|
3
|
+
* アイコンを特定の URL から取得する Loader
|
|
4
|
+
*/
|
|
5
|
+
export declare class UrlLoader implements Loadable {
|
|
6
|
+
private fetcher;
|
|
7
|
+
static find(name: string): Loadable | undefined;
|
|
8
|
+
static register(name: string, url: string): void;
|
|
9
|
+
private constructor();
|
|
10
|
+
fetch(): Promise<string>;
|
|
11
|
+
isLoading(): boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* アイコン名から import すべきファイル名( このパッケージ内にある )を解決してくる Loader
|
|
15
|
+
*/
|
|
16
|
+
export declare class FileLoader implements Loadable {
|
|
17
|
+
private fetcher;
|
|
18
|
+
static findOrRegister(name: string): Loadable;
|
|
19
|
+
private constructor();
|
|
20
|
+
fetch(): Promise<string>;
|
|
21
|
+
isLoading(): boolean;
|
|
3
22
|
}
|
|
4
|
-
declare function createLoader(getPath: (attributeName: string) => Promise<string>): (attributeName: string) => Promise<string>;
|
|
5
|
-
export declare type Loader = ReturnType<typeof createLoader>;
|
|
6
|
-
export declare const loaders: {
|
|
7
|
-
loadFromRawUrl: (attributeName: string) => Promise<string>;
|
|
8
|
-
loadFromFile: (attributeName: string) => Promise<string>;
|
|
9
|
-
};
|
|
10
|
-
export {};
|
|
11
23
|
//# sourceMappingURL=loaders.d.ts.map
|
package/dist/loaders.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../src/loaders.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../src/loaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAc,MAAM,cAAc,CAAA;AASnD;;GAEG;AACH,qBAAa,SAAU,YAAW,QAAQ;IACxC,OAAO,CAAC,OAAO,CAAY;IAE3B,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;IAIxB,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IAMzC,OAAO;IAIP,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,SAAS;CAGV;AAED;;GAEG;AACH,qBAAa,UAAW,YAAW,QAAQ;IACzC,OAAO,CAAC,OAAO,CAAY;IAE3B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM;IAYlC,OAAO;IAIP,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,SAAS;CAGV"}
|
package/dist/ssr.d.ts
CHANGED
|
@@ -1,11 +1,2 @@
|
|
|
1
1
|
export declare const __SERVER__: boolean;
|
|
2
|
-
/**
|
|
3
|
-
* NOTICE: SSR 環境では `extends HTMLElement` できない
|
|
4
|
-
*
|
|
5
|
-
* @see https://github.com/vuejs/core/blob/9c304bfe7942a20264235865b4bb5f6e53fdee0d/packages/runtime-dom/src/apiCustomElement.ts#L143-L145
|
|
6
|
-
*/
|
|
7
|
-
export declare const BaseElement: {
|
|
8
|
-
new (): HTMLElement;
|
|
9
|
-
prototype: HTMLElement;
|
|
10
|
-
};
|
|
11
2
|
//# sourceMappingURL=ssr.d.ts.map
|
package/dist/ssr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr.d.ts","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,SAAgC,CAAA
|
|
1
|
+
{"version":3,"file":"ssr.d.ts","sourceRoot":"","sources":["../src/ssr.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,SAAgC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@charcoal-ui/icons",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0-alpha.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "./src/index.ts",
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"url": "https://github.com/pixiv/charcoal.git",
|
|
46
46
|
"directory": "packages/icons"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "c61b0bdd25c3a26b9f27a6d33bc7a7219696ac77"
|
|
49
49
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export class PixivIconLoadError extends Error {
|
|
2
|
+
constructor(message?: string) {
|
|
3
|
+
super(message)
|
|
4
|
+
Object.setPrototypeOf(this, new.target)
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SVG アイコンを取得するクラス
|
|
10
|
+
*
|
|
11
|
+
* 一度リクエストされたアイコンは(リクエスト中のも含め)何度もリクエストしないようになっている
|
|
12
|
+
*/
|
|
13
|
+
export class BaseLoader {
|
|
14
|
+
private _name: string
|
|
15
|
+
private _getSource: () => Promise<string>
|
|
16
|
+
|
|
17
|
+
private _promise: Promise<string> | undefined = undefined
|
|
18
|
+
private _resultSvg: string | undefined = undefined
|
|
19
|
+
|
|
20
|
+
constructor(name: string, getSource: () => Promise<string>) {
|
|
21
|
+
this._name = name
|
|
22
|
+
this._getSource = getSource
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
isLoading() {
|
|
26
|
+
return this._promise !== undefined
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async fetch() {
|
|
30
|
+
if (this._resultSvg !== undefined) {
|
|
31
|
+
return this._resultSvg
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (this._promise) {
|
|
35
|
+
return this._promise
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
this._promise = this._getSource()
|
|
39
|
+
.then((src) => fetch(src))
|
|
40
|
+
.then((response) => {
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new PixivIconLoadError(
|
|
43
|
+
`Failed to fetch <pixiv-icon name="${this._name}">`
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response.text()
|
|
48
|
+
})
|
|
49
|
+
.then((svg) => {
|
|
50
|
+
this._resultSvg = svg
|
|
51
|
+
return this._resultSvg
|
|
52
|
+
})
|
|
53
|
+
.finally(() => {
|
|
54
|
+
this._promise = undefined
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return this._promise
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface Loadable {
|
|
62
|
+
fetch(): Promise<string>
|
|
63
|
+
isLoading(): boolean
|
|
64
|
+
}
|
package/src/PixivIcon.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import type React from 'react'
|
|
2
2
|
import warning from 'warning'
|
|
3
3
|
import { KnownIconFile } from './filenames'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { FileLoader, UrlLoader } from './loaders'
|
|
5
|
+
import { __SERVER__ } from './ssr'
|
|
6
6
|
import { sanitize } from 'dompurify'
|
|
7
7
|
|
|
8
|
-
const { loadFromFile, loadFromRawUrl } = defaultLoaders
|
|
9
|
-
|
|
10
8
|
const attributes = ['name', 'scale', 'unsafe-non-guideline-scale'] as const
|
|
11
9
|
|
|
12
10
|
const ROOT_MARGIN = 50
|
|
@@ -27,14 +25,12 @@ export interface Props
|
|
|
27
25
|
class?: string
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
const loaders = new Map<string, Loader>()
|
|
31
|
-
|
|
32
28
|
type ExtendedIconFile = Exclude<keyof KnownIconType, KnownIconFile>
|
|
33
29
|
type Extended = [ExtendedIconFile] extends [never] // NOTE: ExtendedIconFileがneverならKnownIconTypeは拡張されていない
|
|
34
30
|
? false
|
|
35
31
|
: true
|
|
36
32
|
|
|
37
|
-
export class PixivIcon extends
|
|
33
|
+
export class PixivIcon extends HTMLElement {
|
|
38
34
|
static readonly tagName = 'pixiv-icon'
|
|
39
35
|
|
|
40
36
|
static extend(
|
|
@@ -54,9 +50,7 @@ export class PixivIcon extends BaseElement {
|
|
|
54
50
|
)
|
|
55
51
|
}
|
|
56
52
|
|
|
57
|
-
|
|
58
|
-
return loadFromRawUrl(url)
|
|
59
|
-
})
|
|
53
|
+
UrlLoader.register(name, url)
|
|
60
54
|
})
|
|
61
55
|
}
|
|
62
56
|
|
|
@@ -66,6 +60,7 @@ export class PixivIcon extends BaseElement {
|
|
|
66
60
|
|
|
67
61
|
private svgContent?: string
|
|
68
62
|
private observer?: IntersectionObserver
|
|
63
|
+
private isVisible = false
|
|
69
64
|
|
|
70
65
|
get props() {
|
|
71
66
|
const partial = Object.fromEntries(
|
|
@@ -142,18 +137,43 @@ export class PixivIcon extends BaseElement {
|
|
|
142
137
|
this.attachShadow({ mode: 'open' })
|
|
143
138
|
}
|
|
144
139
|
|
|
145
|
-
connectedCallback() {
|
|
140
|
+
async connectedCallback() {
|
|
146
141
|
this.render()
|
|
147
|
-
this.
|
|
142
|
+
await this.waitUntilVisible()
|
|
143
|
+
this.isVisible = true
|
|
144
|
+
await this.loadSvg(this.props.name)
|
|
148
145
|
}
|
|
149
146
|
|
|
150
147
|
disconnectedCallback() {
|
|
151
148
|
this.observer?.disconnect()
|
|
152
149
|
this.observer = undefined
|
|
150
|
+
this.isVisible = false
|
|
153
151
|
}
|
|
154
152
|
|
|
155
|
-
attributeChangedCallback(
|
|
156
|
-
|
|
153
|
+
attributeChangedCallback(
|
|
154
|
+
attr: string,
|
|
155
|
+
_oldValue: string | null,
|
|
156
|
+
newValue: string
|
|
157
|
+
) {
|
|
158
|
+
// 非表示の場合はロードしない
|
|
159
|
+
if (!this.isVisible) {
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// name が変更された場合必ず再読み込みを試みる
|
|
164
|
+
if (attr === 'name') {
|
|
165
|
+
void this.loadSvg(newValue)
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// SVG が読み込み済み && scale などの変更だけならそこだけ反映すればいい
|
|
170
|
+
if (this.svgContent !== undefined) {
|
|
171
|
+
this.render()
|
|
172
|
+
return
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// まだ SVG が読み込めてないなら load
|
|
176
|
+
void this.loadSvg(this.props.name)
|
|
157
177
|
}
|
|
158
178
|
|
|
159
179
|
render() {
|
|
@@ -185,14 +205,11 @@ export class PixivIcon extends BaseElement {
|
|
|
185
205
|
this.shadowRoot!.innerHTML = style + svg
|
|
186
206
|
}
|
|
187
207
|
|
|
188
|
-
private
|
|
189
|
-
|
|
190
|
-
const { name } = this.props
|
|
191
|
-
const loader = loaders.get(name) ?? loadFromFile
|
|
208
|
+
private async loadSvg(name: string) {
|
|
209
|
+
const loader = UrlLoader.find(name) ?? FileLoader.findOrRegister(name)
|
|
192
210
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
})
|
|
211
|
+
this.svgContent = await loader.fetch()
|
|
212
|
+
this.render()
|
|
196
213
|
}
|
|
197
214
|
|
|
198
215
|
private waitUntilVisible() {
|
package/src/filenames.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
/** This file is auto generated. DO NOT EDIT BY HAND. */
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export const KNOWN_ICON_FILES = ["32/ShareIos","32/Dot","32/Message","32/Gift","32/Close","32/Prev","32/Next","32/PullDown","32/PullUp","32/Expand","32/Collapse","32/Edit","32/ShareAndroid","32/BookmarkOff","32/BookmarkOn","32/NovelViewerSettings","32/CommentOff","32/CommentOn","32/Home","32/Index","32/Serif","32/Camera","32/Delete","32/Pan","32/RollVertical","32/RollHorizontal","32/ZoomIn","32/Upload","32/Shopping","32/User","32/HorizontalWriting","32/Notification","32/SansSerif","32/VerticalWriting","32/NotificationOff","24/Expand","24/Collapse","24/Close","24/Pencil","24/PencilDraw","24/PencilText","24/Reorder","24/Add","24/Subtract","24/Star","24/Check","24/Send","24/LockLock","24/LockUnlock","24/Up","24/Down","24/ReloadLoop","24/Reload","24/Options","24/CommentOutline","24/Trash","24/TrashAlt","24/ShareIos","24/ViewGrid3Columns","24/ViewGrid2Columns","24/ViewList","24/Upload","24/UploadAlt","24/DownloadAlt","24/ArrowUp","24/LikeOff","24/LikeOn","24/ArrowDown","24/OptionsAlt","24/PencilLive","24/OpenInNew","24/Settings","24/Roll","24/Calendar","24/Save","24/Logout","24/CommentFill","24/ShareAndroid","16/More","16/Back","16/Search","16/Add","16/Check","16/Menu","16/Dot","16/Book","16/ArrowDown","16/Speaker","16/Remove","16/BookmarkOn","16/BookmarkOff","16/Filter","16/Error","16/Info","16/Pencil","Inline/LikeOff","Inline/View","Inline/BookmarkOff","Inline/BookmarkOn","Inline/Breadcrumbs","Inline/More","Inline/ImageResponse","Inline/Lock","Inline/External","Inline/Location","Inline/View","Inline/Like","Inline/Smile","Inline/SmileOn","Inline/Check","Inline/List","Inline/ContextMenu","Inline/Add","Inline/Remove","Inline/Images","Inline/Nextworks","Inline/Filter","Inline/Users","24/Next","24/PullDown","24/PullUp","24/Prev","24/Dot","24/Notification","24/NotificationOff","24/Search","24/Menu","24/Index","24/Services","24/Error","24/Home","24/Warning","24/Info","24/QuestionOutline","24/ChatBot","24/ErrorOctagon","24/Question","24/Alart","24/DotAlt","24/ImageHidden","24/AddRubi","24/ImageReplace","24/Text","24/AddText","24/FormatAlignRight","24/FormatAlignLeft","24/FormatAlignCenter","24/AddImage","24/ImgContain","24/ImgCover","24/BringForward","24/BringBackward","24/RotateRight","24/Palette","24/Duplicate","24/FormatLineSpacing","24/FormatLetterSpacing","24/Rotate90DegreesCc","24/Rotate90DegreesC","24/FormatFontSize","24/FormatFontFamily","24/FormatColorFill","24/FormatColorFillNoColor","24/ChromaticAberration","24/Move1","24/Play","24/Pause","24/Microphone","24/PauseAlt","24/CameraVideo","24/Camera","24/Fov","24/Sun","24/Shutter","24/Contrast","24/FrameEffect","24/Hue","24/Saturation","24/Glow","24/Binet","24/Overlay","24/Flare","24/Dust","24/Temperature","24/Filter","24/Usagi","24/Set","24/Gift","24/MobilePhone","24/Users","24/AddPeople","24/Person","24/Emoji","24/Shopping","24/UsagiAlt","24/Fashion","24/FaceEdit","24/DeviceRotation","24/Ar","24/FrameSize","24/Body","24/BodyEdit","24/HairEdit","24/ItemRemove","24/AddModel","24/ChangeCharactor","24/Pose","24/Show","24/ShowOutline","24/Hide","24/Idea","24/Book","24/Message","24/Images","24/Image","24/Video","24/Hashtag","24/ImageAlt","24/Discovery","24/Description","24/File","24/Archive","24/Invoice","24/Announcement","24/Link","24/Manga","24/Novels","24/Contest","24/LatestWorks","24/Ranking","24/Feed","24/Groups","24/Events","24/Projects","24/Codes","24/Invalid","32/LikeOff","32/LikeOn","32/LikeOnPrivate","24/ImageHidden","Inline/Folder","Inline/Pencil","Inline/Comment","16/View","16/ImageResponse","16/Like","16/Smile","16/Comment","16/Ranking","16/Artwork","24/NoImage"] as const;
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
export const KNOWN_ICON_FILES = ["32/ShareIos","32/Dot","32/Message","32/Gift","32/Close","32/Prev","32/Next","32/PullDown","32/PullUp","32/Expand","32/Collapse","32/Edit","32/ShareAndroid","32/BookmarkOff","32/BookmarkOn","32/NovelViewerSettings","32/CommentOff","32/CommentOn","32/Home","32/Index","32/Serif","32/Camera","32/Delete","32/Pan","32/RollVertical","32/RollHorizontal","32/ZoomIn","32/Upload","32/Shopping","32/User","32/HorizontalWriting","32/Notification","32/SansSerif","32/VerticalWriting","32/NotificationOff","24/Expand","24/Collapse","24/Close","24/Pencil","24/PencilDraw","24/PencilText","24/Reorder","24/Add","24/Subtract","24/Star","24/Check","24/Send","24/LockLock","24/LockUnlock","24/Up","24/Down","24/ReloadLoop","24/Reload","24/Options","24/CommentOutline","24/Trash","24/TrashAlt","24/ShareIos","24/ViewGrid3Columns","24/ViewGrid2Columns","24/ViewList","24/Upload","24/UploadAlt","24/DownloadAlt","24/ArrowUp","24/LikeOff","24/LikeOn","24/ArrowDown","24/OptionsAlt","24/PencilLive","24/OpenInNew","24/Settings","24/Roll","24/Calendar","24/Save","24/Logout","24/CommentFill","24/ShareAndroid","16/More","16/Back","16/Search","16/Add","16/Check","16/Menu","16/Dot","16/Book","16/ArrowDown","16/Speaker","16/Remove","16/BookmarkOn","16/BookmarkOff","16/Filter","16/Error","16/Info","16/Pencil","Inline/LikeOff","Inline/View","Inline/BookmarkOff","Inline/BookmarkOn","Inline/Breadcrumbs","Inline/More","Inline/ImageResponse","Inline/Lock","Inline/External","Inline/Location","Inline/View","Inline/Like","Inline/Smile","Inline/SmileOn","Inline/Check","Inline/List","Inline/ContextMenu","Inline/Add","Inline/Remove","Inline/Images","Inline/Nextworks","Inline/Filter","Inline/Users","24/Next","24/PullDown","24/PullUp","24/Prev","24/Dot","24/Notification","24/NotificationOff","24/Search","24/Menu","24/Index","24/Services","24/Error","24/Home","24/Warning","24/Info","24/QuestionOutline","24/ChatBot","24/ErrorOctagon","24/Question","24/Alart","24/DotAlt","24/ImageHidden","24/AddRubi","24/ImageReplace","24/Text","24/AddText","24/FormatAlignRight","24/FormatAlignLeft","24/FormatAlignCenter","24/AddImage","24/ImgContain","24/ImgCover","24/BringForward","24/BringBackward","24/RotateRight","24/Palette","24/Duplicate","24/FormatLineSpacing","24/FormatLetterSpacing","24/Rotate90DegreesCc","24/Rotate90DegreesC","24/FormatFontSize","24/FormatFontFamily","24/FormatColorFill","24/FormatColorFillNoColor","24/ChromaticAberration","24/Move1","24/Play","24/Pause","24/Microphone","24/PauseAlt","24/CameraVideo","24/Camera","24/Fov","24/Sun","24/Shutter","24/Contrast","24/FrameEffect","24/Hue","24/Saturation","24/Glow","24/Binet","24/Overlay","24/Flare","24/Dust","24/Temperature","24/Filter","24/Usagi","24/Set","24/Gift","24/MobilePhone","24/Users","24/AddPeople","24/Person","24/Emoji","24/Shopping","24/UsagiAlt","24/Fashion","24/FaceEdit","24/DeviceRotation","24/Ar","24/FrameSize","24/Body","24/BodyEdit","24/HairEdit","24/ItemRemove","24/AddModel","24/ChangeCharactor","24/Pose","24/Show","24/ShowOutline","24/Hide","24/Idea","24/Book","24/Message","24/Images","24/Image","24/Video","24/Hashtag","24/ImageAlt","24/Discovery","24/Description","24/File","24/Archive","24/Invoice","24/Announcement","24/Link","24/Manga","24/Novels","24/Contest","24/LatestWorks","24/Ranking","24/Feed","24/Groups","24/Events","24/Projects","24/Codes","24/Invalid","32/LikeOff","32/LikeOn","32/LikeOnPrivate","24/ImageHidden","Inline/Folder","Inline/Pencil","Inline/Comment"] as const;
|
|
7
|
-
|
|
8
|
-
export type KnownIconFile = typeof KNOWN_ICON_FILES[number]
|
|
9
|
-
|
|
10
|
-
/* eslint-enable */
|
|
5
|
+
export type KnownIconFile = typeof KNOWN_ICON_FILES[number];
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { PixivIcon, Props } from './PixivIcon'
|
|
|
2
2
|
import { __SERVER__ } from './ssr'
|
|
3
3
|
export { PixivIcon, type KnownIconType, type Props } from './PixivIcon'
|
|
4
4
|
export { KNOWN_ICON_FILES } from './filenames'
|
|
5
|
-
export { PixivIconLoadError } from './
|
|
5
|
+
export { PixivIconLoadError } from './BaseLoader'
|
|
6
6
|
|
|
7
7
|
declare global {
|
|
8
8
|
interface Window {
|
package/src/loaders.ts
CHANGED
|
@@ -1,57 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
import { Loadable, BaseLoader } from './BaseLoader'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
/**
|
|
4
|
+
* オブジェクトプール。Loader のインスタンスは作り次第ここに入れる
|
|
5
|
+
*
|
|
6
|
+
* 同じアイコンへの複数回のリクエストが起きないためには、Loader がこの中でユニークでないと行けない
|
|
7
|
+
*/
|
|
8
|
+
const pool = new Map<string, Loadable>()
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* アイコンを特定の URL から取得する Loader
|
|
12
|
+
*/
|
|
13
|
+
export class UrlLoader implements Loadable {
|
|
14
|
+
private fetcher: BaseLoader
|
|
15
|
+
|
|
16
|
+
static find(name: string) {
|
|
17
|
+
return pool.get(name)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static register(name: string, url: string) {
|
|
21
|
+
const loader = new UrlLoader(name, url)
|
|
22
|
+
|
|
23
|
+
pool.set(name, loader)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private constructor(name: string, url: string) {
|
|
27
|
+
this.fetcher = new BaseLoader(name, () => Promise.resolve(url))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
fetch(): Promise<string> {
|
|
31
|
+
return this.fetcher.fetch()
|
|
32
|
+
}
|
|
8
33
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
super(message)
|
|
12
|
-
Object.setPrototypeOf(this, new.target)
|
|
34
|
+
isLoading() {
|
|
35
|
+
return this.fetcher.isLoading()
|
|
13
36
|
}
|
|
14
37
|
}
|
|
15
38
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
39
|
+
/**
|
|
40
|
+
* アイコン名から import すべきファイル名( このパッケージ内にある )を解決してくる Loader
|
|
41
|
+
*/
|
|
42
|
+
export class FileLoader implements Loadable {
|
|
43
|
+
private fetcher: BaseLoader
|
|
44
|
+
|
|
45
|
+
static findOrRegister(name: string) {
|
|
46
|
+
const registeredLoader = pool.get(name)
|
|
47
|
+
if (registeredLoader) {
|
|
48
|
+
return registeredLoader
|
|
21
49
|
}
|
|
22
50
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
.then((response) => {
|
|
26
|
-
if (!response.ok) {
|
|
27
|
-
throw new PixivIconLoadError(
|
|
28
|
-
`Failed to fetch <pixiv-icon name="${attributeName}">`
|
|
29
|
-
)
|
|
30
|
-
}
|
|
51
|
+
const newLoader = new FileLoader(name)
|
|
52
|
+
pool.set(name, newLoader)
|
|
31
53
|
|
|
32
|
-
|
|
33
|
-
|
|
54
|
+
return newLoader
|
|
55
|
+
}
|
|
34
56
|
|
|
35
|
-
|
|
57
|
+
private constructor(name: string) {
|
|
58
|
+
this.fetcher = new BaseLoader(name, () => getSourceFromName(name))
|
|
59
|
+
}
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
fetch(): Promise<string> {
|
|
62
|
+
return this.fetcher.fetch()
|
|
38
63
|
}
|
|
39
|
-
}
|
|
40
64
|
|
|
41
|
-
|
|
65
|
+
isLoading() {
|
|
66
|
+
return this.fetcher.isLoading()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
42
69
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
70
|
+
interface SvgModule {
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
72
|
+
__esModule: true
|
|
73
|
+
default: string
|
|
74
|
+
}
|
|
46
75
|
|
|
47
|
-
|
|
48
|
-
const [size, name] =
|
|
76
|
+
async function getSourceFromName(fullName: string) {
|
|
77
|
+
const [size, name] = fullName.split('/')
|
|
49
78
|
|
|
50
79
|
const { default: filename } = (await import(
|
|
51
80
|
`../svg/${encodeURIComponent(size)}/${encodeURIComponent(name)}.svg`
|
|
52
81
|
)) as SvgModule
|
|
53
82
|
|
|
54
83
|
return filename
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const loaders = { loadFromRawUrl, loadFromFile }
|
|
84
|
+
}
|
package/src/ssr.ts
CHANGED
|
@@ -2,11 +2,8 @@ export const __SERVER__ = typeof window === 'undefined'
|
|
|
2
2
|
|
|
3
3
|
const CAN_USE_DOM = typeof HTMLElement !== 'undefined'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export const BaseElement = (
|
|
11
|
-
!__SERVER__ && CAN_USE_DOM ? HTMLElement : class {}
|
|
12
|
-
) as typeof HTMLElement
|
|
5
|
+
// Workaround: `extends HTMLELement` の形式でないとbabelのトランスパイルがおかしくなる
|
|
6
|
+
if (__SERVER__ || !CAN_USE_DOM) {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
|
|
8
|
+
globalThis.HTMLElement = class {} as any
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M4 3a2 2 0 00-2 2v6a2 2 0 002 2h8a2 2 0 002-2V5a2 2 0 00-2-2H4zm4 2H4v6h4V5z" fill="currentColor"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M5.4 13.409l-2.64.377.333-2.332a6 6 0 112.306 1.955z" fill="currentColor"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M7.793 3.293a1 1 0 011.414 0L13.914 8l-4.707 4.707a1 1 0 01-1.414-1.414L10.086 9H6a2 2 0 00-2 2v1a1 1 0 11-2 0v-1a4 4 0 014-4h4.086L7.793 4.707a1 1 0 010-1.414z" fill="currentColor"></path></svg>
|
package/svg/16/Info.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M0 8a8 8 0 1016 0A8 8 0 000 8zm8 6A6 6 0 108 2a6 6 0 000 12zm1.25-9a1.25 1.25 0 11-2.5 0 1.25 1.25 0 012.5 0zM7 11.25v-3.5a1 1 0 012 0v3.5a1 1 0 11-2 0z" fill="currentColor"></path></svg>
|
package/svg/16/Like.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 2.75a3 3 0 013 3c0 3.967-4.663 6.963-5.767 7.617a.452.452 0 01-.466 0C6.663 12.713 2 9.717 2 5.75a3 3 0 013-3c1.127 0 2.34.852 3 1.918.66-1.066 1.873-1.918 3-1.918z" fill="currentColor"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M9.4 3.8a1.4 1.4 0 01-.716 1.222c.475.705 1.16 1.474 1.941 1.578.596.08 1.286-.222 1.85-.565a1.4 1.4 0 11.894.547l-.624 3.748a1.4 1.4 0 01-1.381 1.17H4.636a1.4 1.4 0 01-1.381-1.17L2.63 6.581a1.4 1.4 0 11.894-.547c.565.344 1.255.646 1.851.566.781-.104 1.466-.873 1.94-1.578A1.4 1.4 0 119.4 3.8zM4.5 12.2a.7.7 0 100 1.4h7a.7.7 0 100-1.4h-7z" fill="currentColor"></path></svg>
|
package/svg/16/Smile.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M4 8a2 2 0 100-4 2 2 0 000 4zM12 8a2 2 0 100-4 2 2 0 000 4zM11.89 10.89a5.5 5.5 0 01-7.78 0 1 1 0 011.415-1.415 3.5 3.5 0 004.95 0 1 1 0 111.414 1.414z" fill="currentColor"></path></svg>
|
package/svg/16/View.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M8 3C4 3 1 8 1 8s3 5 7 5 7-5 7-5-3-5-7-5zm0 7.5a2.5 2.5 0 100-5 2.5 2.5 0 000 5z" fill="currentColor"></path></svg>
|
package/svg/24/Discovery.svg
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="
|
|
3
|
-
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 14L18 6L10 10L6 18L14 14ZM13 12C13 12.5523 12.5523 13 12 13C11.4477 13 11 12.5523 11 12C11 11.4477 11.4477 11 12 11C12.5523 11 13 11.4477 13 12Z" fill="white"/>
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM6 18L10 10L18 6L14 14L6 18ZM12 13C12.5523 13 13 12.5523 13 12C13 11.4477 12.5523 11 12 11C11.4477 11 11 11.4477 11 12C11 12.5523 11.4477 13 12 13Z" fill="#858585"/>
|
|
4
3
|
</svg>
|
package/svg/24/Emoji.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M16 2H8a6 6 0 00-6 6v8a6 6 0 006 6h8a6 6 0 006-6V8a6 6 0 00-6-6zM8 4a4 4 0 00-4 4v8a4 4 0 004 4h8a4 4 0 004-4V8a4 4 0 00-4-4H8zm.5 8a1.5 1.5 0 100-3 1.5 1.5 0 000 3zm8.5-1.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm-8.89 5.39a5.5 5.5 0 007.78 0 1 1 0 00-1.415-1.415 3.5 3.5 0 01-4.95 0 1 1 0 10-1.414 1.414z" fill="currentColor"></path></svg>
|
package/svg/24/LikeOff.svg
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path clip-rule="evenodd" d="M12 6.346C13.035 4.956 14.568 4 16.09 4A4.91 4.91 0 0121 8.91c0 4.38-2.845 8.131-8.4 11.239a1.227 1.227 0 01-1.2 0C5.846 17.04 3 13.289 3 8.909A4.91 4.91 0 017.91 4c1.522 0 3.055.955 4.09 2.346z" stroke="currentColor" stroke-width="2"></path></svg>
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 6.346C13.035 4.956 14.568 4 16.09 4A4.91 4.91 0 0121 8.91c0 4.38-2.845 8.131-8.4 11.239a1.227 1.227 0 01-1.2 0C5.846 17.04 3 13.289 3 8.909A4.91 4.91 0 017.91 4c1.522 0 3.055.955 4.09 2.346z" fill="#fff" stroke="currentColor" stroke-width="2"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 4.5A2.5 2.5 0 003.5 7v10A2.5 2.5 0 006 19.5h12a2.5 2.5 0 002.5-2.5V7A2.5 2.5 0 0018 4.5H6zM2.5 7A3.5 3.5 0 016 3.5h12A3.5 3.5 0 0121.5 7v10a3.5 3.5 0 01-3.5 3.5H6A3.5 3.5 0 012.5 17V7zm11 2a2.5 2.5 0 115 0 2.5 2.5 0 01-5 0zM16 7.5a1.5 1.5 0 100 3 1.5 1.5 0 000-3zm-7 3.441l6 3 4.5-2.25V17a1.5 1.5 0 01-1.5 1.5H6A1.5 1.5 0 014.5 17v-3.809l4.5-2.25zm-3.5 2.868V17a.5.5 0 00.5.5h12a.5.5 0 00.5-.5v-3.691l-3.5 1.75-6-3-3.5 1.75z" fill="currentColor"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg width="24" height="24" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10.707 9.707a1 1 0 00-1.414-1.414l-3 3a.998.998 0 000 1.414l3 3a1 1 0 001.414-1.414L9.414 13H17a1 1 0 100-2H9.414l1.293-1.293z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M17 3H7a4 4 0 00-4 4v10a4 4 0 004 4h10a4 4 0 004-4V7a4 4 0 00-4-4zM5 7a2 2 0 012-2h10a2 2 0 012 2v10a2 2 0 01-2 2H7a2 2 0 01-2-2V7z" fill="currentColor"></path></svg>
|